Merge pull request 'fix/117-toaster_button_on_event_creation' (#118)
Reviewed-on: #118 Reviewed-by: Dominik <mail@dominikstahl.dev>
This commit is contained in:
commit
ed6174ad34
5 changed files with 161 additions and 151 deletions
|
@ -40,14 +40,12 @@ export default function ShowEvent() {
|
||||||
|
|
||||||
if (isLoading || userLoading) {
|
if (isLoading || userLoading) {
|
||||||
return (
|
return (
|
||||||
<div className='flex justify-center items-center h-screen'>
|
<div className='flex justify-center items-center h-full'>Loading...</div>
|
||||||
Loading...
|
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (error || !eventData?.data?.event) {
|
if (error || !eventData?.data?.event) {
|
||||||
return (
|
return (
|
||||||
<div className='flex justify-center items-center h-screen'>
|
<div className='flex justify-center items-center h-full'>
|
||||||
Error loading event.
|
Error loading event.
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -70,167 +68,169 @@ export default function ShowEvent() {
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card className='w-[80%] max-w-screen p-0 gap-0 max-xl:w-[95%] mx-auto'>
|
<div className='flex items-center justify-center h-full'>
|
||||||
<CardHeader className='p-0 m-0 gap-0' />
|
<Card className='w-[80%] max-w-screen p-0 gap-0 max-xl:w-[95%] mx-auto'>
|
||||||
|
<CardHeader className='p-0 m-0 gap-0' />
|
||||||
|
|
||||||
<CardContent>
|
<CardContent>
|
||||||
<div className='flex flex-col gap-5 w-full'>
|
<div className='flex flex-col gap-5 w-full'>
|
||||||
<div className='grid grid-row-start:auto gap-4 sm:gap-8'>
|
<div className='grid grid-row-start:auto gap-4 sm:gap-8'>
|
||||||
<div className='h-full mt-0 ml-2 mb-16 flex items-center justify-between max-sm:grid max-sm:grid-row-start:auto max-sm:mb-6 max-sm:mt-10 max-sm:ml-0'>
|
<div className='h-full mt-0 ml-2 mb-16 flex items-center justify-between max-sm:grid max-sm:grid-row-start:auto max-sm:mb-6 max-sm:mt-10 max-sm:ml-0'>
|
||||||
<div className='w-[100px] max-sm:w-full max-sm:flex max-sm:justify-center'>
|
<div className='w-[100px] max-sm:w-full max-sm:flex max-sm:justify-center'>
|
||||||
<Logo colorType='monochrome' logoType='submark' width={50} />
|
<Logo colorType='monochrome' logoType='submark' width={50} />
|
||||||
|
</div>
|
||||||
|
<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'>
|
||||||
|
{event.title || 'Untitled Event'}
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
<div className='w-0 sm:w-[100px]'></div>
|
||||||
</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='grid grid-cols-4 gap-4 h-full w-full max-lg:grid-cols-2 max-sm:grid-cols-1'>
|
||||||
<h1 className='text-center'>
|
<div>
|
||||||
{event.title || 'Untitled Event'}
|
<Label className='text-[var(--color-neutral-300)] mb-2'>
|
||||||
</h1>
|
start Time
|
||||||
</div>
|
|
||||||
<div className='w-0 sm:w-[100px]'></div>
|
|
||||||
</div>
|
|
||||||
<div className='grid grid-cols-4 gap-4 h-full w-full max-lg:grid-cols-2 max-sm:grid-cols-1'>
|
|
||||||
<div>
|
|
||||||
<Label className='text-[var(--color-neutral-300)] mb-2'>
|
|
||||||
start Time
|
|
||||||
</Label>
|
|
||||||
<Label size='large'>
|
|
||||||
{event.start_time
|
|
||||||
? `${formatDate(event.start_time)} ${formatTime(event.start_time)}`
|
|
||||||
: '-'}
|
|
||||||
</Label>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<Label className='text-[var(--color-neutral-300)] mb-2'>
|
|
||||||
end Time
|
|
||||||
</Label>
|
|
||||||
<Label size='large'>
|
|
||||||
{event.end_time
|
|
||||||
? `${formatDate(event.end_time)} ${formatTime(event.end_time)}`
|
|
||||||
: '-'}
|
|
||||||
</Label>
|
|
||||||
</div>
|
|
||||||
<div className='w-54'>
|
|
||||||
<Label className='text-[var(--color-neutral-300)] mb-2'>
|
|
||||||
Location
|
|
||||||
</Label>
|
|
||||||
<Label size='large'>{event.location || '-'}</Label>
|
|
||||||
</div>
|
|
||||||
<div className='flex flex-col gap-4'>
|
|
||||||
<div className='flex flex-row gap-2'>
|
|
||||||
<Label className='w-[70px] text-[var(--color-neutral-300)]'>
|
|
||||||
created:
|
|
||||||
</Label>
|
</Label>
|
||||||
<Label>
|
<Label size='large'>
|
||||||
{event.created_at ? formatDate(event.created_at) : '-'}
|
{event.start_time
|
||||||
|
? `${formatDate(event.start_time)} ${formatTime(event.start_time)}`
|
||||||
|
: '-'}
|
||||||
</Label>
|
</Label>
|
||||||
</div>
|
</div>
|
||||||
<div className='flex flex-row gap-2'>
|
<div>
|
||||||
<Label className='w-[70px] text-[var(--color-neutral-300)]'>
|
<Label className='text-[var(--color-neutral-300)] mb-2'>
|
||||||
updated:
|
end Time
|
||||||
</Label>
|
</Label>
|
||||||
<Label>
|
<Label size='large'>
|
||||||
{event.updated_at ? formatDate(event.updated_at) : '-'}
|
{event.end_time
|
||||||
|
? `${formatDate(event.end_time)} ${formatTime(event.end_time)}`
|
||||||
|
: '-'}
|
||||||
</Label>
|
</Label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div className='w-54'>
|
||||||
</div>
|
<Label className='text-[var(--color-neutral-300)] mb-2'>
|
||||||
<div className='h-full w-full grid grid-cols-2 gap-4 max-sm:grid-cols-1'>
|
Location
|
||||||
<div className='h-full w-full grid grid-flow-row gap-4 sm:gap-8'>
|
</Label>
|
||||||
<div className='h-full w-full'>
|
<Label size='large'>{event.location || '-'}</Label>
|
||||||
|
</div>
|
||||||
|
<div className='flex flex-col gap-4'>
|
||||||
<div className='flex flex-row gap-2'>
|
<div className='flex flex-row gap-2'>
|
||||||
<Label className='text-[var(--color-neutral-300)]'>
|
<Label className='w-[70px] text-[var(--color-neutral-300)]'>
|
||||||
Organiser:
|
created:
|
||||||
|
</Label>
|
||||||
|
<Label>
|
||||||
|
{event.created_at ? formatDate(event.created_at) : '-'}
|
||||||
|
</Label>
|
||||||
|
</div>
|
||||||
|
<div className='flex flex-row gap-2'>
|
||||||
|
<Label className='w-[70px] text-[var(--color-neutral-300)]'>
|
||||||
|
updated:
|
||||||
|
</Label>
|
||||||
|
<Label>
|
||||||
|
{event.updated_at ? formatDate(event.updated_at) : '-'}
|
||||||
</Label>
|
</Label>
|
||||||
<Label size='large'>{organiserName}</Label>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className='h-full w-full'>
|
</div>
|
||||||
|
<div className='h-full w-full grid grid-cols-2 gap-4 max-sm:grid-cols-1'>
|
||||||
|
<div className='h-full w-full grid grid-flow-row gap-4 sm:gap-8'>
|
||||||
|
<div className='h-full w-full'>
|
||||||
|
<div className='flex flex-row gap-2'>
|
||||||
|
<Label className='text-[var(--color-neutral-300)]'>
|
||||||
|
Organiser:
|
||||||
|
</Label>
|
||||||
|
<Label size='large'>{organiserName}</Label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className='h-full w-full'>
|
||||||
|
<Label className='text-[var(--color-neutral-300)] mb-2'>
|
||||||
|
Description
|
||||||
|
</Label>
|
||||||
|
<Label size='large'>{event.description || '-'}</Label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className='h-full w-full mt-2'>
|
||||||
<Label className='text-[var(--color-neutral-300)] mb-2'>
|
<Label className='text-[var(--color-neutral-300)] mb-2'>
|
||||||
Description
|
Participants
|
||||||
</Label>
|
</Label>{' '}
|
||||||
<Label size='large'>{event.description || '-'}</Label>
|
<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) => (
|
||||||
|
<ParticipantListEntry key={user.user.id} {...user} />
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className='h-full w-full mt-2'>
|
|
||||||
<Label className='text-[var(--color-neutral-300)] mb-2'>
|
|
||||||
Participants
|
|
||||||
</Label>{' '}
|
|
||||||
<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) => (
|
|
||||||
<ParticipantListEntry key={user.user.id} {...user} />
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<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 === event.organizer.id ? (
|
||||||
<Dialog
|
<Dialog
|
||||||
open={deleteDialogOpen}
|
open={deleteDialogOpen}
|
||||||
onOpenChange={setDeleteDialogOpen}
|
onOpenChange={setDeleteDialogOpen}
|
||||||
>
|
>
|
||||||
<DialogTrigger asChild>
|
<DialogTrigger asChild>
|
||||||
<Button variant='destructive' className='w-full'>
|
<Button variant='destructive' className='w-full'>
|
||||||
delete
|
delete
|
||||||
</Button>
|
|
||||||
</DialogTrigger>
|
|
||||||
<DialogContent>
|
|
||||||
<DialogHeader>
|
|
||||||
<DialogTitle>Delete Event</DialogTitle>
|
|
||||||
<DialogDescription>
|
|
||||||
Are you sure you want to delete the event “
|
|
||||||
{event.title}”? This action cannot be undone.
|
|
||||||
</DialogDescription>
|
|
||||||
</DialogHeader>
|
|
||||||
<DialogFooter>
|
|
||||||
<Button
|
|
||||||
variant='secondary'
|
|
||||||
onClick={() => setDeleteDialogOpen(false)}
|
|
||||||
>
|
|
||||||
Cancel
|
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
</DialogTrigger>
|
||||||
variant='muted'
|
<DialogContent>
|
||||||
onClick={() => {
|
<DialogHeader>
|
||||||
deleteEvent.mutate(
|
<DialogTitle>Delete Event</DialogTitle>
|
||||||
{ eventID: event.id },
|
<DialogDescription>
|
||||||
{
|
Are you sure you want to delete the event “
|
||||||
onSuccess: () => {
|
{event.title}”? This action cannot be undone.
|
||||||
router.push('/home');
|
</DialogDescription>
|
||||||
toast.custom((t) => (
|
</DialogHeader>
|
||||||
<ToastInner
|
<DialogFooter>
|
||||||
toastId={t}
|
<Button
|
||||||
title='Event deleted'
|
variant='secondary'
|
||||||
description={event?.title}
|
onClick={() => setDeleteDialogOpen(false)}
|
||||||
variant='success'
|
>
|
||||||
/>
|
Cancel
|
||||||
));
|
</Button>
|
||||||
|
<Button
|
||||||
|
variant='muted'
|
||||||
|
onClick={() => {
|
||||||
|
deleteEvent.mutate(
|
||||||
|
{ eventID: event.id },
|
||||||
|
{
|
||||||
|
onSuccess: () => {
|
||||||
|
router.push('/home');
|
||||||
|
toast.custom((t) => (
|
||||||
|
<ToastInner
|
||||||
|
toastId={t}
|
||||||
|
title='Event deleted'
|
||||||
|
description={event?.title}
|
||||||
|
variant='success'
|
||||||
|
/>
|
||||||
|
));
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
);
|
||||||
);
|
setDeleteDialogOpen(false);
|
||||||
setDeleteDialogOpen(false);
|
}}
|
||||||
}}
|
>
|
||||||
>
|
Delete
|
||||||
Delete
|
</Button>
|
||||||
</Button>
|
</DialogFooter>
|
||||||
</DialogFooter>
|
</DialogContent>
|
||||||
</DialogContent>
|
</Dialog>
|
||||||
</Dialog>
|
) : 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 === event.organizer.id ? (
|
<RedirectButton
|
||||||
<RedirectButton
|
redirectUrl={`/events/edit/${eventID}`}
|
||||||
redirectUrl={`/events/edit/${eventID}`}
|
buttonText='edit'
|
||||||
buttonText='edit'
|
className='w-full'
|
||||||
className='w-full'
|
/>
|
||||||
/>
|
) : null}
|
||||||
) : null}
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</CardContent>
|
||||||
</CardContent>
|
</Card>
|
||||||
</Card>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { Suspense } from 'react';
|
||||||
|
|
||||||
export default function NewEvent() {
|
export default function NewEvent() {
|
||||||
return (
|
return (
|
||||||
<div className='flex flex-col items-center justify-center h-screen'>
|
<div className='flex flex-col items-center justify-center h-full'>
|
||||||
<Card className='w-[80%] max-w-screen p-0 gap-0 max-xl:w-[95%] max-h-[90vh] overflow-auto'>
|
<Card className='w-[80%] max-w-screen p-0 gap-0 max-xl:w-[95%] max-h-[90vh] overflow-auto'>
|
||||||
<CardHeader className='p-0 m-0 gap-0' />
|
<CardHeader className='p-0 m-0 gap-0' />
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ export default function Events() {
|
||||||
const events = eventsData?.data?.events || [];
|
const events = eventsData?.data?.events || [];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='relative h-screen flex flex-col items-center'>
|
<div className='relative h-full flex flex-col items-center'>
|
||||||
{/* Heading */}
|
{/* Heading */}
|
||||||
<h1 className='text-3xl font-bold mt-8 mb-4 text-center z-10'>
|
<h1 className='text-3xl font-bold mt-8 mb-4 text-center z-10'>
|
||||||
My Events
|
My Events
|
||||||
|
|
|
@ -233,7 +233,7 @@ function CalendarWithUserEvents({
|
||||||
resourceTitleAccessor={(event) => event.title}
|
resourceTitleAccessor={(event) => event.title}
|
||||||
startAccessor={(event) => event.start}
|
startAccessor={(event) => event.start}
|
||||||
endAccessor={(event) => event.end}
|
endAccessor={(event) => event.end}
|
||||||
selectable={sesstion.data?.user?.id === userId && !additionalEvents}
|
selectable={sesstion.data?.user?.id === userId}
|
||||||
onEventDrop={(event) => {
|
onEventDrop={(event) => {
|
||||||
const { start, end, event: droppedEvent } = event;
|
const { start, end, event: droppedEvent } = event;
|
||||||
if (droppedEvent.type === 'blocked_private') return;
|
if (droppedEvent.type === 'blocked_private') return;
|
||||||
|
|
|
@ -51,7 +51,12 @@ const EventForm: React.FC<EventFormProps> = (props) => {
|
||||||
const startFromUrl = searchParams.get('start');
|
const startFromUrl = searchParams.get('start');
|
||||||
const endFromUrl = searchParams.get('end');
|
const endFromUrl = searchParams.get('end');
|
||||||
|
|
||||||
const { mutate: createEvent, status, isSuccess, error } = usePostApiEvent();
|
const {
|
||||||
|
mutateAsync: createEvent,
|
||||||
|
status,
|
||||||
|
isSuccess,
|
||||||
|
error,
|
||||||
|
} = usePostApiEvent();
|
||||||
const { data, isLoading, error: fetchError } = useGetApiUserMe();
|
const { data, isLoading, error: fetchError } = useGetApiUserMe();
|
||||||
const { data: eventData } = useGetApiEventEventID(props.eventId!, {
|
const { data: eventData } = useGetApiEventEventID(props.eventId!, {
|
||||||
query: { enabled: props.type === 'edit' },
|
query: { enabled: props.type === 'edit' },
|
||||||
|
@ -150,8 +155,10 @@ const EventForm: React.FC<EventFormProps> = (props) => {
|
||||||
participants: selectedParticipants.map((u) => u.id),
|
participants: selectedParticipants.map((u) => u.id),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let eventID: string | undefined;
|
||||||
|
|
||||||
if (props.type === 'edit' && props.eventId) {
|
if (props.type === 'edit' && props.eventId) {
|
||||||
await patchEvent.mutateAsync({
|
const mutationResult = await patchEvent.mutateAsync({
|
||||||
eventID: props.eventId,
|
eventID: props.eventId,
|
||||||
data: {
|
data: {
|
||||||
title: data.title,
|
title: data.title,
|
||||||
|
@ -162,9 +169,12 @@ const EventForm: React.FC<EventFormProps> = (props) => {
|
||||||
participants: data.participants,
|
participants: data.participants,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
eventID = mutationResult.data.event.id;
|
||||||
console.log('Updating event');
|
console.log('Updating event');
|
||||||
} else {
|
} else {
|
||||||
console.log('Creating event');
|
console.log('Creating event');
|
||||||
|
const mutationResult = await createEvent({ data });
|
||||||
|
eventID = mutationResult.data.event.id;
|
||||||
createEvent({ data });
|
createEvent({ data });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -173,7 +183,7 @@ const EventForm: React.FC<EventFormProps> = (props) => {
|
||||||
toastId={t}
|
toastId={t}
|
||||||
title='Event saved'
|
title='Event saved'
|
||||||
description={event?.title}
|
description={event?.title}
|
||||||
onAction={() => router.push(`/events/${event?.id}`)}
|
onAction={() => router.push(`/events/${eventID}`)}
|
||||||
variant='success'
|
variant='success'
|
||||||
buttonText='show'
|
buttonText='show'
|
||||||
/>
|
/>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue