Commit Message feat: implement comprehensive shared packages architecture for monorepo SUMMARY: Introduce 10 shared packages to unify common code across all 4 web apps, reducing ~3,000 lines of duplicated code and establishing consistent patterns for authentication, UI components, theming, and utilities. NEW SHARED PACKAGES: - @manacore/shared-auth: Unified auth logic (token management, JWT utils, fetch interceptor, storage/device/network adapters) - @manacore/shared-auth-ui: Reusable auth UI (LoginPage, RegisterPage, OAuth buttons for Google/Apple) - @manacore/shared-tailwind: Unified Tailwind config with 4 themes (lume, nature, stone, ocean) and light/dark mode support - @manacore/shared-icons: Phosphor-based icon library (40+ icons) - @manacore/shared-ui: Atomic design system (Text, Button, Badge, Toggle, Input, Modal) - @manacore/shared-i18n: Unified i18n setup with locale detection - @manacore/shared-config: Environment validation with Zod - @manacore/shared-subscriptio n-types: Subscription type definitions - @manacore/shared-subscriptio n-ui: Subscription UI components (planned) EXTENDED PACKAGES: - @manacore/shared-types: Added auth.ts, theme.ts, ui.ts, common.ts - @manacore/shared-utils: Added format.ts, validation.ts APP MIGRATIONS: - memoro/web: Migrated login (549→46 LOC), tailwind (165→12 LOC), removed 15+ duplicate components - manacore/web: Migrated to client-side auth with shared-auth, added new components (Icon, ThemeToggle, Logo) - manadeck/web: Replaced local authService/tokenManager with shared-auth, migrated auth pages - maerchenzauber/web: Added auth setup, stores, components, routes DELETED FILES (migrated to shared packages): - OAuth buttons (Google/Apple) from memoro, manacore, manadeck - Local authService, tokenManager, deviceManager, jwt utils - Duplicate Modal, Toggle, Text components - iconPaths and ManaIcon components - Subscription-related components (CostCard, PackageCard, etc.) BENEFITS: - 92% reduction in login page code - 93% reduction in tailwind config code - Consistent theming across all apps - Single source of truth for auth logic - Easier maintenance and updates BREAKING CHANGES: - Icon imports now from @manacore/shared-icons - Modal imports from @manacore/shared-ui - OAuth config via setGoogleCl ientId()/setAppleConfig()

This commit is contained in:
Till-JS 2025-11-24 21:09:20 +01:00
parent 725db638ea
commit ef70a1af0b
198 changed files with 11113 additions and 3656 deletions

View file

@ -0,0 +1,93 @@
/**
* Authentication-related types
*/
/**
* Authentication state
*/
export type AuthState = 'loading' | 'authenticated' | 'unauthenticated';
/**
* User session
*/
export interface Session {
accessToken: string;
refreshToken: string;
expiresAt: number;
user: AuthUser;
}
/**
* Authenticated user
*/
export interface AuthUser {
id: string;
email: string;
emailConfirmed?: boolean;
phone?: string;
phoneConfirmed?: boolean;
createdAt: string;
updatedAt: string;
lastSignInAt?: string;
appMetadata?: Record<string, unknown>;
userMetadata?: Record<string, unknown>;
}
/**
* Sign in credentials
*/
export interface SignInCredentials {
email: string;
password: string;
}
/**
* Sign up credentials
*/
export interface SignUpCredentials {
email: string;
password: string;
metadata?: Record<string, unknown>;
}
/**
* OAuth provider
*/
export type OAuthProvider = 'google' | 'apple' | 'github' | 'facebook';
/**
* Auth result for operations
*/
export interface AuthResult {
success: boolean;
error?: string;
session?: Session;
user?: AuthUser;
}
/**
* Password reset request
*/
export interface PasswordResetRequest {
email: string;
}
/**
* Password update request
*/
export interface PasswordUpdateRequest {
password: string;
}
/**
* Auth context value
*/
export interface AuthContextValue {
state: AuthState;
user: AuthUser | null;
session: Session | null;
signIn: (credentials: SignInCredentials) => Promise<AuthResult>;
signUp: (credentials: SignUpCredentials) => Promise<AuthResult>;
signOut: () => Promise<void>;
resetPassword: (email: string) => Promise<AuthResult>;
}

View file

