fix: empty event form edit fields #125

Merged
dominik merged 3 commits from fix/empty_event_form_fields into main 2025-07-01 07:20:10 +00:00
6 changed files with 58 additions and 42 deletions

View file

@ -6,7 +6,7 @@ const nextConfig: NextConfig = {
remotePatterns: [ remotePatterns: [
{ {
protocol: 'https', protocol: 'https',
hostname: 'img1.wikia.nocookie.net', hostname: 'i.gifer.com',
port: '', port: '',
pathname: '/**', pathname: '/**',
}, },

View file

@ -51,9 +51,6 @@ export default function ShowEvent() {
); );
} }
const event = eventData.data.event;
const organiserName = userData?.data.user?.name || 'Unknown User';
// Format dates & times for display // Format dates & times for display
const formatDate = (isoString?: string) => { const formatDate = (isoString?: string) => {
if (!isoString) return '-'; if (!isoString) return '-';
@ -81,7 +78,7 @@ export default function ShowEvent() {
</div> </div>
<div className='items-center ml-auto mr-auto max-sm:mb-6 max-sm:w-full max-sm:flex max-sm:justify-center'> <div className='items-center ml-auto mr-auto max-sm:mb-6 max-sm:w-full max-sm:flex max-sm:justify-center'>
<h1 className='text-center'> <h1 className='text-center'>
{event.title || 'Untitled Event'} {eventData.data.event.title || 'Untitled Event'}
</h1> </h1>
</div> </div>
<div className='w-0 sm:w-[100px]'></div> <div className='w-0 sm:w-[100px]'></div>
@ -92,8 +89,8 @@ export default function ShowEvent() {
start Time start Time
</Label> </Label>
<Label size='large'> <Label size='large'>
{event.start_time {eventData.data.event.start_time
? `${formatDate(event.start_time)} ${formatTime(event.start_time)}` ? `${formatDate(eventData.data.event.start_time)} ${formatTime(eventData.data.event.start_time)}`
: '-'} : '-'}
</Label> </Label>
</div> </div>
@ -102,8 +99,8 @@ export default function ShowEvent() {
end Time end Time
</Label> </Label>
<Label size='large'> <Label size='large'>
{event.end_time {eventData.data.event.end_time
? `${formatDate(event.end_time)} ${formatTime(event.end_time)}` ? `${formatDate(eventData.data.event.end_time)} ${formatTime(eventData.data.event.end_time)}`
: '-'} : '-'}
</Label> </Label>
</div> </div>
@ -111,7 +108,9 @@ export default function ShowEvent() {
<Label className='text-[var(--color-neutral-300)] mb-2'> <Label className='text-[var(--color-neutral-300)] mb-2'>
Location Location
</Label> </Label>
<Label size='large'>{event.location || '-'}</Label> <Label size='large'>
{eventData.data.event.location || '-'}
</Label>
</div> </div>
<div className='flex flex-col gap-4'> <div className='flex flex-col gap-4'>
<div className='flex flex-row gap-2'> <div className='flex flex-row gap-2'>
@ -119,7 +118,9 @@ export default function ShowEvent() {
created: created:
</Label> </Label>
<Label> <Label>
{event.created_at ? formatDate(event.created_at) : '-'} {eventData.data.event.created_at
? formatDate(eventData.data.event.created_at)
: '-'}
</Label> </Label>
</div> </div>
<div className='flex flex-row gap-2'> <div className='flex flex-row gap-2'>
@ -127,7 +128,9 @@ export default function ShowEvent() {
updated: updated:
</Label> </Label>
<Label> <Label>
{event.updated_at ? formatDate(event.updated_at) : '-'} {eventData.data.event.updated_at
? formatDate(eventData.data.event.updated_at)
: '-'}
</Label> </Label>
</div> </div>
</div> </div>
@ -139,14 +142,18 @@ export default function ShowEvent() {
<Label className='text-[var(--color-neutral-300)]'> <Label className='text-[var(--color-neutral-300)]'>
Organiser: Organiser:
</Label> </Label>
<Label size='large'>{organiserName}</Label> <Label size='large'>
{userData?.data.user?.name || 'Unknown User'}
</Label>
</div> </div>
</div> </div>
<div className='h-full w-full'> <div className='h-full w-full'>
<Label className='text-[var(--color-neutral-300)] mb-2'> <Label className='text-[var(--color-neutral-300)] mb-2'>
Description Description
</Label> </Label>
<Label size='large'>{event.description || '-'}</Label> <Label size='large'>
{eventData.data.event.description || '-'}
</Label>
</div> </div>
</div> </div>
<div className='h-full w-full mt-2'> <div className='h-full w-full mt-2'>
@ -154,11 +161,11 @@ export default function ShowEvent() {
Participants Participants
</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) => ( {eventData.data.event.participants?.map((user) => (
<ParticipantListEntry <ParticipantListEntry
key={user.user.id} key={user.user.id}
{...user} {...user}
eventID={event.id} eventID={eventData.data.event.id}
/> />
))} ))}
</div> </div>
@ -167,7 +174,8 @@ export default function ShowEvent() {
<div className='flex flex-row gap-2 justify-end mt-4 mb-6'> <div className='flex flex-row gap-2 justify-end mt-4 mb-6'>
<div className='w-[20%] grid max-sm:w-full'> <div className='w-[20%] grid max-sm:w-full'>
{session.data?.user?.id === event.organizer.id ? ( {session.data?.user?.id ===
eventData.data.event.organizer.id ? (
<Dialog <Dialog
open={deleteDialogOpen} open={deleteDialogOpen}
onOpenChange={setDeleteDialogOpen} onOpenChange={setDeleteDialogOpen}
@ -182,7 +190,8 @@ export default function ShowEvent() {
<DialogTitle>Delete Event</DialogTitle> <DialogTitle>Delete Event</DialogTitle>
<DialogDescription> <DialogDescription>
Are you sure you want to delete the event &ldquo; Are you sure you want to delete the event &ldquo;
{event.title}&rdquo;? This action cannot be undone. {eventData.data.event.title}&rdquo;? This action
cannot be undone.
</DialogDescription> </DialogDescription>
</DialogHeader> </DialogHeader>
<DialogFooter> <DialogFooter>
@ -196,7 +205,7 @@ export default function ShowEvent() {
variant='muted' variant='muted'
onClick={() => { onClick={() => {
deleteEvent.mutate( deleteEvent.mutate(
{ eventID: event.id }, { eventID: eventData.data.event.id },
{ {
onSuccess: () => { onSuccess: () => {
router.push('/home'); router.push('/home');
@ -204,7 +213,7 @@ export default function ShowEvent() {
<ToastInner <ToastInner
toastId={t} toastId={t}
title='Event deleted' title='Event deleted'
description={event?.title} description={eventData.data.event.title}
variant='success' variant='success'
/> />
)); ));
@ -222,7 +231,8 @@ export default function ShowEvent() {
) : null} ) : null}
</div> </div>
<div className='w-[20%] grid max-sm:w-full'> <div className='w-[20%] grid max-sm:w-full'>
{session.data?.user?.id === event.organizer.id ? ( {session.data?.user?.id ===
eventData.data.event.organizer.id ? (
<RedirectButton <RedirectButton
redirectUrl={`/events/edit/${eventID}`} redirectUrl={`/events/edit/${eventID}`}
buttonText='edit' buttonText='edit'

View file

@ -61,10 +61,11 @@ export default async function LoginPage() {
</HoverCardTrigger> </HoverCardTrigger>
<HoverCardContent className='flex items-center justify-center'> <HoverCardContent className='flex items-center justify-center'>
<Image <Image
src='https://img1.wikia.nocookie.net/__cb20140808110649/clubpenguin/images/a/a1/Action_Dance_Light_Blue.gif' src='https://i.gifer.com/22CU.gif'
width='150' width='150'
height='150' height='150'
alt='dancing penguin' alt='cat gif'
unoptimized
></Image> ></Image>
</HoverCardContent> </HoverCardContent>
</HoverCard> </HoverCard>

View file

@ -36,6 +36,12 @@ export default function LabeledInput({
value || defaultValue || '', value || defaultValue || '',
); );
React.useEffect(() => {
if (value !== undefined) {
setInputValue(value);
}
}, [value]);
const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => { const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setInputValue(e.target.value); setInputValue(e.target.value);
if (rest.onChange) { if (rest.onChange) {

View file

@ -64,9 +64,6 @@ const EventForm: React.FC<EventFormProps> = (props) => {
const patchEvent = usePatchApiEventEventID(); const patchEvent = usePatchApiEventEventID();
const router = useRouter(); const router = useRouter();
// Extract event fields for form defaults
const event = eventData?.data?.event;
// State for date and time fields // State for date and time fields
const [startDate, setStartDate] = React.useState<Date | undefined>(undefined); const [startDate, setStartDate] = React.useState<Date | undefined>(undefined);
const [startTime, setStartTime] = React.useState(''); const [startTime, setStartTime] = React.useState('');
@ -87,22 +84,24 @@ const EventForm: React.FC<EventFormProps> = (props) => {
// Update state when event data loads // Update state when event data loads
React.useEffect(() => { React.useEffect(() => {
if (props.type === 'edit' && event) { if (props.type === 'edit' && eventData?.data?.event) {
setTitle(event.title || ''); setTitle(eventData?.data?.event.title || '');
// Parse start_time and end_time // Parse start_time and end_time
if (event.start_time) { if (eventData?.data?.event.start_time) {
const start = new Date(event.start_time); const start = new Date(eventData?.data?.event.start_time);
setStartDate(start); setStartDate(start);
setStartTime(start.toTimeString().slice(0, 5)); // "HH:mm" setStartTime(start.toTimeString().slice(0, 5)); // "HH:mm"
} }
if (event.end_time) { if (eventData?.data?.event.end_time) {
const end = new Date(event.end_time); const end = new Date(eventData?.data?.event.end_time);
setEndDate(end); setEndDate(end);
setEndTime(end.toTimeString().slice(0, 5)); // "HH:mm" setEndTime(end.toTimeString().slice(0, 5)); // "HH:mm"
} }
setLocation(event.location || ''); setLocation(eventData?.data?.event.location || '');
setDescription(event.description || ''); setDescription(eventData?.data?.event.description || '');
setSelectedParticipants(event.participants?.map((u) => u.user) || []); setSelectedParticipants(
eventData?.data?.event.participants?.map((u) => u.user) || [],
);
} else if (props.type === 'create' && startFromUrl && endFromUrl) { } else if (props.type === 'create' && startFromUrl && endFromUrl) {
// If creating a new event with URL params, set title and dates // If creating a new event with URL params, set title and dates
setTitle(''); setTitle('');
@ -113,7 +112,7 @@ const EventForm: React.FC<EventFormProps> = (props) => {
setEndDate(end); setEndDate(end);
setEndTime(end.toTimeString().slice(0, 5)); // "HH:mm" setEndTime(end.toTimeString().slice(0, 5)); // "HH:mm"
} }
}, [event, props.type, startFromUrl, endFromUrl]); }, [eventData?.data?.event, props.type, startFromUrl, endFromUrl]);
async function handleSubmit(e: React.FormEvent<HTMLFormElement>) { async function handleSubmit(e: React.FormEvent<HTMLFormElement>) {
e.preventDefault(); e.preventDefault();
@ -181,7 +180,7 @@ const EventForm: React.FC<EventFormProps> = (props) => {
<ToastInner <ToastInner
toastId={t} toastId={t}
title='Event saved' title='Event saved'
description={event?.title} description={eventData?.data?.event.title}
onAction={() => router.push(`/events/${eventID}`)} onAction={() => router.push(`/events/${eventID}`)}
variant='success' variant='success'
buttonText='show' buttonText='show'
@ -198,12 +197,12 @@ const EventForm: React.FC<EventFormProps> = (props) => {
// Use DB values for created_at/updated_at in edit mode // Use DB values for created_at/updated_at in edit mode
const createdAtValue = const createdAtValue =
props.type === 'edit' && event?.created_at props.type === 'edit' && eventData?.data?.event?.created_at
? event.created_at ? eventData.data.event.created_at
: new Date().toISOString(); : new Date().toISOString();
const updatedAtValue = const updatedAtValue =
props.type === 'edit' && event?.updated_at props.type === 'edit' && eventData?.data?.event?.updated_at
? event.updated_at ? eventData.data.event.updated_at
: new Date().toISOString(); : new Date().toISOString();
// Format date for display // Format date for display

View file

@ -98,7 +98,7 @@ export default function AccountTab() {
toast.custom((t) => ( toast.custom((t) => (
<ToastInner <ToastInner
toastId={t} toastId={t}
title='Settings saved' title='Error saving settings'
description={ description={
error.response?.data.message || 'An unknown error occurred.' error.response?.data.message || 'An unknown error occurred.'
} }