From e0204aeeee0f7b00bc2270c6f4373e409d091034 Mon Sep 17 00:00:00 2001 From: Paul Nothaft Date: Thu, 1 Jan 2026 23:52:07 +0100 Subject: [PATCH] Add planning document for optional event contact fields Addresses GitHub issue #60 - making customer name, customer email, and admin email fields optional when creating events. This feature adds three new admin settings: - event_require_customer_name (default: true) - event_require_customer_email (default: true) - event_require_admin_email (default: true) Implementation includes: - Database migration for new app_settings entries - Backend conditional validation in event creation - Frontend settings UI with toggle switches - Dynamic form validation based on settings - Warning messages for email-related settings - Graceful handling of empty contact fields Maintains backward compatibility with default behavior unchanged. --- docs/feature-optional-event-fields.md | 564 ++++++++++++++++++++++++++ 1 file changed, 564 insertions(+) create mode 100644 docs/feature-optional-event-fields.md diff --git a/docs/feature-optional-event-fields.md b/docs/feature-optional-event-fields.md new file mode 100644 index 00000000..4d9c8d7a --- /dev/null +++ b/docs/feature-optional-event-fields.md @@ -0,0 +1,564 @@ +# Feature: Optional Event Contact Fields + +## Overview + +This feature adds a settings option to configure whether client/customer contact information (name, email) and admin email are required fields when creating new events. This addresses the needs of users who don't use the email/SMTP functionality and find these mandatory fields unnecessary. + +**GitHub Issue:** [#60](https://github.com/the-luap/picpeak/issues/60) + +--- + +## Problem Statement + +Currently, when creating a new event, the following fields are **mandatory**: +- Customer Name +- Customer Email +- Admin Email + +For users who: +- Don't use SMTP/email functionality +- Share galleries via manual link distribution +- Self-host for personal use without client management + +These required fields create unnecessary friction and force users to enter placeholder data. + +--- + +## User Story + +As an administrator, I want to configure whether client contact information is required when creating events, so that I can streamline event creation when I don't need email functionality. + +--- + +## Feature Requirements + +### 1. New Settings Options + +Add three new settings to the Admin Settings page under a new section "Event Creation": + +| Setting | Label | Type | Default | Description | +|---------|-------|------|---------|-------------| +| `event_require_customer_name` | Require customer name | Toggle | `true` | When enabled, customer name is required for new events | +| `event_require_customer_email` | Require customer email | Toggle | `true` | When enabled, customer email is required for new events | +| `event_require_admin_email` | Require admin email | Toggle | `true` | When enabled, admin email is required for new events | + +### 2. Settings UI Location + +**Path:** Admin Panel → Settings → Event Creation (new section) + +``` +┌─────────────────────────────────────────────────────────────┐ +│ Settings │ +├─────────────────────────────────────────────────────────────┤ +│ ▼ General │ +│ ▼ Gallery Display │ +│ ▼ Storage │ +│ ▼ Event Creation ← NEW SECTION │ +│ ┌─────────────────────────────────────────────────────┐ │ +│ │ Required Fields │ │ +│ │ │ │ +│ │ Configure which contact fields are required when │ │ +│ │ creating new events. │ │ +│ │ │ │ +│ │ [✓] Require customer name │ │ +│ │ Customer name must be provided for new events │ │ +│ │ │ │ +│ │ [✓] Require customer email │ │ +│ │ Customer email must be provided for new events │ │ +│ │ ⚠️ Required for sending gallery invitations │ │ +│ │ │ │ +│ │ [✓] Require admin email │ │ +│ │ Admin email must be provided for new events │ │ +│ │ ⚠️ Required for receiving event notifications │ │ +│ └─────────────────────────────────────────────────────┘ │ +│ ▼ Security │ +│ ▼ Email/SMTP │ +└─────────────────────────────────────────────────────────────┘ +``` + +### 3. Event Creation Form Updates + +The event creation form (`/admin/events/new`) should: + +1. **Fetch settings** on load to determine field requirements +2. **Conditionally apply validation** based on settings +3. **Update field labels** to show optional indicator when not required +4. **Remove asterisk (*)** from non-required fields + +#### Field Display Logic + +| Setting Value | Field Label | Validation | Placeholder | +|---------------|-------------|------------|-------------| +| `true` (required) | "Customer Name *" | Required | "Enter customer name" | +| `false` (optional) | "Customer Name (optional)" | Optional | "Enter customer name (optional)" | + +### 4. Warning Messages + +When disabling email-related required fields, show informational warnings: + +**When disabling "Require customer email":** +> Note: Without a customer email, you won't be able to send gallery invitation emails automatically. You'll need to share gallery links manually. + +**When disabling "Require admin email":** +> Note: Without an admin email, you won't receive event notifications such as expiration reminders or guest feedback alerts. + +### 5. Backward Compatibility + +- Existing events with empty contact fields remain valid +- Default values maintain current behavior (`true` = required) +- Settings changes only affect new event creation + +--- + +## Technical Specification + +### 6. Database Changes + +#### 6.1 Settings Table Entries + +Add new rows to `app_settings` table: + +```sql +INSERT INTO app_settings (key, value, category, description) VALUES +('event_require_customer_name', 'true', 'events', 'Require customer name when creating events'), +('event_require_customer_email', 'true', 'events', 'Require customer email when creating events'), +('event_require_admin_email', 'true', 'events', 'Require admin email when creating events'); +``` + +#### 6.2 Migration File + +**File:** `/backend/migrations/core/YYYYMMDDHHMMSS_add_optional_event_fields_settings.js` + +```javascript +exports.up = function(knex) { + return knex('app_settings').insert([ + { + key: 'event_require_customer_name', + value: 'true', + category: 'events', + description: 'Require customer name when creating events' + }, + { + key: 'event_require_customer_email', + value: 'true', + category: 'events', + description: 'Require customer email when creating events' + }, + { + key: 'event_require_admin_email', + value: 'true', + category: 'events', + description: 'Require admin email when creating events' + } + ]); +}; + +exports.down = function(knex) { + return knex('app_settings') + .whereIn('key', [ + 'event_require_customer_name', + 'event_require_customer_email', + 'event_require_admin_email' + ]) + .del(); +}; +``` + +--- + +### 7. API Changes + +#### 7.1 Settings Endpoint (Existing) + +The existing settings endpoints should already handle these new settings: + +**GET `/api/admin/settings`** - Returns all settings including new ones +**PUT `/api/admin/settings`** - Updates settings including new ones + +#### 7.2 Public Settings Endpoint + +**GET `/api/public/settings`** - Should include event field requirements for frontend validation + +Add to public settings response: +```json +{ + "event_require_customer_name": true, + "event_require_customer_email": true, + "event_require_admin_email": true +} +``` + +#### 7.3 Event Creation Validation Update + +**File:** `/backend/src/routes/adminEvents.js` + +Update the event creation endpoint to conditionally validate fields: + +```javascript +// Before (current) +if (!customer_name) { + return res.status(400).json({ error: 'Customer name is required' }); +} + +// After (with settings check) +const settings = await getSettings(); +if (settings.event_require_customer_name && !customer_name) { + return res.status(400).json({ error: 'Customer name is required' }); +} +``` + +--- + +### 8. Backend Implementation + +#### 8.1 Update Event Validation + +**File:** `/backend/src/routes/adminEvents.js` + +```javascript +// POST /api/admin/events +router.post('/', adminAuth, async (req, res) => { + try { + const { + event_name, + event_type, + event_date, + customer_name, + customer_email, + admin_email, + // ... other fields + } = req.body; + + // Get settings for validation + const settings = await db('app_settings') + .whereIn('key', [ + 'event_require_customer_name', + 'event_require_customer_email', + 'event_require_admin_email' + ]) + .select('key', 'value'); + + const settingsMap = settings.reduce((acc, s) => { + acc[s.key] = s.value === 'true'; + return acc; + }, {}); + + // Conditional validation + const errors = []; + + if (!event_name) { + errors.push('Event name is required'); + } + + if (settingsMap.event_require_customer_name && !customer_name) { + errors.push('Customer name is required'); + } + + if (settingsMap.event_require_customer_email && !customer_email) { + errors.push('Customer email is required'); + } + + if (settingsMap.event_require_admin_email && !admin_email) { + errors.push('Admin email is required'); + } + + if (errors.length > 0) { + return res.status(400).json({ errors }); + } + + // Continue with event creation... + } catch (error) { + // Error handling... + } +}); +``` + +#### 8.2 Add Settings to Public Endpoint + +**File:** `/backend/src/routes/publicSettings.js` + +```javascript +// Add to public settings response +const eventFieldSettings = await db('app_settings') + .whereIn('key', [ + 'event_require_customer_name', + 'event_require_customer_email', + 'event_require_admin_email' + ]) + .select('key', 'value'); + +// Include in response +response.eventFieldRequirements = eventFieldSettings.reduce((acc, s) => { + acc[s.key] = s.value === 'true'; + return acc; +}, {}); +``` + +--- + +### 9. Frontend Implementation + +#### 9.1 Settings Page Update + +**File:** `/frontend/src/components/admin/Settings.tsx` (or similar) + +Add new section for Event Creation settings: + +```tsx +// New section component +const EventCreationSettings: React.FC = () => { + const { settings, updateSetting } = useSettings(); + + return ( + }> + +

