refactor: consolidate admin authorization into layout and introduce AdminShell component

This commit is contained in:
2026-06-30 22:56:25 +07:00 Unverified
parent 848f93641f
commit e2f480af62
12 changed files with 444 additions and 99 deletions
+81
View File
@@ -0,0 +1,81 @@
"use client";
import { useState } from "react";
import {
Card,
CardContent,
CardHeader,
CardTitle,
} from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { RefreshCw } from "lucide-react";
import { refetchPlatform } from "./actions";
import { toast } from "sonner";
interface Platform {
name: string;
cachedCount: number | null;
}
function formatCount(n: number | null): string {
if (n === null) return "No data";
if (n >= 1_000_000) return `${(n / 1_000_000).toFixed(1)}M`;
if (n >= 1_000) return `${(n / 1_000).toFixed(1)}K`;
return n.toString();
}
export function BackendClient({ platforms }: { platforms: Platform[] }) {
const [data, setData] = useState<Platform[]>(platforms);
const [loading, setLoading] = useState<string | null>(null);
const handleRefetch = async (platform: string) => {
setLoading(platform);
try {
const result = await refetchPlatform(platform);
setData((prev) =>
prev.map((p) =>
p.name === platform ? { ...p, cachedCount: result.count } : p
)
);
toast.success(`${platform} refetched successfully`);
} catch {
toast.error(`Failed to refetch ${platform}`);
} finally {
setLoading(null);
}
};
return (
<div className="grid gap-4 sm:grid-cols-2">
{data.map((p) => (
<Card key={p.name}>
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
<CardTitle className="text-sm font-medium capitalize">
{p.name}
</CardTitle>
<Badge
variant={p.cachedCount !== null ? "default" : "secondary"}
>
{formatCount(p.cachedCount)}
</Badge>
</CardHeader>
<CardContent>
<Button
variant="outline"
size="sm"
className="gap-2"
disabled={loading !== null}
onClick={() => handleRefetch(p.name)}
>
<RefreshCw
className={`w-3 h-3 ${loading === p.name ? "animate-spin" : ""}`}
/>
Refetch
</Button>
</CardContent>
</Card>
))}
</div>
);
}