import React from 'react'; import { useNavigate, useParams } from 'react-router-dom'; import { useTranslation } from 'react-i18next'; import { CalendarDays, ChevronDown, MapPin } from 'lucide-react'; import { YStack, XStack } from '@tamagui/stacks'; import { SizableText as Text } from '@tamagui/text'; import { Switch } from '@tamagui/switch'; import { MobileShell } from './components/MobileShell'; import { MobileCard, CTAButton } from './components/Primitives'; import { createEvent, getEvent, updateEvent, getEventTypes, TenantEvent, TenantEventType } from '../api'; import { resolveEventSlugAfterUpdate } from './eventFormNavigation'; import { adminPath } from '../constants'; import { isAuthError } from '../auth/tokens'; import { getApiValidationMessage } from '../lib/apiError'; import toast from 'react-hot-toast'; type FormState = { name: string; date: string; eventTypeId: number | null; description: string; location: string; published: boolean; autoApproveUploads: boolean; tasksEnabled: boolean; }; export default function MobileEventFormPage() { const { slug: slugParam } = useParams<{ slug?: string }>(); const slug = slugParam ?? null; const isEdit = Boolean(slug); const navigate = useNavigate(); const { t } = useTranslation(['management', 'common']); const [form, setForm] = React.useState({ name: '', date: '', eventTypeId: null, description: '', location: '', published: false, autoApproveUploads: true, tasksEnabled: true, }); const [eventTypes, setEventTypes] = React.useState([]); const [typesLoading, setTypesLoading] = React.useState(false); const [loading, setLoading] = React.useState(isEdit); const [saving, setSaving] = React.useState(false); const [error, setError] = React.useState(null); React.useEffect(() => { if (!slug) return; (async () => { setLoading(true); try { const data = await getEvent(slug); setForm({ name: renderName(data.name), date: toDateTimeLocal(data.event_date), eventTypeId: data.event_type_id ?? data.event_type?.id ?? null, description: typeof data.description === 'string' ? data.description : '', location: resolveLocation(data), published: data.status === 'published', autoApproveUploads: (data.settings?.guest_upload_visibility as string | undefined) === 'immediate', tasksEnabled: (data.settings?.engagement_mode as string | undefined) !== 'photo_only' && (data.engagement_mode as string | undefined) !== 'photo_only', }); setError(null); } catch (err) { if (!isAuthError(err)) { setError(getApiErrorMessage(err, t('events.errors.loadFailed', 'Event konnte nicht geladen werden.'))); } } finally { setLoading(false); } })(); }, [slug, t, isEdit]); React.useEffect(() => { (async () => { setTypesLoading(true); try { const types = await getEventTypes(); setEventTypes(types); // Default to first type if none set if (!form.eventTypeId && types.length) { setForm((prev) => ({ ...prev, eventTypeId: types[0].id })); } } catch { // silently ignore; fallback to null } finally { setTypesLoading(false); } })(); }, []); async function handleSubmit() { setSaving(true); setError(null); try { if (isEdit && slug) { const updated = await updateEvent(slug, { name: form.name, event_date: form.date || undefined, event_type_id: form.eventTypeId ?? undefined, status: form.published ? 'published' : 'draft', settings: { location: form.location, guest_upload_visibility: form.autoApproveUploads ? 'immediate' : 'review', engagement_mode: form.tasksEnabled ? 'tasks' : 'photo_only', }, }); const nextSlug = resolveEventSlugAfterUpdate(slug, updated); navigate(adminPath(`/mobile/events/${nextSlug}`)); } else { const payload = { name: form.name || t('eventForm.fields.name.fallback', 'Event'), slug: `${Date.now()}`, event_type_id: form.eventTypeId ?? undefined, event_date: form.date || undefined, status: (form.published ? 'published' : 'draft') as const, settings: { location: form.location, guest_upload_visibility: form.autoApproveUploads ? 'immediate' : 'review', engagement_mode: form.tasksEnabled ? 'tasks' : 'photo_only', }, }; const { event } = await createEvent(payload as any); navigate(adminPath(`/mobile/events/${event.slug}`)); } } catch (err) { if (!isAuthError(err)) { const message = getApiValidationMessage(err, t('eventForm.errors.saveFailed', 'Event could not be saved.')); setError(message); toast.error(message); } } finally { setSaving(false); } } return ( navigate(-1)} > {error ? ( {error} ) : null} setForm((prev) => ({ ...prev, name: e.target.value }))} placeholder={t('eventForm.fields.name.placeholder', 'e.g. Summer Party 2025')} style={inputStyle} /> setForm((prev) => ({ ...prev, date: e.target.value }))} style={{ ...inputStyle, flex: 1 }} /> {typesLoading ? ( {t('eventForm.fields.type.loading', 'Loading event types…')} ) : eventTypes.length === 0 ? ( {t('eventForm.fields.type.empty', 'No event types available yet. Please add one in the admin area.')} ) : ( )}