Add Event Themes management page to dashboard
Introduced a new "Event Themes" page to allow users to manage visual themes for events. Updated the dashboard to include a button for navigating to the new page. The themes page supports listing, viewing, and creating themes, enhancing customization options for users.
This commit is contained in:
108
frontend/src/app/(main)/dashboard/event-themes/page.tsx
Normal file
108
frontend/src/app/(main)/dashboard/event-themes/page.tsx
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { useQuery } from "@tanstack/react-query";
|
||||||
|
import { listEventThemes } from "@/client/sdk.gen";
|
||||||
|
import {
|
||||||
|
Card,
|
||||||
|
CardContent,
|
||||||
|
CardFooter,
|
||||||
|
CardHeader,
|
||||||
|
CardTitle,
|
||||||
|
CardDescription,
|
||||||
|
} from "@/components/ui/card";
|
||||||
|
import { Badge } from "@/components/ui/badge";
|
||||||
|
import { Button } from "@/components/ui/button";
|
||||||
|
import Image from "next/image";
|
||||||
|
import Link from "next/link";
|
||||||
|
import { Loader2Icon, PaletteIcon } from "lucide-react";
|
||||||
|
import { useEventThemes } from "@/context/event-theme-context";
|
||||||
|
|
||||||
|
export default function EventThemesPage() {
|
||||||
|
// const { data: themes, isLoading } = useQuery({
|
||||||
|
// queryKey: ["event-themes"],
|
||||||
|
// queryFn: () => listEventThemes().then(res => res.data),
|
||||||
|
// });
|
||||||
|
|
||||||
|
const { themes, isLoadingThemes } = useEventThemes();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="max-w-7xl mx-auto py-6 px-4">
|
||||||
|
<div className="flex items-center justify-between mb-8">
|
||||||
|
<div>
|
||||||
|
<h1 className="text-3xl font-bold">Event Themes</h1>
|
||||||
|
<p className="mt-2 text-gray-500 dark:text-gray-400">
|
||||||
|
Manage visual themes for your celebrations.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<Button asChild>
|
||||||
|
<Link href="/dashboard/event-themes/new">+ New Theme</Link>
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{isLoadingThemes && (
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<Loader2Icon className="animate-spin h-6 w-6 text-blue-500" />
|
||||||
|
<span>Loading themes...</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{!isLoadingThemes && themes && themes.length === 0 && (
|
||||||
|
<div className="bg-gray-100 dark:bg-slate-700 rounded p-8 text-center">
|
||||||
|
<p className="text-gray-500 dark:text-gray-400">
|
||||||
|
You haven't created any theme yet.
|
||||||
|
</p>
|
||||||
|
<Button asChild className="mt-4">
|
||||||
|
<Link href="/dashboard/events/new">Create Your First Theme</Link>
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{!isLoadingThemes && themes && themes.length > 0 && (
|
||||||
|
<div className="grid gap-6 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4">
|
||||||
|
{themes.map((theme) => (
|
||||||
|
<Card
|
||||||
|
key={theme.id}
|
||||||
|
className="hover:shadow-lg transition-shadow flex flex-col overflow-hidden"
|
||||||
|
>
|
||||||
|
<CardHeader className="p-0 relative h-48 bg-gray-50 dark:bg-gray-800">
|
||||||
|
{theme.preview_image_url ? (
|
||||||
|
<Image
|
||||||
|
src={theme.preview_image_url}
|
||||||
|
alt={`${theme.name} Preview`}
|
||||||
|
style={{ objectFit: "cover" }}
|
||||||
|
fill
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<div className="flex items-center justify-center h-full text-gray-400">
|
||||||
|
<PaletteIcon className="h-12 w-12" />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</CardHeader>
|
||||||
|
<CardContent className="flex-grow p-4">
|
||||||
|
<CardTitle className="text-lg truncate">{theme.name}</CardTitle>
|
||||||
|
<CardDescription className="line-clamp-2">
|
||||||
|
{theme.description || "No description provided."}
|
||||||
|
</CardDescription>
|
||||||
|
</CardContent>
|
||||||
|
<CardFooter className="flex flex-col gap-2 p-4 border-t border-gray-200 dark:border-gray-700">
|
||||||
|
<div className="flex gap-2">
|
||||||
|
{theme.background_image_url && (
|
||||||
|
<Badge>Background Image</Badge>
|
||||||
|
)}
|
||||||
|
{theme.foreground_image_url && (
|
||||||
|
<Badge>Foreground Image</Badge>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<Button variant="outline" size="sm" asChild className="w-full">
|
||||||
|
<Link href={`/dashboard/event-themes/${theme.id}`}>
|
||||||
|
Edit Theme
|
||||||
|
</Link>
|
||||||
|
</Button>
|
||||||
|
</CardFooter>
|
||||||
|
</Card>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -35,9 +35,14 @@ export default function DashboardPage() {
|
|||||||
Manage your scheduled events.
|
Manage your scheduled events.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<Button asChild>
|
<div className="flex gap-2">
|
||||||
<Link href="/dashboard/events/new">+ Add New Event</Link>
|
<Button variant="outline" asChild>
|
||||||
</Button>
|
<Link href="/dashboard/event-themes">Manage Themes</Link>
|
||||||
|
</Button>
|
||||||
|
<Button asChild>
|
||||||
|
<Link href="/dashboard/events/new">+ Add New Event</Link>
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{isLoadingUserEvents && (
|
{isLoadingUserEvents && (
|
||||||
|
|||||||
Reference in New Issue
Block a user