- Add Skeletons.tsx with TastingListSkeleton, ChartSkeleton, etc. - Add useOptimistic.ts hooks for React 19 optimistic updates - Update stats page to use skeleton loading instead of spinner - Remove force-dynamic exports (12 files) for SSG compatibility - Note: PPR (cacheComponents) tested but reverted - requires RSC-first refactor
56 lines
2.0 KiB
TypeScript
56 lines
2.0 KiB
TypeScript
|
|
import { createClient } from '@/lib/supabase/server';
|
|
import { redirect } from 'next/navigation';
|
|
import { checkIsAdmin } from '@/services/track-api-usage';
|
|
import { getBanners } from '@/services/banner-actions';
|
|
import Link from 'next/link';
|
|
import { ArrowLeft, Image, ExternalLink, ToggleLeft, ToggleRight, Trash2, Plus, Edit2 } from 'lucide-react';
|
|
import BannerManager from './BannerManager';
|
|
|
|
export default async function AdminBannersPage() {
|
|
const supabase = await createClient();
|
|
const { data: { user } } = await supabase.auth.getUser();
|
|
|
|
if (!user) {
|
|
redirect('/');
|
|
}
|
|
|
|
const isAdmin = await checkIsAdmin(user.id);
|
|
if (!isAdmin) {
|
|
redirect('/');
|
|
}
|
|
|
|
const { banners, error } = await getBanners();
|
|
|
|
return (
|
|
<main className="min-h-screen bg-zinc-950 p-6 pb-24">
|
|
<div className="max-w-4xl mx-auto">
|
|
{/* Header */}
|
|
<div className="flex items-center gap-4 mb-8">
|
|
<Link
|
|
href="/admin"
|
|
className="p-2 rounded-xl bg-zinc-900 border border-zinc-800 text-zinc-400 hover:text-white hover:border-zinc-700 transition-colors"
|
|
>
|
|
<ArrowLeft size={20} />
|
|
</Link>
|
|
<div className="flex-1">
|
|
<h1 className="text-2xl font-bold text-white">Banner Management</h1>
|
|
<p className="text-sm text-zinc-500">
|
|
Manage hero banners for the home page
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
{error && (
|
|
<div className="mb-6 p-4 bg-red-500/20 border border-red-500/50 rounded-xl text-red-400 text-sm">
|
|
Error loading banners: {error}
|
|
</div>
|
|
)}
|
|
|
|
{/* Client Component for Interactive Banner Management */}
|
|
<BannerManager initialBanners={banners} />
|
|
</div>
|
|
</main>
|
|
);
|
|
}
|