@@ -0,0 +1,72 @@
|
||||
"use client";
|
||||
|
||||
import { useAuth } from "@/components/AuthProvider";
|
||||
import { ItemEditor } from "@/components/ItemEditor";
|
||||
import { useParams, useRouter } from "next/navigation";
|
||||
import { useEffect, useState } from "react";
|
||||
import { Button } from "@/components/ui/button";
|
||||
|
||||
type Campaign = {
|
||||
id: string;
|
||||
name: string;
|
||||
gridSize: number;
|
||||
};
|
||||
|
||||
export default function EditCampaignPage() {
|
||||
const { user, loading: authLoading } = useAuth();
|
||||
const params = useParams();
|
||||
const router = useRouter();
|
||||
const [campaign, setCampaign] = useState<Campaign | null>(null);
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
useEffect(() => {
|
||||
if (authLoading) return;
|
||||
if (!user || !user.isAdmin) { router.push("/"); return; }
|
||||
|
||||
const campaignId = params.campaignId as string;
|
||||
fetch("/api/campaigns")
|
||||
.then(r => r.json())
|
||||
.then(campaigns => {
|
||||
const c = campaigns.find((c: Campaign) => c.id === campaignId);
|
||||
if (c) setCampaign(c);
|
||||
})
|
||||
.finally(() => setLoading(false));
|
||||
}, [user, authLoading, params.campaignId, router]);
|
||||
|
||||
if (authLoading || loading) {
|
||||
return (
|
||||
<div className="flex items-center justify-center min-h-[60vh]">
|
||||
<div className="text-center font-mono text-sm text-slate-600 animate-pulse">Loading...</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (!campaign) {
|
||||
return (
|
||||
<div className="flex items-center justify-center min-h-[60vh]">
|
||||
<div className="text-center">
|
||||
<div className="text-4xl mb-3">🗺️💀</div>
|
||||
<p className="text-sm font-mono text-slate-500">Campaign not found</p>
|
||||
<Button variant="outline" className="mt-4 font-mono text-xs" onClick={() => router.push("/admin")}>
|
||||
← Back
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="py-4 max-w-2xl mx-auto space-y-4">
|
||||
<div className="flex items-center gap-3">
|
||||
<Button variant="ghost" size="sm" onClick={() => router.push("/admin")} className="font-mono text-xs">
|
||||
← BACK
|
||||
</Button>
|
||||
<div>
|
||||
<h1 className="text-xl font-mono text-cyan-300 uppercase tracking-wider">{campaign.name}</h1>
|
||||
<p className="text-xs text-slate-500 font-mono">{campaign.gridSize}×{campaign.gridSize} grid</p>
|
||||
</div>
|
||||
</div>
|
||||
<ItemEditor campaign={campaign} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
"use client";
|
||||
|
||||
import { useAuth } from "@/components/AuthProvider";
|
||||
import { AdminDashboard } from "@/components/AdminDashboard";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useEffect } from "react";
|
||||
|
||||
export default function AdminPage() {
|
||||
const { user, loading } = useAuth();
|
||||
const router = useRouter();
|
||||
|
||||
useEffect(() => {
|
||||
if (loading) return;
|
||||
if (!user) { router.push("/"); return; }
|
||||
if (!user.isAdmin) { router.push("/"); return; }
|
||||
}, [user, loading, router]);
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<div className="flex items-center justify-center min-h-[60vh]">
|
||||
<div className="text-center font-mono text-sm text-slate-600 animate-pulse">
|
||||
<div className="text-3xl mb-2">🔐</div>
|
||||
Verifying command clearance...
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (!user || !user.isAdmin) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return <AdminDashboard />;
|
||||
}
|
||||
Reference in New Issue
Block a user