updates
This commit is contained in:
30
app/(app)/recap/RecapPageSkeletons.tsx
Normal file
30
app/(app)/recap/RecapPageSkeletons.tsx
Normal file
@@ -0,0 +1,30 @@
|
||||
/**
|
||||
* Shared markup for loading states (used by `loading.tsx` and explicit `<Suspense>` in pages)
|
||||
* so the recap UI always shows the same skeleton while server data is pending.
|
||||
*/
|
||||
export function RecapGridPageSkeleton() {
|
||||
return (
|
||||
<div className="p-4 sm:p-6">
|
||||
<div className="mb-4 h-24 animate-pulse rounded-2xl border border-white/10 bg-black/40" />
|
||||
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2 xl:grid-cols-3">
|
||||
{Array.from({ length: 6 }).map((_, index) => (
|
||||
<div key={index} className="h-[220px] animate-pulse rounded-2xl border border-white/10 bg-white/5" />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export function RecapDetailPageSkeleton() {
|
||||
return (
|
||||
<div className="p-4 sm:p-6">
|
||||
<div className="h-16 animate-pulse rounded-2xl border border-white/10 bg-black/40" />
|
||||
<div className="mt-4 grid grid-cols-1 gap-3 sm:grid-cols-2 xl:grid-cols-4">
|
||||
{Array.from({ length: 4 }).map((_, index) => (
|
||||
<div key={index} className="h-24 animate-pulse rounded-2xl border border-white/10 bg-black/30" />
|
||||
))}
|
||||
</div>
|
||||
<div className="mt-4 h-48 animate-pulse rounded-2xl border border-white/10 bg-black/30" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,13 +1,5 @@
|
||||
import { RecapDetailPageSkeleton } from "../RecapPageSkeletons";
|
||||
|
||||
export default function LoadingRecapDetail() {
|
||||
return (
|
||||
<div className="p-4 sm:p-6">
|
||||
<div className="h-16 animate-pulse rounded-2xl border border-white/10 bg-black/40" />
|
||||
<div className="mt-4 grid grid-cols-1 gap-3 sm:grid-cols-2 xl:grid-cols-4">
|
||||
{Array.from({ length: 4 }).map((_, index) => (
|
||||
<div key={index} className="h-24 animate-pulse rounded-2xl border border-white/10 bg-black/30" />
|
||||
))}
|
||||
</div>
|
||||
<div className="mt-4 h-48 animate-pulse rounded-2xl border border-white/10 bg-black/30" />
|
||||
</div>
|
||||
);
|
||||
return <RecapDetailPageSkeleton />;
|
||||
}
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
import { Suspense } from "react";
|
||||
import { notFound, redirect } from "next/navigation";
|
||||
import { requireSession } from "@/lib/auth/requireSession";
|
||||
import { getRecapMachineDetailCached, parseRecapDetailRangeInput } from "@/lib/recap/redesign";
|
||||
import { RecapDetailPageSkeleton } from "../RecapPageSkeletons";
|
||||
import RecapDetailClient from "./RecapDetailClient";
|
||||
|
||||
export default async function RecapMachineDetailPage({
|
||||
async function RecapDetailData({
|
||||
params,
|
||||
searchParams,
|
||||
}: {
|
||||
@@ -33,3 +35,17 @@ export default async function RecapMachineDetailPage({
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export default function RecapMachineDetailPage({
|
||||
params,
|
||||
searchParams,
|
||||
}: {
|
||||
params: Promise<{ machineId: string }>;
|
||||
searchParams?: Promise<Record<string, string | string[] | undefined>>;
|
||||
}) {
|
||||
return (
|
||||
<Suspense fallback={<RecapDetailPageSkeleton />}>
|
||||
<RecapDetailData params={params} searchParams={searchParams} />
|
||||
</Suspense>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,12 +1,5 @@
|
||||
import { RecapGridPageSkeleton } from "./RecapPageSkeletons";
|
||||
|
||||
export default function LoadingRecapGrid() {
|
||||
return (
|
||||
<div className="p-4 sm:p-6">
|
||||
<div className="mb-4 h-24 animate-pulse rounded-2xl border border-white/10 bg-black/40" />
|
||||
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2 xl:grid-cols-3">
|
||||
{Array.from({ length: 6 }).map((_, index) => (
|
||||
<div key={index} className="h-[220px] animate-pulse rounded-2xl border border-white/10 bg-white/5" />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
return <RecapGridPageSkeleton />;
|
||||
}
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
import { Suspense } from "react";
|
||||
import { redirect } from "next/navigation";
|
||||
import { requireSession } from "@/lib/auth/requireSession";
|
||||
import { getRecapSummaryCached } from "@/lib/recap/redesign";
|
||||
import RecapGridClient from "./RecapGridClient";
|
||||
import { RecapGridPageSkeleton } from "./RecapPageSkeletons";
|
||||
|
||||
export default async function RecapPage() {
|
||||
async function RecapGridData() {
|
||||
const session = await requireSession();
|
||||
if (!session) redirect("/login?next=/recap");
|
||||
|
||||
@@ -14,3 +16,11 @@ export default async function RecapPage() {
|
||||
|
||||
return <RecapGridClient initialData={initialData} />;
|
||||
}
|
||||
|
||||
export default function RecapPage() {
|
||||
return (
|
||||
<Suspense fallback={<RecapGridPageSkeleton />}>
|
||||
<RecapGridData />
|
||||
</Suspense>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user