Skip to content

Commit

Permalink
Add loading skeleton to admin page
Browse files Browse the repository at this point in the history
  • Loading branch information
aahnik committed Jan 10, 2025
1 parent a4c41de commit c544e8a
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 16 deletions.
22 changes: 6 additions & 16 deletions app/admin/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ import { Organization } from "./mockData";
import StatCard from "@/components/stat-card";
import { useEffect, useState } from "react";
import { fetchApi } from "@/lib/client/fetch";
import { UnauthorizedPage } from "@/mint/unauthorized";

import { notFound } from "next/navigation";
import { PageSkeleton } from "@/components/ui/page-skeleton";

interface AdminData {
platformStats: {
Expand Down Expand Up @@ -33,8 +35,8 @@ const columns: ColumnDef<Organization>[] = [

export default function AdminPage() {
const [data, setData] = useState<AdminData | null>(null);
const [isLoading, setIsLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
const [isLoading, setIsLoading] = useState(true);

useEffect(() => {
const fetchData = async () => {
Expand All @@ -56,23 +58,11 @@ export default function AdminPage() {
}, []);

if (isLoading) {
return (
<div className="flex items-center justify-center min-h-screen">
Loading...
</div>
);
}

if (error === "unauthorized") {
return <UnauthorizedPage />;
return <PageSkeleton />;
}

if (error || !data) {
return (
<div className="flex items-center justify-center min-h-screen">
Error: {error}
</div>
);
return notFound();
}

return (
Expand Down
40 changes: 40 additions & 0 deletions app/skeleton/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
"use client";

import { PageSkeleton } from "@/components/ui/page-skeleton";
import { Button } from "@/components/ui/button";
import { useTheme } from "@/contexts/theme-context";

export default function SkeletonDebugPage() {
const { theme, setTheme } = useTheme();

return (
<div className="min-h-screen">
<div className="container mx-auto p-4">
<div className="flex justify-end mb-4 gap-2">
<Button
variant="outline"
onClick={() => setTheme("light")}
className={theme === "light" ? "border-primary" : ""}
>
Light
</Button>
<Button
variant="outline"
onClick={() => setTheme("dark")}
className={theme === "dark" ? "border-primary" : ""}
>
Dark
</Button>
<Button
variant="outline"
onClick={() => setTheme("system")}
className={theme === "system" ? "border-primary" : ""}
>
System
</Button>
</div>
</div>
<PageSkeleton />
</div>
);
}
42 changes: 42 additions & 0 deletions components/ui/page-skeleton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
"use client";

import { Skeleton } from "@/components/ui/skeleton";
import { Card } from "@/components/ui/card";

export function PageSkeleton() {
return (
<div className="container mx-auto p-6 space-y-8">
{/* Header Section */}
<div className="space-y-4">
<Skeleton className="h-8 w-[250px]" />
<Skeleton className="h-4 w-[350px]" />
</div>

{/* Content Grid */}
<div className="grid gap-6 md:grid-cols-2 lg:grid-cols-3">
{[1, 2, 3].map((i) => (
<Card key={i} className="p-6 space-y-4">
<Skeleton className="h-4 w-[100px]" />
<Skeleton className="h-20 w-full" />
<div className="space-y-2">
<Skeleton className="h-3 w-[140px]" />
<Skeleton className="h-3 w-[100px]" />
</div>
</Card>
))}
</div>

{/* Table/List Section */}
<Card className="p-6">
<div className="space-y-4">
<Skeleton className="h-6 w-[200px]" />
<div className="space-y-2">
{[1, 2, 3, 4].map((i) => (
<Skeleton key={i} className="h-12 w-full" />
))}
</div>
</div>
</Card>
</div>
);
}

0 comments on commit c544e8a

Please sign in to comment.