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.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 @@
{errors.location}
- {/if} - {#if errors.location_url} -{errors.location_url}
- {/if} -{errors.location}
+ {/if} + {#if errors.location_url} +{errors.location_url}
+ {/if} ++
{eventData.visibility === 'public' ? t('create.publicDescription') : t('create.privateDescription')} @@ -342,7 +359,7 @@
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 @@{errors.location}
- {/if} - {#if errors.location_url} -{errors.location_url}
- {/if} -{errors.location}
+ {/if} + {#if errors.location_url} +{errors.location_url}
+ {/if} +