feat: optional customer phone field gated by global toggle (#322)
Adds a `customer_phone` column on events plus an `event_phone_field_enabled` admin setting (default off) that surfaces the input in the create-event and event-detail forms. Designed for downstream automation tooling — once exposed via the upcoming public API, n8n / similar can pick it up to deliver gallery links over WhatsApp, SMS, etc. - Migration 080 adds the column + seeds the setting as false. Existing deployments see no UI change unless the admin opts in via Settings → Events. - Backend strips the field server-side when the toggle is off (defence in depth against form bypass). - Frontend renders the input only when the public-settings flag is true; always optional even then. - publicSettings + EventSettings types extended; CreateEventPage and EventDetailsPage wired to read the toggle and submit the value.
This commit is contained in:
@@ -52,6 +52,7 @@ export interface EventSettings {
|
||||
event_require_expiration: boolean;
|
||||
event_default_require_password: boolean;
|
||||
gallery_show_filter_bar: boolean;
|
||||
event_phone_field_enabled: boolean;
|
||||
}
|
||||
|
||||
export interface SeoSettings {
|
||||
@@ -127,7 +128,8 @@ export function useSettingsState() {
|
||||
event_require_event_date: true,
|
||||
event_require_expiration: true,
|
||||
event_default_require_password: true,
|
||||
gallery_show_filter_bar: true
|
||||
gallery_show_filter_bar: true,
|
||||
event_phone_field_enabled: false
|
||||
});
|
||||
|
||||
// SEO settings state
|
||||
@@ -212,7 +214,8 @@ export function useSettingsState() {
|
||||
event_require_event_date: toBoolean(settings.event_require_event_date, true),
|
||||
event_require_expiration: toBoolean(settings.event_require_expiration, true),
|
||||
event_default_require_password: toBoolean(settings.event_default_require_password, true),
|
||||
gallery_show_filter_bar: toBoolean(settings.gallery_show_filter_bar, true)
|
||||
gallery_show_filter_bar: toBoolean(settings.gallery_show_filter_bar, true),
|
||||
event_phone_field_enabled: toBoolean(settings.event_phone_field_enabled, false)
|
||||
});
|
||||
|
||||
setSeoSettings({
|
||||
|
||||
@@ -187,6 +187,25 @@ export const EventsTab: React.FC<EventsTabProps> = ({
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label className="flex items-start gap-3">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={eventSettings.event_phone_field_enabled}
|
||||
onChange={(e) => setEventSettings(prev => ({ ...prev, event_phone_field_enabled: e.target.checked }))}
|
||||
className="mt-1 w-4 h-4 text-primary-600 rounded focus:ring-primary-500"
|
||||
/>
|
||||
<div>
|
||||
<span className="text-sm font-medium text-neutral-700 dark:text-neutral-300">
|
||||
{t('settings.events.enablePhoneField', 'Enable phone number field')}
|
||||
</span>
|
||||
<p className="text-xs text-neutral-500 dark:text-neutral-400 mt-1">
|
||||
{t('settings.events.enablePhoneFieldHelp', 'Adds an optional phone number input to the event form. Useful for downstream automations like WhatsApp delivery via n8n. Always optional even when enabled.')}
|
||||
</p>
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mt-6">
|
||||
|
||||
Reference in New Issue
Block a user