254 lines
9.0 KiB
TypeScript
254 lines
9.0 KiB
TypeScript
"use client";
|
|
|
|
import { useEffect, useState } from "react";
|
|
import { useSession } from "next-auth/react";
|
|
import { useRouter } from "next/navigation";
|
|
import Navigation from "@/components/Navigation";
|
|
import ImageSelector from "@/components/ImageSelector";
|
|
|
|
interface SitePreferences {
|
|
id: string;
|
|
homeBackground: string | null;
|
|
eventsBackground: string | null;
|
|
leaderboardBackground: string | null;
|
|
}
|
|
|
|
type AdminSection = "preferences" | "users";
|
|
|
|
export default function AdminPage() {
|
|
const { data: session, status } = useSession();
|
|
const router = useRouter();
|
|
const [activeSection, setActiveSection] =
|
|
useState<AdminSection>("preferences");
|
|
const [preferences, setPreferences] = useState<SitePreferences | null>(null);
|
|
const [loading, setLoading] = useState(true);
|
|
const [isEditing, setIsEditing] = useState(false);
|
|
const [formData, setFormData] = useState({
|
|
homeBackground: "",
|
|
eventsBackground: "",
|
|
leaderboardBackground: "",
|
|
});
|
|
|
|
useEffect(() => {
|
|
if (status === "unauthenticated") {
|
|
router.push("/login");
|
|
return;
|
|
}
|
|
|
|
if (status === "authenticated" && session?.user?.role !== "ADMIN") {
|
|
router.push("/");
|
|
return;
|
|
}
|
|
|
|
if (status === "authenticated" && session?.user?.role === "ADMIN") {
|
|
fetchPreferences();
|
|
}
|
|
}, [status, session, router]);
|
|
|
|
const fetchPreferences = async () => {
|
|
try {
|
|
const response = await fetch("/api/admin/preferences");
|
|
if (response.ok) {
|
|
const data = await response.json();
|
|
setPreferences(data);
|
|
setFormData({
|
|
homeBackground: data.homeBackground || "",
|
|
eventsBackground: data.eventsBackground || "",
|
|
leaderboardBackground: data.leaderboardBackground || "",
|
|
});
|
|
}
|
|
} catch (error) {
|
|
console.error("Error fetching preferences:", error);
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
const handleEdit = () => {
|
|
setIsEditing(true);
|
|
};
|
|
|
|
const handleSave = async () => {
|
|
try {
|
|
const response = await fetch("/api/admin/preferences", {
|
|
method: "PUT",
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
},
|
|
body: JSON.stringify(formData),
|
|
});
|
|
|
|
if (response.ok) {
|
|
await fetchPreferences();
|
|
setIsEditing(false);
|
|
}
|
|
} catch (error) {
|
|
console.error("Error updating preferences:", error);
|
|
}
|
|
};
|
|
|
|
const handleCancel = () => {
|
|
setIsEditing(false);
|
|
if (preferences) {
|
|
setFormData({
|
|
homeBackground: preferences.homeBackground || "",
|
|
eventsBackground: preferences.eventsBackground || "",
|
|
leaderboardBackground: preferences.leaderboardBackground || "",
|
|
});
|
|
}
|
|
};
|
|
|
|
if (status === "loading" || loading) {
|
|
return (
|
|
<main className="min-h-screen bg-black relative">
|
|
<Navigation />
|
|
<div className="flex items-center justify-center min-h-screen text-pixel-gold">
|
|
Chargement...
|
|
</div>
|
|
</main>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<main className="min-h-screen bg-black relative">
|
|
<Navigation />
|
|
<section className="relative w-full min-h-screen flex flex-col items-center overflow-hidden pt-24 pb-16">
|
|
<div className="relative z-10 w-full max-w-6xl mx-auto px-8 py-16">
|
|
<h1 className="text-4xl font-gaming font-black mb-8 text-center">
|
|
<span className="bg-gradient-to-r from-pixel-gold via-orange-400 to-pixel-gold bg-clip-text text-transparent">
|
|
ADMIN
|
|
</span>
|
|
</h1>
|
|
|
|
{/* Navigation Tabs */}
|
|
<div className="flex gap-4 mb-8 justify-center">
|
|
<button
|
|
onClick={() => setActiveSection("preferences")}
|
|
className={`px-6 py-3 border uppercase text-xs tracking-widest rounded transition ${
|
|
activeSection === "preferences"
|
|
? "border-pixel-gold bg-pixel-gold/10 text-pixel-gold"
|
|
: "border-pixel-gold/30 bg-black/60 text-gray-400 hover:border-pixel-gold/50"
|
|
}`}
|
|
>
|
|
Préférences UI
|
|
</button>
|
|
<button
|
|
onClick={() => setActiveSection("users")}
|
|
className={`px-6 py-3 border uppercase text-xs tracking-widest rounded transition ${
|
|
activeSection === "users"
|
|
? "border-pixel-gold bg-pixel-gold/10 text-pixel-gold"
|
|
: "border-pixel-gold/30 bg-black/60 text-gray-400 hover:border-pixel-gold/50"
|
|
}`}
|
|
>
|
|
Utilisateurs
|
|
</button>
|
|
</div>
|
|
|
|
{activeSection === "preferences" && (
|
|
<div className="bg-black/80 border border-pixel-gold/30 rounded-lg p-6 backdrop-blur-sm">
|
|
<h2 className="text-2xl font-gaming font-bold mb-6 text-pixel-gold">
|
|
Préférences UI Globales
|
|
</h2>
|
|
<div className="space-y-4">
|
|
<div className="bg-black/60 border border-pixel-gold/20 rounded p-4">
|
|
<div className="flex justify-between items-start mb-4">
|
|
<div>
|
|
<h3 className="text-pixel-gold font-bold text-lg">
|
|
Images de fond du site
|
|
</h3>
|
|
<p className="text-gray-400 text-sm">
|
|
Ces préférences s'appliquent à tous les utilisateurs
|
|
</p>
|
|
</div>
|
|
{!isEditing && (
|
|
<button
|
|
onClick={handleEdit}
|
|
className="px-4 py-2 border border-pixel-gold/50 bg-black/60 text-white uppercase text-xs tracking-widest rounded hover:bg-pixel-gold/10 transition"
|
|
>
|
|
Modifier
|
|
</button>
|
|
)}
|
|
</div>
|
|
|
|
{isEditing ? (
|
|
<div className="space-y-6">
|
|
<ImageSelector
|
|
value={formData.homeBackground}
|
|
onChange={(url) =>
|
|
setFormData({
|
|
...formData,
|
|
homeBackground: url,
|
|
})
|
|
}
|
|
label="Background Home"
|
|
/>
|
|
<ImageSelector
|
|
value={formData.eventsBackground}
|
|
onChange={(url) =>
|
|
setFormData({
|
|
...formData,
|
|
eventsBackground: url,
|
|
})
|
|
}
|
|
label="Background Events"
|
|
/>
|
|
<ImageSelector
|
|
value={formData.leaderboardBackground}
|
|
onChange={(url) =>
|
|
setFormData({
|
|
...formData,
|
|
leaderboardBackground: url,
|
|
})
|
|
}
|
|
label="Background Leaderboard"
|
|
/>
|
|
<div className="flex gap-2 pt-4">
|
|
<button
|
|
onClick={handleSave}
|
|
className="px-4 py-2 border border-green-500/50 bg-green-900/20 text-green-400 uppercase text-xs tracking-widest rounded hover:bg-green-900/30 transition"
|
|
>
|
|
Enregistrer
|
|
</button>
|
|
<button
|
|
onClick={handleCancel}
|
|
className="px-4 py-2 border border-gray-600/50 bg-gray-900/20 text-gray-400 uppercase text-xs tracking-widest rounded hover:bg-gray-900/30 transition"
|
|
>
|
|
Annuler
|
|
</button>
|
|
</div>
|
|
</div>
|
|
) : (
|
|
<div className="space-y-2 text-sm text-gray-400">
|
|
<div>
|
|
Home: {preferences?.homeBackground || "Par défaut"}
|
|
</div>
|
|
<div>
|
|
Events: {preferences?.eventsBackground || "Par défaut"}
|
|
</div>
|
|
<div>
|
|
Leaderboard:{" "}
|
|
{preferences?.leaderboardBackground || "Par défaut"}
|
|
</div>
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)}
|
|
|
|
{activeSection === "users" && (
|
|
<div className="bg-black/80 border border-pixel-gold/30 rounded-lg p-6 backdrop-blur-sm">
|
|
<h2 className="text-2xl font-gaming font-bold mb-6 text-pixel-gold">
|
|
Gestion des Utilisateurs
|
|
</h2>
|
|
<div className="text-center text-gray-400 py-8">
|
|
Section utilisateurs à venir...
|
|
</div>
|
|
</div>
|
|
)}
|
|
</div>
|
|
</section>
|
|
</main>
|
|
);
|
|
}
|