vbytes-lan-registration/src/Web/lan-frontend/app/admin/dashboard/page.tsx

201 lines
6.9 KiB
TypeScript

"use client";
import Link from "next/link";
import { useRouter } from "next/navigation";
import { useEffect, useState } from "react";
interface EventContent {
title: string;
subTitle: string;
eventDate: string;
eventTime: string;
locationName: string;
locationAddress: string;
whatToBring: string;
rulesAndGdpr: string;
}
export default function AdminDashboard() {
const [content, setContent] = useState<EventContent | null>(null);
const [loading, setLoading] = useState(true);
const [saving, setSaving] = useState(false);
const [message, setMessage] = useState({ type: "", text: "" });
const router = useRouter();
useEffect(() => {
const token = localStorage.getItem("adminToken");
if (!token) {
router.push("/admin/login");
return;
}
fetch("/api/Content")
.then((res) => res.json())
.then((data) => {
setContent(data);
setLoading(false);
})
.catch((err) => {
console.error("Failed to fetch content", err);
setLoading(false);
});
}, [router]);
const handleLogout = () => {
localStorage.removeItem("adminToken");
router.push("/admin/login");
};
const handleSave = async (e: React.FormEvent) => {
e.preventDefault();
if (!content) return;
setSaving(true);
setMessage({ type: "", text: "" });
try {
const response = await fetch("/api/Content", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(content),
});
if (response.ok) {
setMessage({ type: "success", text: "Content saved successfully!" });
} else {
setMessage({ type: "error", text: "Failed to save content." });
}
} catch (err) {
setMessage({ type: "error", text: "An error occurred while saving." });
} finally {
setSaving(false);
}
};
const handleChange = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
const { name, value } = e.target;
setContent((prev) => prev ? { ...prev, [name]: value } : null);
};
if (loading) return <div className="p-8">Loading...</div>;
if (!content) return <div className="p-8 text-red-500">Error loading content.</div>;
return (
<div className="min-h-screen bg-gray-50 p-8 font-sans">
<div className="max-w-4xl mx-auto">
<div className="flex justify-between items-center mb-8">
<h1 className="text-3xl font-bold text-gray-900">Admin Dashboard</h1>
<div className="space-x-4">
<Link href="/" className="text-blue-600 hover:underline">View Site</Link>
<button
onClick={handleLogout}
className="bg-gray-200 px-4 py-2 rounded-md hover:bg-gray-300"
>
Logout
</button>
</div>
</div>
<form onSubmit={handleSave} className="bg-white p-8 rounded-lg shadow-md space-y-6">
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
<div className="col-span-2">
<label className="block text-sm font-medium text-gray-700">Page Title</label>
<input
type="text"
name="title"
className="mt-1 block w-full rounded-md border border-gray-300 p-2 text-gray-900"
value={content.title}
onChange={handleChange}
/>
</div>
<div className="col-span-2">
<label className="block text-sm font-medium text-gray-700">Sub-title</label>
<input
type="text"
name="subTitle"
className="mt-1 block w-full rounded-md border border-gray-300 p-2 text-gray-900"
value={content.subTitle}
onChange={handleChange}
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-700">Event Date</label>
<input
type="text"
name="eventDate"
className="mt-1 block w-full rounded-md border border-gray-300 p-2 text-gray-900"
value={content.eventDate}
onChange={handleChange}
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-700">Event Time</label>
<input
type="text"
name="eventTime"
className="mt-1 block w-full rounded-md border border-gray-300 p-2 text-gray-900"
value={content.eventTime}
onChange={handleChange}
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-700">Location Name</label>
<input
type="text"
name="locationName"
className="mt-1 block w-full rounded-md border border-gray-300 p-2 text-gray-900"
value={content.locationName}
onChange={handleChange}
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-700">Location Address</label>
<input
type="text"
name="locationAddress"
className="mt-1 block w-full rounded-md border border-gray-300 p-2 text-gray-900"
value={content.locationAddress}
onChange={handleChange}
/>
</div>
<div className="col-span-2">
<label className="block text-sm font-medium text-gray-700">What to Bring (One item per line)</label>
<textarea
name="whatToBring"
rows={6}
className="mt-1 block w-full rounded-md border border-gray-300 p-2 font-mono text-sm text-gray-900"
value={content.whatToBring}
onChange={handleChange}
/>
</div>
<div className="col-span-2">
<label className="block text-sm font-medium text-gray-700">Rules & GDPR</label>
<textarea
name="rulesAndGdpr"
rows={4}
className="mt-1 block w-full rounded-md border border-gray-300 p-2 text-gray-900"
value={content.rulesAndGdpr}
onChange={handleChange}
/>
</div>
</div>
{message.text && (
<div className={`p-4 rounded-md ${message.type === "success" ? "bg-green-50 text-green-800" : "bg-red-50 text-red-800"}`}>
{message.text}
</div>
)}
<div className="pt-4">
<button
type="submit"
disabled={saving}
className="w-full bg-blue-600 text-white py-3 rounded-md hover:bg-blue-700 disabled:bg-gray-400 font-bold"
>
{saving ? "Saving Changes..." : "Save Content Changes"}
</button>
</div>
</form>
</div>
</div>
);
}