This document provides a comprehensive specification for the document generation modal interface in the Agoria Social Elections management system. The modal facilitates document creation for various Belgian labor law forms (X-series) and announcements related to employee elections.
- Tab: Documenten (Documents)
- Button: "Document" with Plus icon
- Position: Top-right of the documents list, next to the search bar
- Visual: Blue button with white text (
bg-agoria-blue)
- Default: Blue background, white text with Plus icon
- Hover: Darker blue (
bg-agoria-dark-blue) - Focus: Blue ring around button for accessibility
- Disabled: Not applicable (always enabled)
- Width: Max 768px (2xl)
- Height: Max 90vh (90% of viewport height)
- Position: Centered on screen
- Background: Full-screen overlay with 50% opacity black backdrop
- Z-index: 50 (ensures it appears above all content)
Layout: Horizontal layout with icon, title, subtitle, and close button
Components:
-
Icon Container
- Light blue background (
bg-agoria-blue bg-opacity-10) - FileText icon (24x24px)
- Rounded corners (8px)
- Light blue background (
-
Title Area
- Primary: "Generate Document" (text-xl, bold)
- Secondary: Business unit name (text-sm, gray)
-
Close Button
- X icon (24x24px)
- Gray color, transitions to darker on hover
- Position: Absolute right
- Keyboard accessible (Escape key closes modal)
Styling:
- White background
- Bottom border (gray-200)
- Padding: 1.5rem (24px)
- Stays at top when scrolling (sticky positioning)
Position: Below header, also sticky during scroll
Components:
-
Label
- Text: "Select Document Type"
- Required indicator: Red asterisk (*)
- Font: Medium weight, small size
-
Dropdown Select
- Full width
- Placeholder: "Choose an event type..."
- Options: 16 document types (see section 3)
- Border: Gray with focus ring in blue
- Height: Comfortable (48px)
- Font size: 14px
-
Help Text
- Below dropdown
- Text: "Select the type of document you want to generate"
- Color: Gray-500
- Font size: 12px
Styling:
- White background
- Bottom border separator
- Padding: 1.5rem
- Z-index: 10 (appears above content when scrolling)
Function: Displays context or form preview
Default State (No selection):
- Empty state illustration
- FileText icon (48x48px) in gray
- Message: "Please select a document type to continue"
- Light gray background card
After Selection:
- Transitions to selected document form
- Form appears with smooth animation (50ms delay)
Position: Bottom of modal
Components:
- Cancel Button
- Text: "Cancel"
- Style: Gray border, gray text
- Action: Closes modal without saving
Styling:
- Light gray background (
bg-gray-50) - Top border separator
- Padding: 1rem vertical, 1.5rem horizontal
- Buttons aligned to right
| ID | Document Type | Display Name |
|---|---|---|
| 1 | X-60 | Bericht X-60 |
| 2 | X-35 | Bericht X-35 |
| 4 | X-28 | Bericht X-28 |
| 6 | Aanplakking | Aanplakkingsbericht verkiezingsdatum |
| 8 | X-14 | Bericht X-14 |
| 10 | X-28-Modified | Bericht X-28 (gewijzigd) |
| 12 | Kandidatenlijsten | Kandidatenlijsten aanplakken |
| 16 | Tweede-Aanplakking | Tweede aanplakking kandidatenlijsten |
| 17 | Akkoord-Stemmen | Akkoord stemmen brief |
| 18 | Aanplakking-Samenstelling | Aanplakking samenstelling stembureau |
| 19 | X-23 | Bericht X-23 |
| 20 | X-24 | Bericht X-24 |
| 21 | X-25 | Bericht X-25 |
| 22 | X-26 | Bericht X-26 |
| 23 | X-27-1 | Bericht X-27 (Deel 1) |
| 24 | X-27-2 | Bericht X-27 (Deel 2) |
| 25 | X-27-3 | Bericht X-27 (Deel 3) |
| 26 | X-29 | Bericht X-29 |
- Type: Multi-select dropdown
- Options: Nederlands (NL), Français (FR), English (EN)
- Functionality: Allows generating document in multiple languages simultaneously
- Validation: At least one language must be selected
- Visual: Custom multi-select component with checkboxes
- Type: Dropdown
- Label: "Orgaan"
- Options:
- Comité voor Preventie en Bescherming op het Werk (CPBW)
- Ondernemingsraad (OR)
- Validation: Required field
- Default: Empty (user must select)
- Type: Dropdown
- Label: "Output"
- Options: Word, PDF, Email
- Validation: Required field
- Default: PDF
- Type: Date picker
- Format: DD/MM/YYYY
- Label: Context-specific (e.g., "Datum")
- Validation: Valid date, may require future date
- Visual: Native date input with calendar icon
- Type: Text input / Textarea
- Examples:
- Beschrijving TBE (Description)
- Ondernemingsnummers JE (Enterprise numbers)
- Validation: Character limits, required indicators
- Max length: Varies by field (typically 200-500 characters)
- Type: Expandable sections per language
- Visual:
- Collapsible panels with language flag icons
- Chevron indicators (up/down)
- Language name in header
- Content: Rich text area for each selected language
- Functionality:
- Only shows for selected languages
- Expands/collapses independently
- Auto-removes when language deselected
1. User clicks "Document" button
↓
2. Modal opens with document type selection
↓
3. User selects document type from dropdown
↓
4. Specific form loads (50ms transition)
↓
5. User fills required fields
↓
6. User clicks "Genereren" button
↓
7. Loading state shows (spinner on button)
↓
8. Document generated successfully
↓
9. Success callback fires
↓
10. Modal closes
↓
11. Document list refreshes
↓
12. New document appears in list
1. User clicks "Document" button
↓
2. Modal opens
↓
3. User starts filling form OR just opens modal
↓
4. User clicks "Cancel" button OR "X" close button OR presses Escape
↓
5. Modal closes immediately
↓
6. No data saved
↓
7. Returns to document list
1. User fills form incompletely
↓
2. User clicks "Genereren" button
↓
3. System validates form
↓
4. Error detected (missing required field)
↓
5. Error message appears below field in red
↓
6. Field border turns red
↓
7. Form does not submit
↓
8. User corrects error
↓
9. Error message clears on input change
↓
10. User resubmits
1. User selects Document Type A
↓
2. Form A loads
↓
3. User starts filling Form A
↓
4. User changes dropdown to Document Type B
↓
5. Form A unmounts (50ms)
↓
6. Form B loads (50ms delay)
↓
7. Fresh form appears (previous data lost)
- Trigger: On submit (not on blur to avoid annoying users)
- Visual: Red border + red text error message
- Message Format: "{Field name} is verplicht" (Dutch)
- Position: Below the field
Language Selection:
- Minimum: 1 language
- Error: "Selecteer minimaal één taal"
Date Fields:
- Format: DD/MM/YYYY
- Valid date required
- May require future date depending on context
- Error: "Voer een geldige datum in"
Text Fields:
- Maximum character limits enforced
- Error: "Maximum {X} karakters toegestaan"
- Shows character counter near max
Email Fields (if applicable):
- Valid email format
- Error: "Voer een geldig e-mailadres in"
Numeric Fields:
- Only numbers allowed
- May have min/max constraints
- Error: "Voer een geldig nummer in"
- Error Clearing: Errors clear immediately when user starts correcting
- Success Indication: Green checkmark appears for valid required fields
- Field Focus: Blue ring highlights current field
- Disabled Submit: Button may be disabled until form is valid (optional pattern)
- Trigger: After clicking "Genereren" button
- Button Changes:
- Text changes to "Genereren..." or shows spinner
- Button disabled
- Spinner icon appears
- Duration: Varies (typically 1-3 seconds)
- Overlay: Optional - prevent other interactions
- Action: Modal closes automatically
- Feedback: Parent component refreshes document list
- Optional: Success toast notification (not currently implemented)
- Network Error: Alert dialog with error message
- Validation Error: Inline errors (see section 5)
- Server Error: Alert with user-friendly message
- Retry: User can correct and resubmit
- Tab Order: Natural flow through form fields
- Escape Key: Closes modal
- Enter Key: Submits form (when not in textarea)
- Focus Indicators: Visible blue ring on all interactive elements
- Modal Announcement: Screen reader announces modal opening
- Close Button: "Close modal" aria-label
- Required Fields: Properly marked with aria-required
- Error Messages: Associated with fields via aria-describedby
- Focus Management: Focus moves to modal on open, returns to trigger on close
- Color Contrast: All text meets WCAG AA standards
- Focus Indicators: Minimum 2px visible focus rings
- Error States: Not reliant on color alone (icon + text)
- Font Sizes: Minimum 14px for body text
- Click Targets: Minimum 44x44px for touch targets
<div role="dialog" aria-modal="true" aria-labelledby="modal-title">
<h2 id="modal-title">Generate Document</h2>
<label for="document-type">
Select Document Type <span aria-label="required">*</span>
</label>
<select id="document-type" aria-required="true" aria-invalid="false">
...
</select>
<button aria-label="Close modal">X</button>
</div>- Modal Width: 768px
- Layout: Side-by-side for related fields
- Padding: Generous (24px)
- Font Sizes: Standard (14-16px)
- Modal Width: 90% of viewport
- Layout: Stacked fields
- Padding: Medium (16px)
- Font Sizes: Standard
- Modal Width: 95% of viewport, or full screen
- Layout: Single column, stacked
- Padding: Minimal (12px)
- Font Sizes: Slightly larger for readability (16px)
- Scroll: Full modal scrolls within viewport
- Touch Targets: Minimum 48px height
- Sticky Header: Remains visible on all screen sizes
- Sticky Dropdown: Document type always accessible
- Virtual Keyboard: Modal adjusts when keyboard appears on mobile
- Portrait/Landscape: Layout adapts to orientation
- Target: < 100ms to open
- Optimization: Lazy load specific form components
- Implementation: Only load selected form modal on demand
- Delay: 50ms between form switches
- Purpose: Smooth visual transition, prevent flicker
- User Perception: Feels intentional, not laggy
- Expected Time: 1-3 seconds
- Feedback: Loading spinner on button
- Timeout: 30 seconds (show error if exceeded)
- Empty Required Fields: Inline validation messages
- Invalid Formats: Specific format guidance
- Recovery: Clear errors on correction
- Network Failure: "Unable to generate document. Please check your connection."
- Server Error: "Something went wrong. Please try again."
- Timeout: "Request took too long. Please try again."
- Retry Mechanism: User can resubmit after error
- Duplicate Generation: Allow (track version in metadata)
- Concurrent Users: No conflict (separate business units)
- Browser Compatibility: Tested on modern browsers (Chrome, Firefox, Safari, Edge)
- Primary Blue:
#0066CC(agoria-blue) - Dark Blue:
#004C99(agoria-dark-blue) - Success Green:
#10B981 - Error Red:
#EF4444 - Warning Yellow:
#F59E0B - Neutral Gray:
#6B7280 - Light Gray:
#F3F4F6 - White:
#FFFFFF
- Font Family: System font stack (Inter, SF Pro, Roboto)
- Headings: Alegreya Sans (custom)
- Body Text: 14px regular
- Labels: 14px medium weight
- Help Text: 12px regular
- Buttons: 14px medium weight
- Extra Small: 0.5rem (8px)
- Small: 0.75rem (12px)
- Medium: 1rem (16px)
- Large: 1.5rem (24px)
- Extra Large: 2rem (32px)
- Small: 0.375rem (6px)
- Medium: 0.5rem (8px)
- Large: 0.75rem (12px)
- Small:
0 1px 2px 0 rgb(0 0 0 / 0.05) - Medium:
0 4px 6px -1px rgb(0 0 0 / 0.1) - Large:
0 10px 15px -3px rgb(0 0 0 / 0.1) - Extra Large:
0 20px 25px -5px rgb(0 0 0 / 0.1)(modal)
GenerateDocumentModal (Parent)
├── Header Section
│ ├── Icon
│ ├── Title & Subtitle
│ └── Close Button
├── Document Type Selector (Sticky)
│ ├── Label
│ ├── Dropdown
│ └── Help Text
├── Content Area
│ └── Dynamic Form Component (one of 16 types)
│ ├── X60FormModal
│ ├── X35FormModal
│ ├── X28FormModal
│ └── ... (13 more)
└── Footer
└── Cancel Button
- Modal Open: Boolean in parent component
- Selected Document Type: String (event ID)
- Form Data: Object specific to each form type
- Errors: Object mapping field names to error messages
- Loading: Boolean for generation in progress
- Endpoint: To be determined (document generation service)
- Method: POST
- Payload: Form data + business unit ID + document type
- Response: Document URL or ID
- Error Handling: Try-catch with user-friendly messages
Table: generated_documents
- id (uuid, primary key)
- business_unit_id (uuid, foreign key)
- timeline_event_id (text)
- document_type (text)
- title (text)
- language (text)
- status (text: draft/done/sent)
- file_url (text, nullable)
- metadata (jsonb)
- created_at (timestamp)
- updated_at (timestamp)- Template Selection: Allow users to choose from multiple templates
- Draft Saving: Save partial forms and resume later
- Document Preview: Show preview before final generation
- Batch Generation: Generate multiple documents at once
- Custom Fields: Allow business units to add custom data fields
- Version History: Track document revisions
- Email Integration: Send documents directly via email
- Digital Signatures: Add signature workflows
- Auto-save draft every 30 seconds
- Form field tooltips with examples
- Keyboard shortcuts (Cmd+Enter to submit)
- Document templates management interface
- Bulk import from Excel/CSV
- Advanced search and filtering
- Document comparison tool
- Modal opens when "Document" button clicked
- Close button closes modal
- Escape key closes modal
- Clicking overlay closes modal
- Document type dropdown populates correctly
- Form loads when type selected
- All form fields accept input
- Validation works for required fields
- Error messages display correctly
- Submit button generates document
- Loading state displays during generation
- Modal closes on success
- Document list refreshes after generation
- Keyboard navigation works throughout
- Focus moves to modal on open
- Focus returns to trigger on close
- Screen reader announces modal
- All interactive elements have focus indicators
- Error messages are announced
- Color contrast meets WCAG AA
- Works with screen magnification
- Modal displays correctly on desktop (1920px)
- Modal displays correctly on laptop (1366px)
- Modal displays correctly on tablet (768px)
- Modal displays correctly on mobile (375px)
- Touch targets are adequate on mobile
- Virtual keyboard doesn't cover content
- Chrome (latest)
- Firefox (latest)
- Safari (latest)
- Edge (latest)
- Mobile Safari (iOS)
- Chrome Mobile (Android)
- Modal opens in < 100ms
- Form transitions smoothly
- No memory leaks on repeated open/close
- Large forms remain responsive
- Document generation completes within timeout
TBE: Technische Bedrijfseenheid (Technical Business Unit) CPBW: Comité voor Preventie en Bescherming op het Werk (Committee for Prevention and Protection at Work) OR: Ondernemingsraad (Works Council) FOD WASO: Federale Overheidsdienst Werkgelegenheid, Arbeid en Sociaal Overleg (Federal Public Service Employment, Labor and Social Dialogue) X-Series: Belgian labor law forms (X-60, X-35, etc.) Aanplakking: Notice/Posting (official announcement) Kandidatenlijsten: Candidate lists Orgaan: Organ/Body (committee type)
| Version | Date | Author | Changes |
|---|---|---|---|
| 1.0 | 2025-10-17 | UX Design Team | Initial specification |
- Languages (multi-select)
- Orgaan (dropdown)
- Output format (dropdown)
- Date
- Beschrijving TBE (text)
- Ondernemingsnummers JE (text)
- Toelichting Beschrijving TBE (multi-language textarea)
- Toelichting Gewijzigde Structuur (multi-language textarea)
Each of the 16 document types has its own specific form fields. Refer to individual form specifications for complete field lists.
END OF SPECIFICATION