From 26824eb3a86f7ba4cfcc9f28c9488910874270f4 Mon Sep 17 00:00:00 2001 From: Levente Orban Date: Thu, 25 Sep 2025 09:28:44 +0200 Subject: [PATCH] fix: location missing field error --- database/init.sql | 2 +- src/lib/database/schema.ts | 4 +- src/lib/i18n/messages.json | 12 ++- src/lib/types.ts | 2 +- src/routes/+page.svelte | 2 +- src/routes/create/+page.server.ts | 6 +- src/routes/create/+page.svelte | 115 ++++++++++++--------- src/routes/discover/+page.svelte | 6 +- src/routes/event/+page.svelte | 6 +- src/routes/event/[id]/+page.svelte | 10 +- src/routes/event/[id]/edit/+page.server.ts | 6 +- src/routes/event/[id]/edit/+page.svelte | 107 +++++++++++-------- 12 files changed, 161 insertions(+), 117 deletions(-) diff --git a/database/init.sql b/database/init.sql index c9683cd..fa47a98 100644 --- a/database/init.sql +++ b/database/init.sql @@ -14,7 +14,7 @@ CREATE TABLE IF NOT EXISTS events ( date DATE NOT NULL, time TIME NOT NULL, location VARCHAR(200) NOT NULL, - location_type VARCHAR(20) NOT NULL DEFAULT 'text' CHECK (location_type IN ('text','maps')), + location_type VARCHAR(20) NOT NULL DEFAULT 'none' CHECK (location_type IN ('none','text','maps')), location_url VARCHAR(500), type VARCHAR(20) NOT NULL CHECK (type IN ('limited','unlimited')), attendee_limit INTEGER CHECK (attendee_limit > 0), diff --git a/src/lib/database/schema.ts b/src/lib/database/schema.ts index f3f8080..c5d0d21 100644 --- a/src/lib/database/schema.ts +++ b/src/lib/database/schema.ts @@ -17,7 +17,7 @@ import type { InferInsertModel, InferSelectModel } from 'drizzle-orm'; // --- Enums (matching the SQL CHECK constraints) export const eventTypeEnum = pgEnum('event_type', ['limited', 'unlimited']); export const visibilityEnum = pgEnum('visibility', ['public', 'private']); -export const locationTypeEnum = pgEnum('location_type', ['text', 'maps']); +export const locationTypeEnum = pgEnum('location_type', ['none', 'text', 'maps']); // --- Events table export const events = pgTable( @@ -28,7 +28,7 @@ export const events = pgTable( date: date('date', { mode: 'string' }).notNull(), // ISO 'YYYY-MM-DD' time: time('time', { withTimezone: false }).notNull(), // 'HH:MM:SS' location: varchar('location', { length: 200 }).notNull(), - locationType: locationTypeEnum('location_type').notNull().default('text'), + locationType: locationTypeEnum('location_type').notNull().default('none'), locationUrl: varchar('location_url', { length: 500 }), type: eventTypeEnum('type').notNull(), attendeeLimit: integer('attendee_limit'), // nullable in SQL diff --git a/src/lib/i18n/messages.json b/src/lib/i18n/messages.json index c38b4f8..d4e0f3e 100644 --- a/src/lib/i18n/messages.json +++ b/src/lib/i18n/messages.json @@ -15,8 +15,10 @@ "time": "Time", "location": "Location", "locationType": "Location Type", + "locationNone": "None", "locationText": "Text", "locationMaps": "Google Maps", + "locationNoneDescription": "No location specified", "locationTextDescription": "Enter location as plain text.", "locationMapsDescription": "Enter Google Maps link.", "googleMapsUrl": "Google Maps URL", @@ -142,10 +144,12 @@ "locationLabel": "Location", "locationPlaceholder": "Enter location", "locationTypeLabel": "Location Type", + "locationNoneOption": "None", "locationTextOption": "Plain Text", "locationMapsOption": "Google Maps", - "locationTextDescription": "Enter location as plain text", - "locationMapsDescription": "Enter Google Maps link", + "locationNoneDescription": "No location specified.", + "locationTextDescription": "Enter location as plain text.", + "locationMapsDescription": "Enter Google Maps link.", "googleMapsUrlLabel": "Google Maps URL", "googleMapsUrlPlaceholder": "https://maps.google.com/...", "typeLabel": "Type", @@ -156,8 +160,8 @@ "visibilityLabel": "Visibility", "publicOption": "🌍 Public", "privateOption": "🔒 Private", - "publicDescription": "Public events are visible to everyone and can be discovered by others", - "privateDescription": "Private events are only visible to you and people you share the link with", + "publicDescription": "Public events are visible to everyone and can be discovered by others.", + "privateDescription": "Private events are only visible to you and people you share the link with.", "creatingEvent": "Creating Event...", "createEventButton": "Create Event" }, diff --git a/src/lib/types.ts b/src/lib/types.ts index 4f7dad7..8b0379d 100644 --- a/src/lib/types.ts +++ b/src/lib/types.ts @@ -1,7 +1,7 @@ export type EventType = 'limited' | 'unlimited'; export type EventVisibility = 'public' | 'private'; export type ActionType = 'add' | 'remove'; -export type LocationType = 'text' | 'maps'; +export type LocationType = 'none' | 'text' | 'maps'; export interface Event { id: string; diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index 888524a..69525f2 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -25,7 +25,7 @@

{t('home.whyCactoideTitle')}*?🌵 + >

{t('home.whyCactoideDescription')} diff --git a/src/routes/create/+page.server.ts b/src/routes/create/+page.server.ts index 4f935f6..d8d0d56 100644 --- a/src/routes/create/+page.server.ts +++ b/src/routes/create/+page.server.ts @@ -21,7 +21,7 @@ export const actions: Actions = { const date = formData.get('date') as string; const time = formData.get('time') as string; const location = formData.get('location') as string; - const locationType = formData.get('location_type') as 'text' | 'maps'; + const locationType = formData.get('location_type') as 'none' | 'text' | 'maps'; const locationUrl = formData.get('location_url') as string; const type = formData.get('type') as 'limited' | 'unlimited'; const attendeeLimit = formData.get('attendee_limit') as string; @@ -34,8 +34,8 @@ export const actions: Actions = { if (!name?.trim()) missingFields.push('name'); if (!date) missingFields.push('date'); if (!time) missingFields.push('time'); - if (!location?.trim()) missingFields.push('location'); if (!locationType) missingFields.push('location_type'); + if (locationType === 'text' && !location?.trim()) missingFields.push('location'); if (locationType === 'maps' && !locationUrl?.trim()) missingFields.push('location_url'); if (!userId) missingFields.push('userId'); @@ -99,7 +99,7 @@ export const actions: Actions = { name: name.trim(), date: date, time: time, - location: location.trim(), + location: location?.trim() || '', locationType: locationType, locationUrl: locationType === 'maps' ? locationUrl?.trim() : null, type: type, diff --git a/src/routes/create/+page.svelte b/src/routes/create/+page.svelte index eb8440c..ba5b7e3 100644 --- a/src/routes/create/+page.svelte +++ b/src/routes/create/+page.svelte @@ -11,7 +11,7 @@ date: '', time: '', location: '', - location_type: 'text', + location_type: 'none', location_url: '', type: 'unlimited', attendee_limit: undefined, @@ -50,7 +50,10 @@ const handleLocationTypeChange = (locationType: LocationType) => { eventData.location_type = locationType; - if (locationType === 'text') { + if (locationType === 'none') { + eventData.location = ''; + eventData.location_url = ''; + } else if (locationType === 'text') { eventData.location_url = ''; eventData.location = ''; } else { @@ -70,7 +73,7 @@

-
+

{t('create.formTitle')}

@@ -168,7 +171,17 @@ {t('create.locationTypeLabel')} {t('common.required')} -
+
+
- -
- - {#if eventData.location_type === 'text'} - - {:else} - - {/if} - {#if errors.location} -

{errors.location}

- {/if} - {#if errors.location_url} -

{errors.location_url}

- {/if} -
+ + {#if eventData.location_type !== 'none'} +
+ + {#if eventData.location_type === 'text'} + + {:else} + + {/if} + {#if errors.location} +

{errors.location}

+ {/if} + {#if errors.location_url} +

{errors.location_url}

+ {/if} +
+ {/if}
@@ -274,7 +291,7 @@
-

+

{eventData.visibility === 'public' ? t('create.publicDescription') : t('create.privateDescription')} @@ -342,7 +359,7 @@

{:else if event} -
+
@@ -136,7 +136,7 @@
- +
@@ -155,14 +155,16 @@
- {#if event.location_type === 'maps' && event.location_url} + {#if event.location_type === 'none'} +

N/A

+ {:else if event.location_type === 'maps' && event.location_url} - {event.location} + {t('create.locationMapsOption')} {:else}

{event.location}

diff --git a/src/routes/event/[id]/edit/+page.server.ts b/src/routes/event/[id]/edit/+page.server.ts index fee09a7..39febb4 100644 --- a/src/routes/event/[id]/edit/+page.server.ts +++ b/src/routes/event/[id]/edit/+page.server.ts @@ -53,7 +53,7 @@ export const actions: Actions = { const date = formData.get('date') as string; const time = formData.get('time') as string; const location = formData.get('location') as string; - const locationType = formData.get('location_type') as 'text' | 'maps'; + const locationType = formData.get('location_type') as 'none' | 'text' | 'maps'; const locationUrl = formData.get('location_url') as string; const type = formData.get('type') as 'limited' | 'unlimited'; const attendeeLimit = formData.get('attendee_limit') as string; @@ -65,8 +65,8 @@ export const actions: Actions = { if (!name?.trim()) missingFields.push('name'); if (!date) missingFields.push('date'); if (!time) missingFields.push('time'); - if (!location?.trim()) missingFields.push('location'); if (!locationType) missingFields.push('location_type'); + if (locationType === 'text' && !location?.trim()) missingFields.push('location'); if (locationType === 'maps' && !locationUrl?.trim()) missingFields.push('location_url'); if (missingFields.length > 0) { @@ -132,7 +132,7 @@ export const actions: Actions = { name: name.trim(), date: date, time: time, - location: location.trim(), + location: location?.trim() || '', locationType: locationType, locationUrl: locationType === 'maps' ? locationUrl?.trim() : null, type: type, diff --git a/src/routes/event/[id]/edit/+page.svelte b/src/routes/event/[id]/edit/+page.svelte index 680b62f..0bdd782 100644 --- a/src/routes/event/[id]/edit/+page.svelte +++ b/src/routes/event/[id]/edit/+page.svelte @@ -12,7 +12,7 @@ date: data.event.date, time: data.event.time, location: data.event.location, - location_type: data.event.locationType || 'text', + location_type: data.event.locationType || 'none', location_url: data.event.locationUrl || '', type: data.event.type, attendee_limit: data.event.attendeeLimit, @@ -53,7 +53,10 @@ const handleLocationTypeChange = (locationType: LocationType) => { eventData.location_type = locationType; - if (locationType === 'text') { + if (locationType === 'none') { + eventData.location = ''; + eventData.location_url = ''; + } else if (locationType === 'text') { eventData.location_url = ''; eventData.location = ''; } else { @@ -73,7 +76,7 @@
-
+
@@ -169,7 +172,17 @@ {t('create.locationTypeLabel')} {t('common.required')} -
+
+
- -
- - {#if eventData.location_type === 'text'} - - {:else} - - {/if} - {#if errors.location} -

{errors.location}

- {/if} - {#if errors.location_url} -

{errors.location_url}

- {/if} -
+ + {#if eventData.location_type !== 'none'} +
+ + {#if eventData.location_type === 'text'} + + {:else} + + {/if} + {#if errors.location} +

{errors.location}

+ {/if} + {#if errors.location_url} +

{errors.location_url}

+ {/if} +
+ {/if}