85 lines
2.7 KiB
TypeScript
85 lines
2.7 KiB
TypeScript
"use client";
|
|
|
|
import { Suspense, lazy, useEffect, useState } from "react";
|
|
import { useSession } from "next-auth/react";
|
|
|
|
// Dynamic imports with lazy loading
|
|
const QuoteCard = lazy(() => import("@/components/quote-card").then(mod => ({ default: mod.QuoteCard })));
|
|
const Calendar = lazy(() => import("@/components/calendar").then(mod => ({ default: mod.Calendar })));
|
|
const News = lazy(() => import("@/components/news").then(mod => ({ default: mod.News })));
|
|
const Duties = lazy(() => import("@/components/flow").then(mod => ({ default: mod.Duties })));
|
|
const Email = lazy(() => import("@/components/email").then(mod => ({ default: mod.Email })));
|
|
const Parole = lazy(() => import("@/components/parole").then(mod => ({ default: mod.Parole })));
|
|
|
|
// Skeleton loaders for each component
|
|
const QuoteCardSkeleton = () => (
|
|
<div className="bg-gray-100 animate-pulse rounded-lg h-72 w-full"></div>
|
|
);
|
|
|
|
const GenericSkeleton = () => (
|
|
<div className="bg-gray-100 animate-pulse rounded-lg h-96 w-full"></div>
|
|
);
|
|
|
|
export default function Home() {
|
|
const { data: session, status } = useSession();
|
|
const [isLoading, setIsLoading] = useState(true);
|
|
|
|
useEffect(() => {
|
|
if (status !== "loading") {
|
|
setIsLoading(false);
|
|
}
|
|
}, [status]);
|
|
|
|
if (isLoading) {
|
|
return (
|
|
<main className="h-screen flex items-center justify-center">
|
|
<div className="animate-spin rounded-full h-32 w-32 border-t-2 border-b-2 border-gray-900"></div>
|
|
</main>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<main className="h-screen overflow-auto">
|
|
<div className="container mx-auto p-4 mt-12">
|
|
{/* First row */}
|
|
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4 mb-4">
|
|
<div>
|
|
<Suspense fallback={<QuoteCardSkeleton />}>
|
|
<QuoteCard />
|
|
</Suspense>
|
|
</div>
|
|
<div>
|
|
<Suspense fallback={<GenericSkeleton />}>
|
|
<Calendar limit={5} showMore={true} showRefresh={true} />
|
|
</Suspense>
|
|
</div>
|
|
<div>
|
|
<Suspense fallback={<GenericSkeleton />}>
|
|
<News />
|
|
</Suspense>
|
|
</div>
|
|
<div>
|
|
<Suspense fallback={<GenericSkeleton />}>
|
|
<Duties />
|
|
</Suspense>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Second row */}
|
|
<div className="grid grid-cols-1 lg:grid-cols-2 gap-4">
|
|
<div>
|
|
<Suspense fallback={<GenericSkeleton />}>
|
|
<Email />
|
|
</Suspense>
|
|
</div>
|
|
<div>
|
|
<Suspense fallback={<GenericSkeleton />}>
|
|
<Parole />
|
|
</Suspense>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</main>
|
|
);
|
|
}
|