feat(events): refactor event and participant list entries to use schema validation
This commit is contained in:
parent
d9129f3f93
commit
018f94e69d
5 changed files with 24 additions and 35 deletions
|
@ -1,7 +1,6 @@
|
||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { usePathname } from 'next/navigation';
|
|
||||||
import Logo from '@/components/misc/logo';
|
import Logo from '@/components/misc/logo';
|
||||||
import { ThemePicker } from '@/components/misc/theme-picker';
|
import { ThemePicker } from '@/components/misc/theme-picker';
|
||||||
import { Card, CardContent, CardHeader } from '@/components/ui/card';
|
import { Card, CardContent, CardHeader } from '@/components/ui/card';
|
||||||
|
@ -12,12 +11,10 @@ import { RedirectButton } from '@/components/buttons/redirect-button';
|
||||||
import { useSession } from 'next-auth/react';
|
import { useSession } from 'next-auth/react';
|
||||||
import ParticipantListEntry from '@/components/custom-ui/participant-list-entry';
|
import ParticipantListEntry from '@/components/custom-ui/participant-list-entry';
|
||||||
|
|
||||||
export default function ShowEvent() {
|
export default function ShowEvent({ params }: { params: { eventId: string } }) {
|
||||||
const session = useSession();
|
const session = useSession();
|
||||||
const pathname = usePathname();
|
|
||||||
|
|
||||||
// Extract eventId from URL like /events/[eventId]
|
const eventId = params.eventId;
|
||||||
const eventId = pathname.split('/').pop() || '';
|
|
||||||
|
|
||||||
// Fetch event data
|
// Fetch event data
|
||||||
const { data: eventData, isLoading, error } = useGetApiEventEventID(eventId);
|
const { data: eventData, isLoading, error } = useGetApiEventEventID(eventId);
|
||||||
|
@ -145,11 +142,7 @@ export default function ShowEvent() {
|
||||||
</Label>{' '}
|
</Label>{' '}
|
||||||
<div className='grid grid-cols-1 mt-3 sm:max-h-60 sm:grid-cols-2 sm:overflow-y-auto sm:mb-0'>
|
<div className='grid grid-cols-1 mt-3 sm:max-h-60 sm:grid-cols-2 sm:overflow-y-auto sm:mb-0'>
|
||||||
{event.participants?.map((user) => (
|
{event.participants?.map((user) => (
|
||||||
<ParticipantListEntry
|
<ParticipantListEntry key={user.user.id} {...user} />
|
||||||
key={user.user.id}
|
|
||||||
participant={user.user.name}
|
|
||||||
imageSrc={user.user.image}
|
|
||||||
></ParticipantListEntry>
|
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -35,11 +35,9 @@ export default function Events() {
|
||||||
events.map((event) => (
|
events.map((event) => (
|
||||||
<EventListEntry
|
<EventListEntry
|
||||||
key={event.id}
|
key={event.id}
|
||||||
title={event.title}
|
{...event}
|
||||||
id={event.id}
|
created_at={new Date(event.created_at)}
|
||||||
start_time={event.start_time}
|
updated_at={new Date(event.updated_at)}
|
||||||
end_time={event.end_time}
|
|
||||||
location={event.location}
|
|
||||||
/>
|
/>
|
||||||
))
|
))
|
||||||
) : (
|
) : (
|
||||||
|
|
|
@ -2,14 +2,10 @@ import { Card } from '@/components/ui/card';
|
||||||
import Logo from '@/components/misc/logo';
|
import Logo from '@/components/misc/logo';
|
||||||
import { Label } from '@/components/ui/label';
|
import { Label } from '@/components/ui/label';
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
|
import zod from 'zod/v4';
|
||||||
|
import { EventSchema } from '@/app/api/event/validation';
|
||||||
|
|
||||||
type EventListEntryProps = {
|
type EventListEntryProps = zod.output<typeof EventSchema>;
|
||||||
title: string;
|
|
||||||
id: string;
|
|
||||||
start_time: string;
|
|
||||||
end_time: string;
|
|
||||||
location: string | null | undefined;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default function EventListEntry({
|
export default function EventListEntry({
|
||||||
title,
|
title,
|
||||||
|
|
|
@ -3,26 +3,24 @@ import Image from 'next/image';
|
||||||
import { user_default_dark } from '@/assets/usericon/default/defaultusericon-export';
|
import { user_default_dark } from '@/assets/usericon/default/defaultusericon-export';
|
||||||
import { user_default_light } from '@/assets/usericon/default/defaultusericon-export';
|
import { user_default_light } from '@/assets/usericon/default/defaultusericon-export';
|
||||||
import { useTheme } from 'next-themes';
|
import { useTheme } from 'next-themes';
|
||||||
|
import zod from 'zod/v4';
|
||||||
|
import { ParticipantSchema } from '@/app/api/event/[eventID]/participant/validation';
|
||||||
|
|
||||||
type ParticipantListEntryProps = {
|
type ParticipantListEntryProps = zod.output<typeof ParticipantSchema>;
|
||||||
participant: string;
|
|
||||||
imageSrc?: string | null;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default function ParticipantListEntry({
|
export default function ParticipantListEntry({
|
||||||
participant,
|
user,
|
||||||
imageSrc,
|
|
||||||
}: ParticipantListEntryProps) {
|
}: ParticipantListEntryProps) {
|
||||||
const { resolvedTheme } = useTheme();
|
const { resolvedTheme } = useTheme();
|
||||||
const defaultImage =
|
const defaultImage =
|
||||||
resolvedTheme === 'dark' ? user_default_dark : user_default_light;
|
resolvedTheme === 'dark' ? user_default_dark : user_default_light;
|
||||||
|
|
||||||
const finalImageSrc = imageSrc ?? defaultImage;
|
const finalImageSrc = user.image ?? defaultImage;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='flex items-center gap-2 py-1 ml-5'>
|
<div className='flex items-center gap-2 py-1 ml-5'>
|
||||||
<Image src={finalImageSrc} alt='Avatar' width={30} height={30} />
|
<Image src={finalImageSrc} alt='Avatar' width={30} height={30} />
|
||||||
<span>{participant}</span>
|
<span>{user.name}</span>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,10 +19,10 @@ import ParticipantListEntry from '../custom-ui/participant-list-entry';
|
||||||
|
|
||||||
import { useSearchParams } from 'next/navigation';
|
import { useSearchParams } from 'next/navigation';
|
||||||
|
|
||||||
interface User {
|
import zod from 'zod/v4';
|
||||||
id: string;
|
import { PublicUserSchema } from '@/app/api/user/validation';
|
||||||
name: string;
|
|
||||||
}
|
type User = zod.output<typeof PublicUserSchema>;
|
||||||
|
|
||||||
interface EventFormProps {
|
interface EventFormProps {
|
||||||
type: 'create' | 'edit';
|
type: 'create' | 'edit';
|
||||||
|
@ -305,7 +305,11 @@ const EventForm: React.FC<EventFormProps> = (props) => {
|
||||||
/>
|
/>
|
||||||
<div className='grid grid-cols-1 mt-3 sm:max-h-60 sm:grid-cols-2 sm:overflow-y-auto sm:mb-0'>
|
<div className='grid grid-cols-1 mt-3 sm:max-h-60 sm:grid-cols-2 sm:overflow-y-auto sm:mb-0'>
|
||||||
{selectedParticipants.map((user) => (
|
{selectedParticipants.map((user) => (
|
||||||
<ParticipantListEntry key={user.id} participant={user.name} />
|
<ParticipantListEntry
|
||||||
|
key={user.id}
|
||||||
|
user={user}
|
||||||
|
status='PENDING'
|
||||||
|
/>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue