feat: add optional event date and expiration settings

Add global settings to make event_date and expiration optional when
creating galleries. This supports non-event use cases like portraits,
corporate shoots, etc.

New features:
- Settings toggles in Settings → Event Creation tab
- "Require event date" checkbox with warning about random URL identifiers
- "Require expiration date" checkbox with warning about manual archiving
- Galleries without date use random hex suffix in slug (e.g. portrait-smith-a1b2c3)
- Galleries without expiration never expire (stay active until archived)

Backend changes:
- New migration for settings and nullable columns
- Conditional validation based on settings
- Updated slug generation with random suffix fallback
- Updated expiration checker to skip null expires_at
- Updated gallery access control for null expiration

Frontend changes:
- New checkboxes in EventsTab with warnings
- Conditional event date field (shows optional label)
- No Expiration message when expiration disabled
- Updated types for nullable event_date and expires_at

Closes #118
This commit is contained in:
Paul Nothaft
2026-01-16 09:39:32 +01:00
parent 3e69579f5a
commit 2151147f2d
13 changed files with 226 additions and 61 deletions
@@ -49,6 +49,8 @@ export interface EventSettings {
event_require_customer_name: boolean;
event_require_customer_email: boolean;
event_require_admin_email: boolean;
event_require_event_date: boolean;
event_require_expiration: boolean;
}
export function useSettingsState() {
@@ -109,7 +111,9 @@ export function useSettingsState() {
const [eventSettings, setEventSettings] = useState<EventSettings>({
event_require_customer_name: true,
event_require_customer_email: true,
event_require_admin_email: true
event_require_admin_email: true,
event_require_event_date: true,
event_require_expiration: true
});
// Account form state
@@ -178,7 +182,9 @@ export function useSettingsState() {
setEventSettings({
event_require_customer_name: toBoolean(settings.event_require_customer_name, true),
event_require_customer_email: toBoolean(settings.event_require_customer_email, true),
event_require_admin_email: toBoolean(settings.event_require_admin_email, true)
event_require_admin_email: toBoolean(settings.event_require_admin_email, true),
event_require_event_date: toBoolean(settings.event_require_event_date, true),
event_require_expiration: toBoolean(settings.event_require_expiration, true)
});
}
}, [settings, i18n]);