+ Configure which contact fields are required when creating new events. +

+ + updateSetting('event_require_customer_name', value)} + /> + + updateSetting('event_require_customer_email', value)} + warning="Required for sending gallery invitations" + /> + + updateSetting('event_require_admin_email', value)} + warning="Required for receiving event notifications" + /> +
+
+ ); +}; +``` + +#### 9.2 Event Creation Form Update + +**File:** `/frontend/src/components/admin/EventForm.tsx` (or similar) + +```tsx +interface EventFormProps { + // ... existing props +} + +const EventForm: React.FC = () => { + const { settings } = usePublicSettings(); + + const isCustomerNameRequired = settings?.event_require_customer_name ?? true; + const isCustomerEmailRequired = settings?.event_require_customer_email ?? true; + const isAdminEmailRequired = settings?.event_require_admin_email ?? true; + + // Form validation schema (using Zod or Yup) + const validationSchema = useMemo(() => { + return z.object({ + event_name: z.string().min(1, 'Event name is required'), + customer_name: isCustomerNameRequired + ? z.string().min(1, 'Customer name is required') + : z.string().optional(), + customer_email: isCustomerEmailRequired + ? z.string().email('Valid email required') + : z.string().email().optional().or(z.literal('')), + admin_email: isAdminEmailRequired + ? z.string().email('Valid email required') + : z.string().email().optional().or(z.literal('')), + // ... other fields + }); + }, [isCustomerNameRequired, isCustomerEmailRequired, isAdminEmailRequired]); + + return ( +
+ {/* Customer Name Field */} + + + + + {/* Customer Email Field */} + + + + + {/* Admin Email Field */} + + + + + {/* ... rest of form */} +
+ ); +}; +``` + +#### 9.3 Update Types + +**File:** `/frontend/src/types/settings.ts` + +```typescript +interface PublicSettings { + // ... existing settings + event_require_customer_name: boolean; + event_require_customer_email: boolean; + event_require_admin_email: boolean; +} +``` + +--- + +### 10. Email Functionality Impact + +When contact fields are optional and left empty: + +| Field Empty | Impact | +|-------------|--------| +| Customer Email | Cannot send invitation email, "Send Email" button disabled | +| Admin Email | No notifications sent, warning shown in event details | +| Customer Name | Email salutation uses generic greeting | + +#### 10.1 UI Adjustments for Empty Fields + +**Event Details Page:** +- If no customer email: Hide/disable "Send Invitation Email" button +- If no admin email: Show info message "No admin email configured for notifications" + +**Event Creation Success:** +- If customer email provided: "Event created. Send invitation email?" +- If no customer email: "Event created. Share the gallery link manually." + +--- + +## Implementation Checklist + +### Phase 1: Backend +- [ ] Create database migration for new settings +- [ ] Run migration to add default settings +- [ ] Update event creation endpoint with conditional validation +- [ ] Add new settings to public settings endpoint +- [ ] Update event update endpoint with same validation logic +- [ ] Write unit tests for conditional validation + +### Phase 2: Frontend - Settings +- [ ] Add "Event Creation" section to Settings page +- [ ] Create toggle components for each setting +- [ ] Add warning messages for email-related settings +- [ ] Test settings save/load functionality + +### Phase 3: Frontend - Event Form +- [ ] Update EventForm to fetch settings +- [ ] Implement conditional validation schema +- [ ] Update field labels based on requirements +- [ ] Update placeholder text +- [ ] Test form validation with various settings combinations + +### Phase 4: UI Polish +- [ ] Update event details page for empty contact fields +- [ ] Disable email buttons when no email provided +- [ ] Add informational messages where appropriate +- [ ] Update any tooltips or help text + +### Phase 5: Testing +- [ ] Test with all settings enabled (default behavior) +- [ ] Test with all settings disabled +- [ ] Test with mixed settings +- [ ] Test event editing with changed settings +- [ ] End-to-end testing + +--- + +## Test Scenarios + +| # | Settings | Action | Expected Result | +|---|----------|--------|-----------------| +| 1 | All required (default) | Create event without customer name | Validation error | +| 2 | All required | Create event with all fields | Success | +| 3 | Name optional | Create event without customer name | Success | +| 4 | Email optional | Create event without customer email | Success, email button disabled | +| 5 | All optional | Create event with only event name/date | Success | +| 6 | Mixed | Edit settings, create event | Respects new settings | + +--- + +## Acceptance Criteria + +1. ✅ Three new toggle settings available in Admin Settings +2. ✅ Settings persist after save and page refresh +3. ✅ Event creation form respects settings for field requirements +4. ✅ Field labels update to show "(optional)" when not required +5. ✅ Backend validates according to settings +6. ✅ Warning messages shown when disabling email-related fields +7. ✅ Email functionality gracefully handles empty contact fields +8. ✅ Default behavior unchanged (all fields required) +9. ✅ Existing events unaffected by settings changes + +--- + +## Security Considerations + +1. Settings changes require admin authentication +2. Public settings endpoint only exposes necessary field requirements +3. No sensitive data exposed through settings + +--- + +## Related Files + +### Backend +- `/backend/src/routes/adminEvents.js` - Event creation/update +- `/backend/src/routes/adminSettings.js` - Settings management +- `/backend/src/routes/publicSettings.js` - Public settings API +- `/backend/migrations/core/` - Database migrations + +### Frontend +- `/frontend/src/components/admin/Settings.tsx` - Settings page +- `/frontend/src/components/admin/EventForm.tsx` - Event creation form +- `/frontend/src/components/admin/EventDetails.tsx` - Event detail page +- `/frontend/src/services/settingsService.ts` - Settings API service +- `/frontend/src/hooks/useSettings.ts` - Settings hook + +--- + +## Future Enhancements + +1. **Field-level defaults**: Set default values for optional fields +2. **Conditional fields**: Show/hide fields based on other selections +3. **Custom required fields**: Allow adding custom required fields +4. **Per-event-type settings**: Different requirements for wedding vs corporate