2026-01-13 18:47:57 +00:00
|
|
|
import {
|
|
|
|
|
Suspense,
|
|
|
|
|
lazy,
|
|
|
|
|
type ComponentType,
|
|
|
|
|
Component,
|
|
|
|
|
type ErrorInfo,
|
|
|
|
|
} from 'react';
|
2025-12-03 21:56:50 +00:00
|
|
|
import { LoadingSpinner } from './loading-spinner';
|
2026-01-07 18:39:21 +00:00
|
|
|
// import { ErrorBoundary } from '@/components/ErrorBoundary';
|
2026-01-07 09:31:02 +00:00
|
|
|
import { logger } from '@/utils/logger';
|
|
|
|
|
import { Button } from './button';
|
|
|
|
|
import { AlertTriangle, RefreshCw } from 'lucide-react';
|
2025-12-03 21:56:50 +00:00
|
|
|
|
2026-01-07 09:31:02 +00:00
|
|
|
// CRITIQUE FIX #16: Composant de fallback amélioré pour les erreurs de chargement lazy
|
2026-01-07 18:39:21 +00:00
|
|
|
function LazyErrorFallback({
|
|
|
|
|
pageName,
|
|
|
|
|
error,
|
2026-01-13 18:47:57 +00:00
|
|
|
onRetry,
|
2026-01-07 18:39:21 +00:00
|
|
|
}: {
|
2026-01-07 09:31:02 +00:00
|
|
|
pageName: string;
|
|
|
|
|
error?: Error;
|
|
|
|
|
onRetry?: () => void;
|
|
|
|
|
}) {
|
2025-12-17 14:15:45 +00:00
|
|
|
return (
|
|
|
|
|
<div className="container mx-auto px-4 py-8">
|
|
|
|
|
<div className="max-w-2xl mx-auto">
|
2026-01-07 09:31:02 +00:00
|
|
|
<div className="flex items-center gap-3 mb-4">
|
|
|
|
|
<AlertTriangle className="h-6 w-6 text-yellow-600" />
|
2026-01-15 22:54:05 +00:00
|
|
|
<h1 className="text-3xl font-bold">{pageName}</h1>
|
2026-01-07 09:31:02 +00:00
|
|
|
</div>
|
|
|
|
|
<div className="bg-yellow-50 dark:bg-yellow-900/20 border border-yellow-200 dark:border-yellow-800 text-yellow-700 dark:text-yellow-300 px-4 py-3 rounded-lg mb-4">
|
|
|
|
|
<p className="font-medium mb-2">Failed to load {pageName}</p>
|
|
|
|
|
{error && (
|
|
|
|
|
<p className="text-sm opacity-75">
|
|
|
|
|
{error.message || 'An error occurred while loading this page'}
|
|
|
|
|
</p>
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
<div className="flex gap-3">
|
|
|
|
|
{onRetry && (
|
2026-01-13 18:47:57 +00:00
|
|
|
<Button
|
|
|
|
|
onClick={onRetry}
|
|
|
|
|
variant="outline"
|
|
|
|
|
className="flex items-center gap-2"
|
|
|
|
|
>
|
2026-01-07 09:31:02 +00:00
|
|
|
<RefreshCw className="h-4 w-4" />
|
|
|
|
|
Retry
|
|
|
|
|
</Button>
|
|
|
|
|
)}
|
2026-01-07 18:39:21 +00:00
|
|
|
<Button
|
|
|
|
|
onClick={() => window.location.reload()}
|
2026-01-07 09:31:02 +00:00
|
|
|
variant="default"
|
|
|
|
|
className="flex items-center gap-2"
|
|
|
|
|
>
|
|
|
|
|
Refresh Page
|
|
|
|
|
</Button>
|
2025-12-17 14:15:45 +00:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-07 09:31:02 +00:00
|
|
|
// CRITIQUE FIX #16: ErrorBoundary spécifique pour les composants lazy
|
|
|
|
|
class LazyErrorBoundary extends Component<
|
2026-01-07 18:39:21 +00:00
|
|
|
{
|
|
|
|
|
children: React.ReactNode;
|
2026-01-07 09:31:02 +00:00
|
|
|
pageName: string;
|
|
|
|
|
onError?: (error: Error, errorInfo: ErrorInfo) => void;
|
|
|
|
|
},
|
|
|
|
|
{ hasError: boolean; error?: Error }
|
|
|
|
|
> {
|
2026-01-13 18:47:57 +00:00
|
|
|
constructor(props: {
|
|
|
|
|
children: React.ReactNode;
|
|
|
|
|
pageName: string;
|
|
|
|
|
onError?: (error: Error, errorInfo: ErrorInfo) => void;
|
|
|
|
|
}) {
|
2026-01-07 09:31:02 +00:00
|
|
|
super(props);
|
|
|
|
|
this.state = { hasError: false };
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static getDerivedStateFromError(error: Error) {
|
|
|
|
|
return { hasError: true, error };
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
override componentDidCatch(error: Error, errorInfo: ErrorInfo) {
|
|
|
|
|
// CRITIQUE FIX #16: Logger l'erreur avec le logger centralisé au lieu de console.error
|
|
|
|
|
logger.error('[LazyComponent] Failed to load lazy component', {
|
|
|
|
|
pageName: this.props.pageName,
|
|
|
|
|
error: error.message,
|
|
|
|
|
stack: error.stack,
|
|
|
|
|
componentStack: errorInfo.componentStack,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (this.props.onError) {
|
|
|
|
|
this.props.onError(error, errorInfo);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
handleRetry = () => {
|
|
|
|
|
this.setState({ hasError: false, error: undefined });
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
override render() {
|
|
|
|
|
if (this.state.hasError) {
|
|
|
|
|
return (
|
2026-01-07 18:39:21 +00:00
|
|
|
<LazyErrorFallback
|
|
|
|
|
pageName={this.props.pageName}
|
2026-01-07 09:31:02 +00:00
|
|
|
error={this.state.error}
|
|
|
|
|
onRetry={this.handleRetry}
|
|
|
|
|
/>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return this.props.children;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* LazyComponentProps - Propriétés pour les composants lazy créés
|
2026-01-13 18:47:57 +00:00
|
|
|
*
|
2026-01-07 09:31:02 +00:00
|
|
|
* @interface LazyComponentProps
|
|
|
|
|
*/
|
2025-12-03 21:56:50 +00:00
|
|
|
interface LazyComponentProps {
|
2026-01-07 09:31:02 +00:00
|
|
|
/**
|
|
|
|
|
* Composant de fallback personnalisé à afficher pendant le chargement
|
|
|
|
|
* Si non fourni, utilise LoadingSpinner par défaut
|
|
|
|
|
*/
|
2025-12-03 21:56:50 +00:00
|
|
|
fallback?: React.ReactNode;
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-07 09:31:02 +00:00
|
|
|
/**
|
|
|
|
|
* createLazyComponent - Factory pour créer des composants lazy avec Suspense
|
2026-01-13 18:47:57 +00:00
|
|
|
*
|
2026-01-07 09:31:02 +00:00
|
|
|
* Crée un composant lazy avec gestion automatique du Suspense et du fallback.
|
|
|
|
|
* Utile pour le code splitting et le chargement à la demande des composants.
|
2026-01-13 18:47:57 +00:00
|
|
|
*
|
2026-01-07 09:31:02 +00:00
|
|
|
* @template T - Type du composant à charger
|
|
|
|
|
* @param {() => Promise<{ default: T }>} importFunc - Fonction d'import dynamique
|
|
|
|
|
* @param {React.ReactNode} fallback - Composant de fallback (optionnel)
|
|
|
|
|
* @returns {ComponentType} Composant wrapper avec Suspense intégré
|
2026-01-13 18:47:57 +00:00
|
|
|
*
|
2026-01-07 09:31:02 +00:00
|
|
|
* @example
|
|
|
|
|
* ```tsx
|
|
|
|
|
* // Créer un composant lazy
|
|
|
|
|
* const LazyDashboard = createLazyComponent(
|
|
|
|
|
* () => import('@/pages/DashboardPage').then(m => ({ default: m.DashboardPage }))
|
|
|
|
|
* );
|
2026-01-13 18:47:57 +00:00
|
|
|
*
|
2026-01-07 09:31:02 +00:00
|
|
|
* // Utiliser le composant lazy
|
|
|
|
|
* <LazyDashboard fallback={<CustomLoader />} />
|
|
|
|
|
* ```
|
2026-01-13 18:47:57 +00:00
|
|
|
*
|
2026-01-07 09:31:02 +00:00
|
|
|
* @function
|
|
|
|
|
*/
|
|
|
|
|
// CRITIQUE FIX #16: Wrapper pour gérer les erreurs de chargement lazy de manière standardisée
|
|
|
|
|
function createLazyWithErrorHandling<T extends ComponentType<any>>(
|
|
|
|
|
importFunc: () => Promise<{ default: T }>,
|
|
|
|
|
pageName: string,
|
|
|
|
|
) {
|
|
|
|
|
return importFunc().catch((err) => {
|
|
|
|
|
// CRITIQUE FIX #16: Logger l'erreur avec le logger centralisé
|
|
|
|
|
logger.error('[LazyComponent] Failed to import lazy component', {
|
|
|
|
|
pageName,
|
|
|
|
|
error: err instanceof Error ? err.message : String(err),
|
|
|
|
|
stack: err instanceof Error ? err.stack : undefined,
|
|
|
|
|
});
|
2026-01-07 18:39:21 +00:00
|
|
|
|
2026-01-07 09:31:02 +00:00
|
|
|
// Retourner un composant d'erreur au lieu de laisser l'erreur se propager
|
2026-01-07 18:39:21 +00:00
|
|
|
return Promise.resolve({
|
2026-01-13 18:47:57 +00:00
|
|
|
default: () => (
|
|
|
|
|
<LazyErrorFallback
|
|
|
|
|
pageName={pageName}
|
|
|
|
|
error={err instanceof Error ? err : new Error(String(err))}
|
|
|
|
|
/>
|
|
|
|
|
),
|
2026-01-07 18:39:21 +00:00
|
|
|
}) as unknown as Promise<{ default: T }>;
|
2026-01-07 09:31:02 +00:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-03 21:56:50 +00:00
|
|
|
export function createLazyComponent<T extends ComponentType<any>>(
|
|
|
|
|
importFunc: () => Promise<{ default: T }>,
|
2025-12-13 02:34:34 +00:00
|
|
|
fallback?: React.ReactNode,
|
2026-01-07 09:31:02 +00:00
|
|
|
pageName?: string,
|
2025-12-03 21:56:50 +00:00
|
|
|
) {
|
2026-01-07 09:31:02 +00:00
|
|
|
// CRITIQUE FIX #16: Utiliser la fonction avec gestion d'erreur si pageName est fourni
|
2026-01-07 18:39:21 +00:00
|
|
|
const safeImportFunc = pageName
|
2026-01-07 09:31:02 +00:00
|
|
|
? () => createLazyWithErrorHandling(importFunc, pageName)
|
|
|
|
|
: importFunc;
|
2026-01-07 18:39:21 +00:00
|
|
|
|
2026-01-07 09:31:02 +00:00
|
|
|
const LazyComponent = lazy(safeImportFunc);
|
2025-12-03 21:56:50 +00:00
|
|
|
|
|
|
|
|
return function WrappedLazyComponent(
|
2025-12-13 02:34:34 +00:00
|
|
|
props: React.ComponentProps<T> & LazyComponentProps,
|
2025-12-03 21:56:50 +00:00
|
|
|
) {
|
2025-12-17 14:15:45 +00:00
|
|
|
// Extraire fallback des props pour ne pas le passer au composant lazy
|
|
|
|
|
const { fallback: _fallback, ...componentProps } = props;
|
2026-01-07 18:39:21 +00:00
|
|
|
|
2026-01-07 09:31:02 +00:00
|
|
|
// CRITIQUE FIX #16: Wrapper avec ErrorBoundary pour capturer les erreurs runtime
|
|
|
|
|
const component = (
|
2025-12-03 21:56:50 +00:00
|
|
|
<Suspense fallback={fallback || <LoadingSpinner />}>
|
2025-12-17 14:15:45 +00:00
|
|
|
{/* @ts-expect-error - LazyComponent props are compatible but TypeScript can't infer it */}
|
|
|
|
|
<LazyComponent {...componentProps} />
|
2025-12-03 21:56:50 +00:00
|
|
|
</Suspense>
|
|
|
|
|
);
|
2026-01-07 09:31:02 +00:00
|
|
|
|
|
|
|
|
// Si pageName est fourni, wrapper avec LazyErrorBoundary
|
|
|
|
|
if (pageName) {
|
|
|
|
|
return (
|
2026-01-13 18:47:57 +00:00
|
|
|
<LazyErrorBoundary pageName={pageName}>{component}</LazyErrorBoundary>
|
2026-01-07 09:31:02 +00:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return component;
|
2025-12-03 21:56:50 +00:00
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Composants lazy communs
|
2026-01-07 09:31:02 +00:00
|
|
|
// CRITIQUE FIX #16: Ajouter pageName pour tous les composants lazy pour une meilleure gestion d'erreur
|
|
|
|
|
export const LazyDashboard = createLazyComponent(
|
2026-01-13 18:47:57 +00:00
|
|
|
() =>
|
|
|
|
|
import('@/pages/DashboardPage').then((m) => ({ default: m.DashboardPage })),
|
2026-01-07 09:31:02 +00:00
|
|
|
undefined,
|
|
|
|
|
'Dashboard',
|
2025-12-03 21:56:50 +00:00
|
|
|
);
|
2026-01-07 09:31:02 +00:00
|
|
|
export const LazyChat = createLazyComponent(
|
2026-01-13 18:47:57 +00:00
|
|
|
() =>
|
|
|
|
|
import('@/features/chat/pages/ChatPage').then((m) => ({
|
|
|
|
|
default: m.ChatPage,
|
|
|
|
|
})),
|
2026-01-07 09:31:02 +00:00
|
|
|
undefined,
|
|
|
|
|
'Chat',
|
2025-12-03 21:56:50 +00:00
|
|
|
);
|
2026-01-07 09:31:02 +00:00
|
|
|
// CRITIQUE FIX #16: Tous les composants lazy utilisent maintenant la gestion d'erreur standardisée
|
2025-12-03 21:56:50 +00:00
|
|
|
export const LazyLibrary = createLazyComponent(
|
2026-01-13 18:47:57 +00:00
|
|
|
() =>
|
|
|
|
|
import('@/features/library/pages/LibraryPage').then((m) => ({
|
|
|
|
|
default: m.default,
|
|
|
|
|
})),
|
2026-01-07 09:31:02 +00:00
|
|
|
undefined,
|
|
|
|
|
'Library',
|
|
|
|
|
);
|
|
|
|
|
export const LazyProfile = createLazyComponent(
|
|
|
|
|
() => import('@/pages/ProfilePage').then((m) => ({ default: m.ProfilePage })),
|
|
|
|
|
undefined,
|
|
|
|
|
'Profile',
|
|
|
|
|
);
|
|
|
|
|
export const LazySettings = createLazyComponent(
|
2026-01-13 18:47:57 +00:00
|
|
|
() =>
|
|
|
|
|
import('@/pages/SettingsPage').then((m) => ({ default: m.SettingsPage })),
|
2026-01-07 09:31:02 +00:00
|
|
|
undefined,
|
|
|
|
|
'Settings',
|
|
|
|
|
);
|
|
|
|
|
export const LazyLogin = createLazyComponent(
|
|
|
|
|
() => import('@/pages/LoginPage').then((m) => ({ default: m.LoginPage })),
|
|
|
|
|
undefined,
|
|
|
|
|
'Login',
|
|
|
|
|
);
|
|
|
|
|
export const LazyRegister = createLazyComponent(
|
2026-01-13 18:47:57 +00:00
|
|
|
() =>
|
|
|
|
|
import('@/pages/RegisterPage').then((m) => ({ default: m.RegisterPage })),
|
2026-01-07 09:31:02 +00:00
|
|
|
undefined,
|
|
|
|
|
'Register',
|
2025-12-03 21:56:50 +00:00
|
|
|
);
|
|
|
|
|
export const LazyForgotPassword = createLazyComponent(
|
2025-12-13 02:34:34 +00:00
|
|
|
() => import('@/features/auth/pages/ForgotPasswordPage'),
|
2026-01-07 09:31:02 +00:00
|
|
|
undefined,
|
|
|
|
|
'Forgot Password',
|
2025-12-03 21:56:50 +00:00
|
|
|
);
|
|
|
|
|
export const LazyVerifyEmail = createLazyComponent(
|
2025-12-13 02:34:34 +00:00
|
|
|
() => import('@/features/auth/pages/VerifyEmailPage'),
|
2026-01-07 09:31:02 +00:00
|
|
|
undefined,
|
|
|
|
|
'Verify Email',
|
2025-12-03 21:56:50 +00:00
|
|
|
);
|
|
|
|
|
export const LazyResetPassword = createLazyComponent(
|
2025-12-13 02:34:34 +00:00
|
|
|
() => import('@/features/auth/pages/ResetPasswordPage'),
|
2026-01-07 09:31:02 +00:00
|
|
|
undefined,
|
|
|
|
|
'Reset Password',
|
2025-12-03 21:56:50 +00:00
|
|
|
);
|
|
|
|
|
export const LazySessions = createLazyComponent(
|
2025-12-13 02:34:34 +00:00
|
|
|
() => import('@/features/auth/pages/SessionsPage'),
|
2026-01-07 09:31:02 +00:00
|
|
|
undefined,
|
|
|
|
|
'Sessions',
|
2025-12-03 21:56:50 +00:00
|
|
|
);
|
|
|
|
|
export const LazyNotFound = createLazyComponent(
|
2025-12-13 02:34:34 +00:00
|
|
|
() => import('@/features/error/pages/NotFoundPage'),
|
2026-01-07 09:31:02 +00:00
|
|
|
undefined,
|
|
|
|
|
'Not Found',
|
2025-12-03 21:56:50 +00:00
|
|
|
);
|
|
|
|
|
export const LazyServerError = createLazyComponent(
|
2025-12-13 02:34:34 +00:00
|
|
|
() => import('@/features/error/pages/ServerErrorPage'),
|
2026-01-07 09:31:02 +00:00
|
|
|
undefined,
|
|
|
|
|
'Server Error',
|
|
|
|
|
);
|
|
|
|
|
export const LazyUserProfile = createLazyComponent(
|
2026-01-13 18:47:57 +00:00
|
|
|
() =>
|
|
|
|
|
import('@/features/profile/pages/UserProfilePage').then((m) => ({
|
|
|
|
|
default: m.UserProfilePage,
|
|
|
|
|
})),
|
2026-01-07 09:31:02 +00:00
|
|
|
undefined,
|
|
|
|
|
'User Profile',
|
|
|
|
|
);
|
|
|
|
|
export const LazyRoles = createLazyComponent(
|
2026-01-13 18:47:57 +00:00
|
|
|
() =>
|
|
|
|
|
import('@/features/roles/pages/RolesPage').then((m) => ({
|
|
|
|
|
default: m.RolesPage,
|
|
|
|
|
})),
|
2026-01-07 09:31:02 +00:00
|
|
|
undefined,
|
|
|
|
|
'Roles',
|
|
|
|
|
);
|
|
|
|
|
export const LazyTrackDetail = createLazyComponent(
|
2026-01-13 18:47:57 +00:00
|
|
|
() =>
|
|
|
|
|
import('@/features/tracks/pages/TrackDetailPage').then((m) => ({
|
|
|
|
|
default: m.TrackDetailPage,
|
|
|
|
|
})),
|
2026-01-07 09:31:02 +00:00
|
|
|
undefined,
|
|
|
|
|
'Track Detail',
|
2025-12-03 21:56:50 +00:00
|
|
|
);
|
2026-01-07 09:31:02 +00:00
|
|
|
export const LazyPlaylistRoutes = createLazyComponent(
|
2026-01-13 18:47:57 +00:00
|
|
|
() =>
|
|
|
|
|
import('@/features/playlists/routes').then((m) => ({
|
|
|
|
|
default: m.PlaylistRoutes,
|
|
|
|
|
})),
|
2026-01-07 09:31:02 +00:00
|
|
|
undefined,
|
|
|
|
|
'Playlists',
|
|
|
|
|
);
|
|
|
|
|
export const LazySearch = createLazyComponent(
|
|
|
|
|
() => import('@/pages/SearchPage').then((m) => ({ default: m.SearchPage })),
|
|
|
|
|
undefined,
|
|
|
|
|
'Search',
|
|
|
|
|
);
|
|
|
|
|
export const LazyNotifications = createLazyComponent(
|
2026-01-13 18:47:57 +00:00
|
|
|
() =>
|
|
|
|
|
import('@/features/notifications/pages/NotificationsPage').then((m) => ({
|
|
|
|
|
default: m.NotificationsPage,
|
|
|
|
|
})),
|
2026-01-07 09:31:02 +00:00
|
|
|
undefined,
|
|
|
|
|
'Notifications',
|
|
|
|
|
);
|
|
|
|
|
export const LazyMarketplace = createLazyComponent(
|
2026-01-13 18:47:57 +00:00
|
|
|
() =>
|
|
|
|
|
import('@/pages/marketplace/MarketplaceHome').then((m) => ({
|
|
|
|
|
default: m.MarketplaceHome,
|
|
|
|
|
})),
|
2026-01-07 09:31:02 +00:00
|
|
|
undefined,
|
|
|
|
|
'Marketplace',
|
|
|
|
|
);
|
|
|
|
|
export const LazyAnalytics = createLazyComponent(
|
2026-01-13 18:47:57 +00:00
|
|
|
() =>
|
|
|
|
|
import('@/pages/AnalyticsPage').then((m) => ({ default: m.AnalyticsPage })),
|
2026-01-07 09:31:02 +00:00
|
|
|
undefined,
|
|
|
|
|
'Analytics',
|
|
|
|
|
);
|
|
|
|
|
export const LazyWebhooks = createLazyComponent(
|
2026-01-13 18:47:57 +00:00
|
|
|
() =>
|
|
|
|
|
import('@/pages/WebhooksPage').then((m) => ({ default: m.WebhooksPage })),
|
2026-01-07 09:31:02 +00:00
|
|
|
undefined,
|
|
|
|
|
'Webhooks',
|
|
|
|
|
);
|
|
|
|
|
export const LazyAdminDashboard = createLazyComponent(
|
2026-01-13 18:47:57 +00:00
|
|
|
() =>
|
|
|
|
|
import('@/pages/AdminDashboardPage').then((m) => ({
|
|
|
|
|
default: m.AdminDashboardPage,
|
|
|
|
|
})),
|
2026-01-07 09:31:02 +00:00
|
|
|
undefined,
|
|
|
|
|
'Admin Dashboard',
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
export const LazyDesignSystemDemo = createLazyComponent(
|
2026-01-13 18:47:57 +00:00
|
|
|
() =>
|
|
|
|
|
import('@/pages/DesignSystemDemoPage').then((m) => ({
|
|
|
|
|
default: m.default,
|
|
|
|
|
})),
|
2026-01-07 09:31:02 +00:00
|
|
|
undefined,
|
|
|
|
|
'Design System Demo',
|
2025-12-25 10:29:27 +00:00
|
|
|
);
|
feat: Visual masterpiece - true light mode & premium UI
🎨 **True Light/Dark Mode**
- Implemented proper light mode with inverted color scheme
- Smooth theme transitions (0.3s ease)
- Light mode colors: white backgrounds, dark text, vibrant accents
- System theme detection with proper class application
🌈 **Enhanced Theme System**
- 4 color themes work in both light and dark modes
- Cyber (cyan/magenta), Ocean (blue/teal), Forest (green/lime), Sunset (orange/purple)
- Theme-specific glassmorphism effects
- Proper contrast in light mode
✨ **Premium Animations**
- Float, glow-pulse, slide-in, scale-in, rotate-in animations
- Smooth page transitions
- Hover effects with depth (lift, glow, scale)
- Micro-interactions on all interactive elements
🎯 **Visual Polish**
- Enhanced glassmorphism for light/dark modes
- Custom scrollbar with theme colors
- Beautiful text selection
- Focus indicators for accessibility
- Premium utility classes
🔧 **Technical Improvements**
- Updated UIStore to properly apply light/dark classes
- Added data-theme attribute for CSS targeting
- Smooth scroll behavior
- Optimized transitions
The app is now a visual masterpiece with perfect light/dark mode support!
2026-01-11 01:32:21 +00:00
|
|
|
|
|
|
|
|
// New pages for navigation fix
|
|
|
|
|
export const LazySocial = createLazyComponent(
|
|
|
|
|
() => import('@/pages/SocialPage').then((m) => ({ default: m.SocialPage })),
|
|
|
|
|
undefined,
|
|
|
|
|
'Social Feed',
|
|
|
|
|
);
|
|
|
|
|
export const LazyGear = createLazyComponent(
|
|
|
|
|
() => import('@/pages/GearPage').then((m) => ({ default: m.GearPage })),
|
|
|
|
|
undefined,
|
|
|
|
|
'Gear Locker',
|
|
|
|
|
);
|
|
|
|
|
export const LazyLive = createLazyComponent(
|
|
|
|
|
() => import('@/pages/LivePage').then((m) => ({ default: m.LivePage })),
|
|
|
|
|
undefined,
|
|
|
|
|
'Live Sessions',
|
|
|
|
|
);
|
|
|
|
|
export const LazyEducation = createLazyComponent(
|
2026-01-13 18:47:57 +00:00
|
|
|
() =>
|
|
|
|
|
import('@/pages/EducationPage').then((m) => ({ default: m.EducationPage })),
|
feat: Visual masterpiece - true light mode & premium UI
🎨 **True Light/Dark Mode**
- Implemented proper light mode with inverted color scheme
- Smooth theme transitions (0.3s ease)
- Light mode colors: white backgrounds, dark text, vibrant accents
- System theme detection with proper class application
🌈 **Enhanced Theme System**
- 4 color themes work in both light and dark modes
- Cyber (cyan/magenta), Ocean (blue/teal), Forest (green/lime), Sunset (orange/purple)
- Theme-specific glassmorphism effects
- Proper contrast in light mode
✨ **Premium Animations**
- Float, glow-pulse, slide-in, scale-in, rotate-in animations
- Smooth page transitions
- Hover effects with depth (lift, glow, scale)
- Micro-interactions on all interactive elements
🎯 **Visual Polish**
- Enhanced glassmorphism for light/dark modes
- Custom scrollbar with theme colors
- Beautiful text selection
- Focus indicators for accessibility
- Premium utility classes
🔧 **Technical Improvements**
- Updated UIStore to properly apply light/dark classes
- Added data-theme attribute for CSS targeting
- Smooth scroll behavior
- Optimized transitions
The app is now a visual masterpiece with perfect light/dark mode support!
2026-01-11 01:32:21 +00:00
|
|
|
undefined,
|
|
|
|
|
'Education',
|
|
|
|
|
);
|
|
|
|
|
export const LazyQueue = createLazyComponent(
|
|
|
|
|
() => import('@/pages/QueuePage').then((m) => ({ default: m.QueuePage })),
|
|
|
|
|
undefined,
|
|
|
|
|
'Queue',
|
|
|
|
|
);
|
|
|
|
|
export const LazyDeveloper = createLazyComponent(
|
2026-01-13 18:47:57 +00:00
|
|
|
() =>
|
|
|
|
|
import('@/pages/DeveloperPage').then((m) => ({ default: m.DeveloperPage })),
|
feat: Visual masterpiece - true light mode & premium UI
🎨 **True Light/Dark Mode**
- Implemented proper light mode with inverted color scheme
- Smooth theme transitions (0.3s ease)
- Light mode colors: white backgrounds, dark text, vibrant accents
- System theme detection with proper class application
🌈 **Enhanced Theme System**
- 4 color themes work in both light and dark modes
- Cyber (cyan/magenta), Ocean (blue/teal), Forest (green/lime), Sunset (orange/purple)
- Theme-specific glassmorphism effects
- Proper contrast in light mode
✨ **Premium Animations**
- Float, glow-pulse, slide-in, scale-in, rotate-in animations
- Smooth page transitions
- Hover effects with depth (lift, glow, scale)
- Micro-interactions on all interactive elements
🎯 **Visual Polish**
- Enhanced glassmorphism for light/dark modes
- Custom scrollbar with theme colors
- Beautiful text selection
- Focus indicators for accessibility
- Premium utility classes
🔧 **Technical Improvements**
- Updated UIStore to properly apply light/dark classes
- Added data-theme attribute for CSS targeting
- Smooth scroll behavior
- Optimized transitions
The app is now a visual masterpiece with perfect light/dark mode support!
2026-01-11 01:32:21 +00:00
|
|
|
undefined,
|
|
|
|
|
'Developer API',
|
|
|
|
|
);
|