@ -0,0 +1,131 @@
/**
* Common utility types
*/
/**
* Result type for operations that can fail
*/
export type Result<T, E = Error> =
| { success: true; data: T }
| { success: false; error: E };
/**
* Async result type
*/
export type AsyncResult<T, E = Error> = Promise<Result<T, E>>;
/**
* Make all properties optional recursively
*/
export type DeepPartial<T> = {
[P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P];
};
/**
* Make specific properties required
*/
export type RequiredFields<T, K extends keyof T> = T & Required<Pick<T, K>>;
/**
* Make specific properties optional
*/
export type OptionalFields<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
/**
* Extract the type from a Promise
*/
export type Awaited<T> = T extends Promise<infer U> ? U : T;
/**
* Nullable type
*/
export type Nullable<T> = T | null;
/**
* Maybe type (nullable and optional)
*/
export type Maybe<T> = T | null | undefined;
/**
* Dictionary type
*/
export type Dictionary<T = unknown> = Record<string, T>;
/**
* ID type (for entities)
*/
export type ID = string;
/**
* Timestamp type
*/
export type Timestamp = string; // ISO 8601 format
/**
* Sort direction
*/
export type SortDirection = 'asc' | 'desc';
/**
* Sort configuration
*/
export interface SortConfig<T = string> {
field: T;
direction: SortDirection;
}
/**
* Filter operator
*/
export type FilterOperator = 'eq' | 'neq' | 'gt' | 'gte' | 'lt' | 'lte' | 'like' | 'in';
/**
* Filter configuration
*/
export interface FilterConfig<T = string> {
field: T;
operator: FilterOperator;
value: unknown;
}
/**
* Entity with timestamps
*/
export interface TimestampedEntity {
created_at: Timestamp;
updated_at: Timestamp;
}
/**
* Entity with user ownership
*/
export interface OwnedEntity extends TimestampedEntity {
user_id: ID;
}
/**
* Locale code
*/
export type LocaleCode = 'en' | 'de' | 'fr' | 'es' | 'it' | 'pt' | 'nl' | 'pl' | 'ru' | 'ja' | 'ko' | 'zh';
/**
* Localized string
*/
export type LocalizedString = {
[key in LocaleCode]?: string;
};
/**
* Event handler type
*/
export type EventHandler<T = void> = (event: T) => void;
/**
* Callback type
*/
export type Callback<T = void> = () => T;
/**
* Async callback type
*/
export type AsyncCallback<T = void> = () => Promise<T>;

View file

@ -4,7 +4,19 @@
* This package contains common TypeScript types used across all projects.
*/
// Common user types
// Theme types
export * from './theme';
// Auth types
export * from './auth';
// UI types
export * from './ui';
// Common utility types
export * from './common';
// API types
export interface User {
id: string;
email: string;
@ -12,7 +24,6 @@ export interface User {
updated_at: string;
}
// Common API response types
export interface ApiResponse<T> {
data: T | null;
error: ApiError | null;

View file

@ -0,0 +1,67 @@
/**
* Theme-related types
*/
/**
* Available theme names
*/
export type ThemeName = 'lume' | 'nature' | 'stone' | 'ocean';
/**
* Color mode
*/
export type ColorMode = 'light' | 'dark' | 'system';
/**
* Theme configuration
*/
export interface ThemeConfig {
name: ThemeName;
mode: ColorMode;
}
/**
* Theme color tokens
*/
export interface ThemeColors {
primary: string;
primaryButton: string;
primaryButtonText: string;
secondary: string;
secondaryButton: string;
contentBackground: string;
contentBackgroundHover: string;
contentPageBackground: string;
menuBackground: string;
menuBackgroundHover: string;
pageBackground: string;
text: string;
textSecondary: string;
borderLight: string;
border: string;
borderStrong: string;
error: string;
success: string;
warning: string;
}
/**
* Complete theme with light and dark variants
*/
export interface Theme {
name: ThemeName;
light: ThemeColors;
dark: ThemeColors;
}
/**
* Theme context value
*/
export interface ThemeContextValue {
theme: ThemeName;
mode: ColorMode;
isDark: boolean;
setTheme: (theme: ThemeName) => void;
setMode: (mode: ColorMode) => void;
toggleMode: () => void;
}

View file

@ -0,0 +1,109 @@
/**
* UI-related types
*/
/**
* Common size variants
*/
export type Size = 'xs' | 'sm' | 'md' | 'lg' | 'xl';
/**
* Button variants
*/
export type ButtonVariant = 'primary' | 'secondary' | 'ghost' | 'danger' | 'link';
/**
* Text variants
*/
export type TextVariant = 'h1' | 'h2' | 'h3' | 'h4' | 'body' | 'small' | 'muted' | 'code';
/**
* Font weight
*/
export type FontWeight = 'normal' | 'medium' | 'semibold' | 'bold';
/**
* Badge variants
*/
export type BadgeVariant = 'default' | 'primary' | 'secondary' | 'success' | 'warning' | 'error';
/**
* Input types
*/
export type InputType = 'text' | 'email' | 'password' | 'number' | 'tel' | 'url' | 'search';
/**
* Toast/notification types
*/
export type ToastType = 'info' | 'success' | 'warning' | 'error';
/**
* Toast notification
*/
export interface Toast {
id: string;
type: ToastType;
message: string;
title?: string;
duration?: number;
dismissible?: boolean;
}
/**
* Modal configuration
*/
export interface ModalConfig {
title?: string;
description?: string;
confirmText?: string;
cancelText?: string;
dangerous?: boolean;
}
/**
* Dropdown/Select option
*/
export interface SelectOption<T = string> {
value: T;
label: string;
disabled?: boolean;
icon?: string;
}
/**
* Tab item
*/
export interface TabItem {
id: string;
label: string;
icon?: string;
disabled?: boolean;
badge?: string | number;
}
/**
* Menu item
*/
export interface MenuItem {
id: string;
label: string;
icon?: string;
href?: string;
onClick?: () => void;
disabled?: boolean;
danger?: boolean;
divider?: boolean;
}
/**
* Breadcrumb item
*/
export interface BreadcrumbItem {
label: string;
href?: string;
}
/**
* Loading state
*/
export type LoadingState = 'idle' | 'loading' | 'success' | 'error';