Compare commits

...

8 commits

Author SHA1 Message Date
b3cb551f7c
fix: event cards layout bugs
Some checks failed
container-scan / Container Scan (pull_request) Successful in 5m2s
tests / Tests (pull_request) Has been cancelled
docker-build / docker (pull_request) Has been cancelled
2025-07-01 11:38:16 +02:00
d7fdd5d257
fix: event deletion issues 2025-07-01 11:37:49 +02:00
9015e993a8 Merge pull request 'fix: hotfixes' (#128)
All checks were successful
container-scan / Container Scan (push) Successful in 2m33s
tests / Tests (push) Successful in 3m20s
docker-build / docker (push) Successful in 1m7s
Reviewed-on: #128
Reviewed-by: micha <MichaBokelmann@web.de>
2025-07-01 09:03:57 +00:00
8dd014ead1 Merge pull request 'test: add event creation test' (#127)
All checks were successful
container-scan / Container Scan (push) Successful in 2m32s
tests / Tests (push) Successful in 3m35s
docker-build / docker (push) Successful in 1m17s
Reviewed-on: #127
Reviewed-by: Maximilian Liebmann <lima@noreply.git.dominikstahl.dev>
2025-07-01 08:18:49 +00:00
b26a46274c Merge pull request 'fix: empty event form edit fields' (#125)
All checks were successful
container-scan / Container Scan (push) Successful in 2m29s
docker-build / docker (push) Successful in 4m8s
tests / Tests (push) Successful in 3m44s
Reviewed-on: #125
Reviewed-by: Maximilian Liebmann <lima@noreply.git.dominikstahl.dev>
2025-07-01 07:20:09 +00:00
cb793b9a38
fix: remove penguin source
All checks were successful
container-scan / Container Scan (pull_request) Successful in 2m33s
docker-build / docker (pull_request) Successful in 4m4s
tests / Tests (pull_request) Successful in 3m45s
2025-07-01 09:08:16 +02:00
2a95836dcb
fix: settings error message
Some checks failed
container-scan / Container Scan (pull_request) Successful in 2m32s
tests / Tests (pull_request) Has been cancelled
docker-build / docker (pull_request) Successful in 3m41s
2025-07-01 08:59:43 +02:00
b5602bead5
fix: empty event form edit fields
Some checks failed
container-scan / Container Scan (pull_request) Failing after 31s
tests / Tests (pull_request) Has been cancelled
docker-build / docker (pull_request) Failing after 2m30s
2025-07-01 08:55:53 +02:00
9 changed files with 241 additions and 54 deletions

View file

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

View file

@ -1,6 +1,6 @@
{
"name": "meetup",
"version": "0.1.0",
"version": "0.1.3",
"private": true,
"scripts": {
"dev": "next dev --turbopack",

View file

@ -0,0 +1,170 @@
-- RedefineTables
PRAGMA defer_foreign_keys=ON;
PRAGMA foreign_keys=OFF;
CREATE TABLE "new_blocked_slots" (
"id" TEXT NOT NULL PRIMARY KEY,
"user_id" TEXT NOT NULL,
"start_time" DATETIME NOT NULL,
"end_time" DATETIME NOT NULL,
"reason" TEXT,
"is_recurring" BOOLEAN NOT NULL DEFAULT false,
"rrule" TEXT,
"recurrence_end_date" DATETIME,
"created_at" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" DATETIME NOT NULL,
CONSTRAINT "blocked_slots_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE CASCADE
);
INSERT INTO "new_blocked_slots" ("created_at", "end_time", "id", "is_recurring", "reason", "recurrence_end_date", "rrule", "start_time", "updated_at", "user_id") SELECT "created_at", "end_time", "id", "is_recurring", "reason", "recurrence_end_date", "rrule", "start_time", "updated_at", "user_id" FROM "blocked_slots";
DROP TABLE "blocked_slots";
ALTER TABLE "new_blocked_slots" RENAME TO "blocked_slots";
CREATE INDEX "blocked_slots_user_id_start_time_end_time_idx" ON "blocked_slots"("user_id", "start_time", "end_time");
CREATE INDEX "blocked_slots_user_id_is_recurring_idx" ON "blocked_slots"("user_id", "is_recurring");
CREATE TABLE "new_calendar_export_tokens" (
"id" TEXT NOT NULL PRIMARY KEY,
"user_id" TEXT NOT NULL,
"token" TEXT NOT NULL,
"scope" TEXT NOT NULL DEFAULT 'MEETINGS_ONLY',
"is_active" BOOLEAN NOT NULL DEFAULT true,
"created_at" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"last_accessed_at" DATETIME,
CONSTRAINT "calendar_export_tokens_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE CASCADE
);
INSERT INTO "new_calendar_export_tokens" ("created_at", "id", "is_active", "last_accessed_at", "scope", "token", "user_id") SELECT "created_at", "id", "is_active", "last_accessed_at", "scope", "token", "user_id" FROM "calendar_export_tokens";
DROP TABLE "calendar_export_tokens";
ALTER TABLE "new_calendar_export_tokens" RENAME TO "calendar_export_tokens";
CREATE UNIQUE INDEX "calendar_export_tokens_token_key" ON "calendar_export_tokens"("token");
CREATE INDEX "calendar_export_tokens_user_id_idx" ON "calendar_export_tokens"("user_id");
CREATE TABLE "new_calendar_subscriptions" (
"id" TEXT NOT NULL PRIMARY KEY,
"user_id" TEXT NOT NULL,
"feed_url" TEXT NOT NULL,
"name" TEXT,
"color" TEXT,
"is_enabled" BOOLEAN NOT NULL DEFAULT true,
"last_synced_at" DATETIME,
"last_sync_error" TEXT,
"sync_frequency_minutes" INTEGER DEFAULT 60,
"created_at" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" DATETIME NOT NULL,
CONSTRAINT "calendar_subscriptions_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE CASCADE
);
INSERT INTO "new_calendar_subscriptions" ("color", "created_at", "feed_url", "id", "is_enabled", "last_sync_error", "last_synced_at", "name", "sync_frequency_minutes", "updated_at", "user_id") SELECT "color", "created_at", "feed_url", "id", "is_enabled", "last_sync_error", "last_synced_at", "name", "sync_frequency_minutes", "updated_at", "user_id" FROM "calendar_subscriptions";
DROP TABLE "calendar_subscriptions";
ALTER TABLE "new_calendar_subscriptions" RENAME TO "calendar_subscriptions";
CREATE INDEX "calendar_subscriptions_user_id_is_enabled_idx" ON "calendar_subscriptions"("user_id", "is_enabled");
CREATE TABLE "new_email_queue" (
"id" TEXT NOT NULL PRIMARY KEY,
"user_id" TEXT NOT NULL,
"subject" TEXT NOT NULL,
"body_html" TEXT NOT NULL,
"body_text" TEXT,
"status" TEXT NOT NULL DEFAULT 'PENDING',
"scheduled_at" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"attempts" INTEGER NOT NULL DEFAULT 0,
"last_attempt_at" DATETIME,
"sent_at" DATETIME,
"error_message" TEXT,
"created_at" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" DATETIME NOT NULL,
CONSTRAINT "email_queue_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE CASCADE
);
INSERT INTO "new_email_queue" ("attempts", "body_html", "body_text", "created_at", "error_message", "id", "last_attempt_at", "scheduled_at", "sent_at", "status", "subject", "updated_at", "user_id") SELECT "attempts", "body_html", "body_text", "created_at", "error_message", "id", "last_attempt_at", "scheduled_at", "sent_at", "status", "subject", "updated_at", "user_id" FROM "email_queue";
DROP TABLE "email_queue";
ALTER TABLE "new_email_queue" RENAME TO "email_queue";
CREATE INDEX "idx_email_queue_pending_jobs" ON "email_queue"("status", "scheduled_at");
CREATE INDEX "idx_email_queue_user_history" ON "email_queue"("user_id", "created_at");
CREATE TABLE "new_external_events" (
"id" TEXT NOT NULL PRIMARY KEY,
"subscription_id" TEXT NOT NULL,
"ical_uid" TEXT NOT NULL,
"summary" TEXT,
"description" TEXT,
"start_time" DATETIME NOT NULL,
"end_time" DATETIME NOT NULL,
"is_all_day" BOOLEAN NOT NULL DEFAULT false,
"location" TEXT,
"rrule" TEXT,
"dtstamp" DATETIME,
"sequence" INTEGER,
"show_as_free" BOOLEAN NOT NULL DEFAULT false,
"last_fetched_at" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "external_events_subscription_id_fkey" FOREIGN KEY ("subscription_id") REFERENCES "calendar_subscriptions" ("id") ON DELETE CASCADE ON UPDATE CASCADE
);
INSERT INTO "new_external_events" ("description", "dtstamp", "end_time", "ical_uid", "id", "is_all_day", "last_fetched_at", "location", "rrule", "sequence", "show_as_free", "start_time", "subscription_id", "summary") SELECT "description", "dtstamp", "end_time", "ical_uid", "id", "is_all_day", "last_fetched_at", "location", "rrule", "sequence", "show_as_free", "start_time", "subscription_id", "summary" FROM "external_events";
DROP TABLE "external_events";
ALTER TABLE "new_external_events" RENAME TO "external_events";
CREATE INDEX "external_events_subscription_id_start_time_end_time_idx" ON "external_events"("subscription_id", "start_time", "end_time");
CREATE INDEX "external_events_subscription_id_show_as_free_idx" ON "external_events"("subscription_id", "show_as_free");
CREATE UNIQUE INDEX "external_events_subscription_id_ical_uid_key" ON "external_events"("subscription_id", "ical_uid");
CREATE TABLE "new_friendships" (
"user_id_1" TEXT NOT NULL,
"user_id_2" TEXT NOT NULL,
"status" TEXT NOT NULL DEFAULT 'PENDING',
"requested_at" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"accepted_at" DATETIME,
PRIMARY KEY ("user_id_1", "user_id_2"),
CONSTRAINT "friendships_user_id_1_fkey" FOREIGN KEY ("user_id_1") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT "friendships_user_id_2_fkey" FOREIGN KEY ("user_id_2") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE CASCADE
);
INSERT INTO "new_friendships" ("accepted_at", "requested_at", "status", "user_id_1", "user_id_2") SELECT "accepted_at", "requested_at", "status", "user_id_1", "user_id_2" FROM "friendships";
DROP TABLE "friendships";
ALTER TABLE "new_friendships" RENAME TO "friendships";
CREATE INDEX "idx_friendships_user2_status" ON "friendships"("user_id_2", "status");
CREATE TABLE "new_group_members" (
"group_id" TEXT NOT NULL,
"user_id" TEXT NOT NULL,
"role" TEXT NOT NULL DEFAULT 'MEMBER',
"added_at" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY ("group_id", "user_id"),
CONSTRAINT "group_members_group_id_fkey" FOREIGN KEY ("group_id") REFERENCES "groups" ("id") ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT "group_members_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE CASCADE
);
INSERT INTO "new_group_members" ("added_at", "group_id", "role", "user_id") SELECT "added_at", "group_id", "role", "user_id" FROM "group_members";
DROP TABLE "group_members";
ALTER TABLE "new_group_members" RENAME TO "group_members";
CREATE INDEX "group_members_user_id_idx" ON "group_members"("user_id");
CREATE TABLE "new_meeting_participants" (
"meeting_id" TEXT NOT NULL,
"user_id" TEXT NOT NULL,
"status" TEXT NOT NULL DEFAULT 'PENDING',
"added_at" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY ("meeting_id", "user_id"),
CONSTRAINT "meeting_participants_meeting_id_fkey" FOREIGN KEY ("meeting_id") REFERENCES "meetings" ("id") ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT "meeting_participants_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE CASCADE
);
INSERT INTO "new_meeting_participants" ("added_at", "meeting_id", "status", "user_id") SELECT "added_at", "meeting_id", "status", "user_id" FROM "meeting_participants";
DROP TABLE "meeting_participants";
ALTER TABLE "new_meeting_participants" RENAME TO "meeting_participants";
CREATE INDEX "idx_participants_user_status" ON "meeting_participants"("user_id", "status");
CREATE TABLE "new_notifications" (
"id" TEXT NOT NULL PRIMARY KEY,
"user_id" TEXT NOT NULL,
"type" TEXT NOT NULL,
"related_entity_type" TEXT,
"related_entity_id" TEXT,
"message" TEXT NOT NULL,
"is_read" BOOLEAN NOT NULL DEFAULT false,
"created_at" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "notifications_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE CASCADE
);
INSERT INTO "new_notifications" ("created_at", "id", "is_read", "message", "related_entity_id", "related_entity_type", "type", "user_id") SELECT "created_at", "id", "is_read", "message", "related_entity_id", "related_entity_type", "type", "user_id" FROM "notifications";
DROP TABLE "notifications";
ALTER TABLE "new_notifications" RENAME TO "notifications";
CREATE INDEX "idx_notifications_user_read_time" ON "notifications"("user_id", "is_read", "created_at");
CREATE TABLE "new_user_notification_preferences" (
"user_id" TEXT NOT NULL,
"notification_type" TEXT NOT NULL,
"email_enabled" BOOLEAN NOT NULL DEFAULT false,
"updated_at" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY ("user_id", "notification_type"),
CONSTRAINT "user_notification_preferences_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE CASCADE
);
INSERT INTO "new_user_notification_preferences" ("email_enabled", "notification_type", "updated_at", "user_id") SELECT "email_enabled", "notification_type", "updated_at", "user_id" FROM "user_notification_preferences";
DROP TABLE "user_notification_preferences";
ALTER TABLE "new_user_notification_preferences" RENAME TO "user_notification_preferences";
PRAGMA foreign_keys=ON;
PRAGMA defer_foreign_keys=OFF;

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
const formatDate = (isoString?: string) => {
if (!isoString) return '-';
@ -81,7 +78,7 @@ export default function ShowEvent() {
</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'}
{eventData.data.event.title || 'Untitled Event'}
</h1>
</div>
<div className='w-0 sm:w-[100px]'></div>
@ -92,8 +89,8 @@ export default function ShowEvent() {
start Time
</Label>
<Label size='large'>
{event.start_time
? `${formatDate(event.start_time)} ${formatTime(event.start_time)}`
{eventData.data.event.start_time
? `${formatDate(eventData.data.event.start_time)} ${formatTime(eventData.data.event.start_time)}`
: '-'}
</Label>
</div>
@ -102,8 +99,8 @@ export default function ShowEvent() {
end Time
</Label>
<Label size='large'>
{event.end_time
? `${formatDate(event.end_time)} ${formatTime(event.end_time)}`
{eventData.data.event.end_time
? `${formatDate(eventData.data.event.end_time)} ${formatTime(eventData.data.event.end_time)}`
: '-'}
</Label>
</div>
@ -111,7 +108,9 @@ export default function ShowEvent() {
<Label className='text-[var(--color-neutral-300)] mb-2'>
Location
</Label>
<Label size='large'>{event.location || '-'}</Label>
<Label size='large'>
{eventData.data.event.location || '-'}
</Label>
</div>
<div className='flex flex-col gap-4'>
<div className='flex flex-row gap-2'>
@ -119,7 +118,9 @@ export default function ShowEvent() {
created:
</Label>
<Label>
{event.created_at ? formatDate(event.created_at) : '-'}
{eventData.data.event.created_at
? formatDate(eventData.data.event.created_at)
: '-'}
</Label>
</div>
<div className='flex flex-row gap-2'>
@ -127,7 +128,9 @@ export default function ShowEvent() {
updated:
</Label>
<Label>
{event.updated_at ? formatDate(event.updated_at) : '-'}
{eventData.data.event.updated_at
? formatDate(eventData.data.event.updated_at)
: '-'}
</Label>
</div>
</div>
@ -139,26 +142,30 @@ export default function ShowEvent() {
<Label className='text-[var(--color-neutral-300)]'>
Organiser:
</Label>
<Label size='large'>{organiserName}</Label>
<Label size='large'>
{userData?.data.user?.name || 'Unknown User'}
</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>
<Label size='large'>
{eventData.data.event.description || '-'}
</Label>
</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) => (
<div className='grid grid-cols-1 mt-3'>
{eventData.data.event.participants?.map((user) => (
<ParticipantListEntry
key={user.user.id}
{...user}
eventID={event.id}
eventID={eventData.data.event.id}
/>
))}
</div>
@ -167,7 +174,8 @@ export default function ShowEvent() {
<div className='flex flex-row gap-2 justify-end mt-4 mb-6'>
<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
open={deleteDialogOpen}
onOpenChange={setDeleteDialogOpen}
@ -182,7 +190,8 @@ export default function ShowEvent() {
<DialogTitle>Delete Event</DialogTitle>
<DialogDescription>
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>
</DialogHeader>
<DialogFooter>
@ -196,7 +205,7 @@ export default function ShowEvent() {
variant='muted'
onClick={() => {
deleteEvent.mutate(
{ eventID: event.id },
{ eventID: eventData.data.event.id },
{
onSuccess: () => {
router.push('/home');
@ -204,7 +213,7 @@ export default function ShowEvent() {
<ToastInner
toastId={t}
title='Event deleted'
description={event?.title}
description={eventData.data.event.title}
variant='success'
/>
));
@ -222,7 +231,8 @@ export default function ShowEvent() {
) : null}
</div>
<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
redirectUrl={`/events/edit/${eventID}`}
buttonText='edit'

View file

@ -63,10 +63,11 @@ export default async function LoginPage() {
</HoverCardTrigger>
<HoverCardContent className='flex items-center justify-center'>
<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'
height='150'
alt='dancing penguin'
alt='cat gif'
unoptimized
></Image>
</HoverCardContent>
</HoverCard>

View file

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

View file

@ -5,7 +5,6 @@ import { Button } from '@/components/ui/button';
import Logo from '@/components/misc/logo';
import TimePicker from '@/components/time-picker';
import { Label } from '@/components/ui/label';
import { useGetApiUserMe } from '@/generated/api/user/user';
import {
usePostApiEvent,
useGetApiEventEventID,
@ -57,16 +56,16 @@ const EventForm: React.FC<EventFormProps> = (props) => {
isSuccess,
error,
} = usePostApiEvent();
const { data, isLoading, error: fetchError } = useGetApiUserMe();
const { data: eventData } = useGetApiEventEventID(props.eventId!, {
const {
data: eventData,
isLoading,
isError,
} = useGetApiEventEventID(props.eventId!, {
query: { enabled: props.type === 'edit' },
});
const patchEvent = usePatchApiEventEventID();
const router = useRouter();
// Extract event fields for form defaults
const event = eventData?.data?.event;
// State for date and time fields
const [startDate, setStartDate] = React.useState<Date | undefined>(undefined);
const [startTime, setStartTime] = React.useState('');
@ -87,22 +86,24 @@ const EventForm: React.FC<EventFormProps> = (props) => {
// Update state when event data loads
React.useEffect(() => {
if (props.type === 'edit' && event) {
setTitle(event.title || '');
if (props.type === 'edit' && eventData?.data?.event) {
setTitle(eventData?.data?.event.title || '');
// Parse start_time and end_time
if (event.start_time) {
const start = new Date(event.start_time);
if (eventData?.data?.event.start_time) {
const start = new Date(eventData?.data?.event.start_time);
setStartDate(start);
setStartTime(start.toTimeString().slice(0, 5)); // "HH:mm"
}
if (event.end_time) {
const end = new Date(event.end_time);
if (eventData?.data?.event.end_time) {
const end = new Date(eventData?.data?.event.end_time);
setEndDate(end);
setEndTime(end.toTimeString().slice(0, 5)); // "HH:mm"
}
setLocation(event.location || '');
setDescription(event.description || '');
setSelectedParticipants(event.participants?.map((u) => u.user) || []);
setLocation(eventData?.data?.event.location || '');
setDescription(eventData?.data?.event.description || '');
setSelectedParticipants(
eventData?.data?.event.participants?.map((u) => u.user) || [],
);
} else if (props.type === 'create' && startFromUrl && endFromUrl) {
// If creating a new event with URL params, set title and dates
setTitle('');
@ -113,7 +114,7 @@ const EventForm: React.FC<EventFormProps> = (props) => {
setEndDate(end);
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>) {
e.preventDefault();
@ -181,7 +182,7 @@ const EventForm: React.FC<EventFormProps> = (props) => {
<ToastInner
toastId={t}
title='Event saved'
description={event?.title}
description={eventData?.data?.event.title}
onAction={() => router.push(`/events/${eventID}`)}
variant='success'
buttonText='show'
@ -193,12 +194,12 @@ const EventForm: React.FC<EventFormProps> = (props) => {
// Use DB values for created_at/updated_at in edit mode
const createdAtValue =
props.type === 'edit' && event?.created_at
? event.created_at
props.type === 'edit' && eventData?.data?.event?.created_at
? eventData.data.event.created_at
: new Date().toISOString();
const updatedAtValue =
props.type === 'edit' && event?.updated_at
? event.updated_at
props.type === 'edit' && eventData?.data?.event?.updated_at
? eventData.data.event.updated_at
: new Date().toISOString();
// Format date for display
@ -211,8 +212,7 @@ const EventForm: React.FC<EventFormProps> = (props) => {
}, []);
if (props.type === 'edit' && isLoading) return <div>Loading...</div>;
if (props.type === 'edit' && fetchError)
return <div>Error loading event.</div>;
if (props.type === 'edit' && isError) return <div>Error loading event.</div>;
return (
<Dialog open={calendarOpen} onOpenChange={setCalendarOpen}>
@ -299,7 +299,7 @@ const EventForm: React.FC<EventFormProps> = (props) => {
<p className='text-[var(--color-neutral-300)]'>
{!isClient || isLoading
? 'Loading...'
: data?.data.user?.name || 'Unknown User'}
: eventData?.data.event.organizer.name || 'Unknown User'}
</p>
</div>
</div>
@ -336,7 +336,7 @@ const EventForm: React.FC<EventFormProps> = (props) => {
<DialogTrigger asChild>
<Button variant='primary'>Calendar</Button>
</DialogTrigger>
<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'>
{selectedParticipants.map((user) => (
<ParticipantListEntry
key={user.id}

View file

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

View file

@ -32,8 +32,8 @@ export default function TimePicker({
const [open, setOpen] = React.useState(false);
return (
<div className='flex gap-4' {...props}>
<div className='flex flex-col gap-3'>
<div className='grid grid-cols-2 gap-4' {...props}>
<div className='grid grid-rows-2 gap-2'>
<Label htmlFor='date' className='px-1'>
{dateLabel}
</Label>
@ -69,7 +69,7 @@ export default function TimePicker({
</PopoverContent>
</Popover>
</div>
<div className='flex flex-col gap-3'>
<div className='grid grid-rows-2 gap-2'>
<Label htmlFor='time' className='px-1'>
{timeLabel}
</Label>