feat(events): add event list lage
This commit is contained in:
parent
51fe42374d
commit
abc4c063c3
2 changed files with 133 additions and 0 deletions
61
src/app/events/page.tsx
Normal file
61
src/app/events/page.tsx
Normal file
|
@ -0,0 +1,61 @@
|
|||
'use client';
|
||||
|
||||
import { RedirectButton } from '@/components/buttons/redirect-button';
|
||||
import EventListEntry from '@/components/custom-ui/event-list-entry';
|
||||
import { ThemePicker } from '@/components/misc/theme-picker';
|
||||
import { Label } from '@/components/ui/label';
|
||||
import { useGetApiEvent } from '@/generated/api/event/event';
|
||||
|
||||
export default function Events() {
|
||||
const { data: eventsData, isLoading, error } = useGetApiEvent();
|
||||
|
||||
if (isLoading) return <div className='text-center mt-10'>Loading...</div>;
|
||||
if (error)
|
||||
return (
|
||||
<div className='text-center mt-10 text-red-500'>Error loading events</div>
|
||||
);
|
||||
|
||||
const events = eventsData?.data?.events || [];
|
||||
|
||||
return (
|
||||
<div className='relative h-screen flex flex-col items-center'>
|
||||
<div className='absolute top-4 right-4'>
|
||||
<ThemePicker />
|
||||
</div>
|
||||
|
||||
{/* Heading */}
|
||||
<h1 className='text-3xl font-bold mt-8 mb-4 text-center z-10'>
|
||||
My Events
|
||||
</h1>
|
||||
|
||||
{/* Scrollable event list */}
|
||||
<div className='w-full flex justify-center overflow-hidden'>
|
||||
<div className='grid gap-8 w-[90%] sm:w-[80%] lg:w-[60%] xl:w-[50%] p-6 overflow-y-auto'>
|
||||
{events.length > 0 ? (
|
||||
events.map((event) => (
|
||||
<EventListEntry
|
||||
key={event.id}
|
||||
title={event.title}
|
||||
id={event.id}
|
||||
start_time={event.start_time}
|
||||
end_time={event.end_time}
|
||||
location={event.location}
|
||||
/>
|
||||
))
|
||||
) : (
|
||||
<div className='flex flex-1 flex-col items-center justify-center min-h-[300px]'>
|
||||
<Label size='large' className='justify-center text-center'>
|
||||
You don't have any events right now
|
||||
</Label>
|
||||
<RedirectButton
|
||||
redirectUrl='/events/new'
|
||||
buttonText='create Event'
|
||||
className='mt-4'
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
72
src/components/custom-ui/event-list-entry.tsx
Normal file
72
src/components/custom-ui/event-list-entry.tsx
Normal file
|
@ -0,0 +1,72 @@
|
|||
import { Card } from '@/components/ui/card';
|
||||
import Logo from '@/components/misc/logo';
|
||||
import { Label } from '@/components/ui/label';
|
||||
import Link from 'next/link';
|
||||
|
||||
type EventListEntryProps = {
|
||||
title: string;
|
||||
id: string;
|
||||
start_time: string;
|
||||
end_time: string;
|
||||
location: string | null | undefined;
|
||||
};
|
||||
|
||||
export default function EventListEntry({
|
||||
title,
|
||||
id,
|
||||
start_time,
|
||||
end_time,
|
||||
location,
|
||||
}: EventListEntryProps) {
|
||||
const formatDate = (isoString?: string) => {
|
||||
if (!isoString) return '-';
|
||||
return new Date(isoString).toLocaleDateString();
|
||||
};
|
||||
const formatTime = (isoString?: string) => {
|
||||
if (!isoString) return '-';
|
||||
return new Date(isoString).toLocaleTimeString([], {
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
});
|
||||
};
|
||||
return (
|
||||
<Link href={`/events/${id}`} className='block'>
|
||||
<Card className='w-full'>
|
||||
<div className='grid grid-cols-1 gap-2 mx-auto md:mx-4 md:grid-cols-[80px_1fr_250px]'>
|
||||
<div className='w-full items-center justify-center grid'>
|
||||
<Logo colorType='monochrome' logoType='submark' width={50} />
|
||||
</div>
|
||||
<div className='w-full items-center justify-center grid my-3 md:my-0'>
|
||||
<h2 className='text-center'>{title}</h2>
|
||||
</div>
|
||||
<div className='grid gap-4'>
|
||||
<div className='grid grid-cols-[80px_auto] gap-2'>
|
||||
<Label className='text-[var(--color-neutral-300)] justify-end'>
|
||||
start
|
||||
</Label>
|
||||
<Label>
|
||||
{formatDate(start_time)} {formatTime(start_time)}
|
||||
</Label>
|
||||
</div>
|
||||
<div className='grid grid-cols-[80px_auto] gap-2'>
|
||||
<Label className='text-[var(--color-neutral-300)] justify-end'>
|
||||
end
|
||||
</Label>
|
||||
<Label>
|
||||
{formatDate(end_time)} {formatTime(end_time)}
|
||||
</Label>
|
||||
</div>
|
||||
{location && (
|
||||
<div className='grid grid-cols-[80px_auto] gap-2'>
|
||||
<Label className='text-[var(--color-neutral-300)] justify-end'>
|
||||
location
|
||||
</Label>
|
||||
<Label>{location}</Label>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
</Link>
|
||||
);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue