91 lines
3.4 KiB
TypeScript
91 lines
3.4 KiB
TypeScript
import { Stat } from '@/app/stat'
|
|
import { Badge } from '@/components/badge'
|
|
import { Button } from '@/components/button'
|
|
import { Heading, Subheading } from '@/components/heading'
|
|
import { Link } from '@/components/link'
|
|
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/table'
|
|
import { getEvent, getEventOrders } from '@/data'
|
|
import { ChevronLeftIcon } from '@heroicons/react/16/solid'
|
|
import type { Metadata } from 'next'
|
|
import { notFound } from 'next/navigation'
|
|
|
|
export async function generateMetadata({ params }: { params: Promise<{ id: string }> }): Promise<Metadata> {
|
|
let { id } = await params
|
|
let event = await getEvent(id)
|
|
|
|
return {
|
|
title: event?.name,
|
|
}
|
|
}
|
|
|
|
export default async function Event({ params }: { params: Promise<{ id: string }> }) {
|
|
let { id } = await params
|
|
let event = await getEvent(id)
|
|
let orders = await getEventOrders(id)
|
|
|
|
if (!event) {
|
|
notFound()
|
|
}
|
|
|
|
return (
|
|
<>
|
|
<div className="max-lg:hidden">
|
|
<Link href="/events" className="inline-flex items-center gap-2 text-sm/6 text-zinc-500 dark:text-zinc-400">
|
|
<ChevronLeftIcon className="size-4 fill-zinc-400 dark:fill-zinc-500" />
|
|
Events
|
|
</Link>
|
|
</div>
|
|
<div className="mt-4 flex flex-wrap items-end justify-between gap-4">
|
|
<div className="flex flex-wrap items-center gap-6">
|
|
<div className="w-32 shrink-0">
|
|
<img className="aspect-3/2 rounded-lg shadow-sm" src={event.imgUrl} alt="" />
|
|
</div>
|
|
<div>
|
|
<div className="flex flex-wrap items-center gap-x-4 gap-y-2">
|
|
<Heading>{event.name}</Heading>
|
|
<Badge color={event.status === 'On Sale' ? 'lime' : 'zinc'}>{event.status}</Badge>
|
|
</div>
|
|
<div className="mt-2 text-sm/6 text-zinc-500">
|
|
{event.date} at {event.time} <span aria-hidden="true">·</span> {event.location}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div className="flex gap-4">
|
|
<Button outline>Edit</Button>
|
|
<Button>View</Button>
|
|
</div>
|
|
</div>
|
|
<div className="mt-8 grid gap-8 sm:grid-cols-3">
|
|
<Stat title="Total revenue" value={event.totalRevenue} change={event.totalRevenueChange} />
|
|
<Stat
|
|
title="Tickets sold"
|
|
value={`${event.ticketsSold}/${event.ticketsAvailable}`}
|
|
change={event.ticketsSoldChange}
|
|
/>
|
|
<Stat title="Pageviews" value={event.pageViews} change={event.pageViewsChange} />
|
|
</div>
|
|
<Subheading className="mt-12">Recent orders</Subheading>
|
|
<Table className="mt-4 [--gutter:--spacing(6)] lg:[--gutter:--spacing(10)]">
|
|
<TableHead>
|
|
<TableRow>
|
|
<TableHeader>Order number</TableHeader>
|
|
<TableHeader>Purchase date</TableHeader>
|
|
<TableHeader>Customer</TableHeader>
|
|
<TableHeader className="text-right">Amount</TableHeader>
|
|
</TableRow>
|
|
</TableHead>
|
|
<TableBody>
|
|
{orders.map((order) => (
|
|
<TableRow key={order.id} href={order.url} title={`Order #${order.id}`}>
|
|
<TableCell>{order.id}</TableCell>
|
|
<TableCell className="text-zinc-500">{order.date}</TableCell>
|
|
<TableCell>{order.customer.name}</TableCell>
|
|
<TableCell className="text-right">US{order.amount.usd}</TableCell>
|
|
</TableRow>
|
|
))}
|
|
</TableBody>
|
|
</Table>
|
|
</>
|
|
)
|
|
}
|