export function incidentReportForm(form: FormTs) {
// Workplace Incident Report Form
// Demonstrates: Pages (multi-page), Datepicker, Timepicker, Dropdown, RadioButton, CheckboxList, Textarea, Slider
// Focus: Structured incident documentation with investigation workflow
// ============================================
// HEADER
// ============================================
form.addRow(row => {
row.addTextPanel('header', {
label: 'Workplace Incident Report',
computedValue: () => 'Document all workplace incidents promptly and accurately. This information is essential for investigation and prevention.',
customStyles: {
backgroundColor: '#b91c1c',
color: 'white',
padding: '24px',
borderRadius: '12px',
textAlign: 'center'
}
});
});
// ============================================
// MULTI-PAGE WIZARD
// ============================================
const pages = form.addPages('incidentPages', {
heightMode: 'current-page'
});
// ============================================
// PAGE 1: Incident Details
// ============================================
const page1 = pages.addPage('details');
const detailsSection = page1.addSubform('detailsSection', {
title: 'Step 1: Incident Details'
});
detailsSection.addRow(row => {
row.addDropdown('incidentType', {
label: 'Type of Incident',
options: [
{ id: 'injury', name: 'Injury / Illness' },
{ id: 'near-miss', name: 'Near Miss (No Injury)' },
{ id: 'property', name: 'Property Damage' },
{ id: 'environmental', name: 'Environmental Release' },
{ id: 'security', name: 'Security Incident' },
{ id: 'vehicle', name: 'Vehicle Accident' },
{ id: 'other', name: 'Other' }
],
placeholder: 'Select incident type',
isRequired: true
});
});
detailsSection.addRow(row => {
row.addDatepicker('incidentDate', {
label: 'Date of Incident',
isRequired: true,
maxDate: () => new Date().toISOString()
}, '1fr');
row.addTimepicker('incidentTime', {
label: 'Time of Incident',
isRequired: true
}, '1fr');
});
detailsSection.addRow(row => {
row.addTextbox('location', {
label: 'Exact Location',
placeholder: 'Building, floor, room, or specific area',
isRequired: true
});
});
detailsSection.addRow(row => {
row.addDropdown('severity', {
label: 'Initial Severity Assessment',
options: [
{ id: 'minor', name: 'Minor - First aid only' },
{ id: 'moderate', name: 'Moderate - Medical treatment required' },
{ id: 'serious', name: 'Serious - Lost time or hospitalization' },
{ id: 'critical', name: 'Critical - Life threatening' },
{ id: 'fatality', name: 'Fatality' },
{ id: 'near-miss', name: 'Near Miss - No injury/damage' }
],
placeholder: 'Select severity',
isRequired: true
});
});
detailsSection.addRow(row => {
row.addTextPanel('severityWarning', {
computedValue: () => {
const severity = detailsSection.dropdown('severity')?.value();
if (severity === 'serious' || severity === 'critical' || severity === 'fatality') {
return '⚠️ CRITICAL: Immediately notify your supervisor, safety manager, and HR. Preserve the scene for investigation.';
}
return '';
},
customStyles: () => ({
backgroundColor: '#fee2e2',
color: '#991b1b',
padding: '12px',
borderRadius: '6px',
fontWeight: 'bold',
textAlign: 'center'
}),
isVisible: () => {
const severity = detailsSection.dropdown('severity')?.value();
return severity === 'serious' || severity === 'critical' || severity === 'fatality';
}
});
});
// Navigation buttons for page 1
const nav1 = page1.addSubform('nav1', { sticky: 'bottom' });
nav1.addRow(row => {
row.addButton('nextBtn1', {
label: 'Continue to Description →',
onClick: () => pages.goToPage('description'),
isDisabled: () => !detailsSection.dropdown('incidentType')?.value()
});
});
// ============================================
// PAGE 2: Description
// ============================================
const page2 = pages.addPage('description');
const descSection = page2.addSubform('descSection', {
title: 'Step 2: What Happened?'
});
descSection.addRow(row => {
row.addTextarea('description', {
label: 'Describe what happened',
placeholder: 'Provide a clear, factual account of the incident. Include what the person was doing, what equipment was involved, and the sequence of events leading to the incident...',
rows: 6,
autoExpand: true,
isRequired: true
});
});
descSection.addRow(row => {
row.addTextarea('immediateActions', {
label: 'Immediate actions taken',
placeholder: 'What was done immediately after the incident? First aid, evacuation, area secured, equipment shut down, etc.',
rows: 3,
autoExpand: true
});
});
// Injury details (conditional)
const injurySection = page2.addSubform('injurySection', {
title: 'Injury Details',
isVisible: () => detailsSection.dropdown('incidentType')?.value() === 'injury',
customStyles: { backgroundColor: '#fef2f2', padding: '16px', borderRadius: '8px' }
});
injurySection.addRow(row => {
row.addCheckboxList('injuryType', {
label: 'Type of Injury (select all that apply)',
options: [
{ id: 'cut', name: 'Cut / Laceration' },
{ id: 'bruise', name: 'Bruise / Contusion' },
{ id: 'sprain', name: 'Sprain / Strain' },
{ id: 'fracture', name: 'Fracture / Break' },
{ id: 'burn', name: 'Burn' },
{ id: 'eye', name: 'Eye Injury' },
{ id: 'respiratory', name: 'Respiratory' },
{ id: 'amputation', name: 'Amputation' },
{ id: 'other', name: 'Other' }
],
orientation: 'vertical'
});
});
injurySection.addRow(row => {
row.addCheckboxList('bodyPart', {
label: 'Body Part Affected',
options: [
{ id: 'head', name: 'Head / Face' },
{ id: 'neck', name: 'Neck' },
{ id: 'shoulder', name: 'Shoulder' },
{ id: 'arm', name: 'Arm / Elbow' },
{ id: 'hand', name: 'Hand / Wrist' },
{ id: 'fingers', name: 'Fingers' },
{ id: 'back', name: 'Back' },
{ id: 'chest', name: 'Chest / Torso' },
{ id: 'leg', name: 'Leg / Knee' },
{ id: 'foot', name: 'Foot / Ankle' },
{ id: 'toes', name: 'Toes' }
],
orientation: 'vertical'
});
});
injurySection.addRow(row => {
row.addRadioButton('medicalTreatment', {
label: 'Medical treatment received',
options: [
{ id: 'none', name: 'No treatment needed' },
{ id: 'first-aid', name: 'First aid on site' },
{ id: 'clinic', name: 'Clinic / Urgent care visit' },
{ id: 'er', name: 'Emergency room' },
{ id: 'hospital', name: 'Hospital admission' }
],
orientation: 'vertical'
});
});
// Navigation for page 2
const nav2 = page2.addSubform('nav2', { sticky: 'bottom' });
nav2.addRow(row => {
row.addButton('backBtn2', {
label: '← Back',
onClick: () => pages.goToPage('details')
}, '1fr');
row.addButton('nextBtn2', {
label: 'Continue to People Involved →',
onClick: () => pages.goToPage('people'),
isDisabled: () => !descSection.textarea('description')?.value()
}, '1fr');
});
// ============================================
// PAGE 3: People Involved
// ============================================
const page3 = pages.addPage('people');
const injuredSection = page3.addSubform('injuredSection', {
title: 'Step 3: Injured/Affected Person',
isVisible: () => detailsSection.dropdown('incidentType')?.value() === 'injury'
});
injuredSection.addRow(row => {
row.addTextbox('injuredName', {
label: 'Injured Person\'s Name',
placeholder: 'Full name',
isRequired: () => detailsSection.dropdown('incidentType')?.value() === 'injury'
}, '1fr');
row.addTextbox('injuredTitle', {
label: 'Job Title / Department',
placeholder: 'Position'
}, '1fr');
});
injuredSection.addRow(row => {
row.addDropdown('employeeType', {
label: 'Employment Status',
options: [
{ id: 'employee', name: 'Employee' },
{ id: 'contractor', name: 'Contractor' },
{ id: 'visitor', name: 'Visitor' },
{ id: 'vendor', name: 'Vendor' },
{ id: 'public', name: 'Member of Public' }
],
placeholder: 'Select status'
}, '1fr');
row.addTextbox('supervisor', {
label: 'Supervisor Name',
placeholder: 'Direct supervisor'
}, '1fr');
});
// Reporter Info
const reporterSection = page3.addSubform('reporterSection', {
title: 'Report Filed By'
});
reporterSection.addRow(row => {
row.addTextbox('reporterName', {
label: 'Your Name',
placeholder: 'Person filing this report',
isRequired: true
}, '1fr');
row.addTextbox('reporterTitle', {
label: 'Your Title / Department',
placeholder: 'Position'
}, '1fr');
});
reporterSection.addRow(row => {
row.addTextbox('reporterPhone', {
label: 'Phone Number',
placeholder: 'For follow-up questions'
}, '1fr');
row.addEmail('reporterEmail', {
label: 'Email',
placeholder: 'your@email.com'
}, '1fr');
});
// Witnesses
const witnessSection = page3.addSubform('witnessSection', {
title: 'Witnesses'
});
witnessSection.addRow(row => {
row.addRadioButton('hasWitnesses', {
label: 'Were there any witnesses?',
options: [
{ id: 'yes', name: 'Yes' },
{ id: 'no', name: 'No' },
{ id: 'unknown', name: 'Unknown' }
],
orientation: 'horizontal'
});
});
witnessSection.addRow(row => {
row.addTextarea('witnessInfo', {
label: 'Witness names and contact information',
placeholder: 'List all witnesses with their names and how to contact them...',
rows: 2,
autoExpand: true,
isVisible: () => witnessSection.radioButton('hasWitnesses')?.value() === 'yes'
});
});
// Navigation for page 3
const nav3 = page3.addSubform('nav3', { sticky: 'bottom' });
nav3.addRow(row => {
row.addButton('backBtn3', {
label: '← Back',
onClick: () => pages.goToPage('description')
}, '1fr');
row.addButton('nextBtn3', {
label: 'Continue to Contributing Factors →',
onClick: () => pages.goToPage('factors')
}, '1fr');
});
// ============================================
// PAGE 4: Contributing Factors
// ============================================
const page4 = pages.addPage('factors');
const factorsSection = page4.addSubform('factorsSection', {
title: 'Step 4: Contributing Factors'
});
factorsSection.addRow(row => {
row.addMatrixQuestion('contributingFactors', {
label: 'Identify factors that may have contributed to this incident:',
rows: [
{ id: 'training', label: 'Lack of training / knowledge' },
{ id: 'procedure', label: 'Procedure not followed' },
{ id: 'equipment', label: 'Equipment failure / defect' },
{ id: 'ppe', label: 'PPE not used / inadequate' },
{ id: 'housekeeping', label: 'Poor housekeeping' },
{ id: 'supervision', label: 'Inadequate supervision' },
{ id: 'fatigue', label: 'Fatigue / stress' },
{ id: 'rushing', label: 'Rushing / time pressure' },
{ id: 'distraction', label: 'Distraction' },
{ id: 'environment', label: 'Environmental conditions' }
],
columns: [
{ id: 'yes', label: 'Contributing' },
{ id: 'possible', label: 'Possible' },
{ id: 'no', label: 'Not a Factor' },
{ id: 'unknown', label: 'Unknown' }
],
striped: true,
fullWidth: true
});
});
factorsSection.addSpacer();
factorsSection.addRow(row => {
row.addSlider('recurrenceRisk', {
label: 'How likely is this type of incident to happen again?',
min: 1,
max: 10,
step: 1,
defaultValue: 5,
showValue: true,
unit: '/10'
});
});
factorsSection.addRow(row => {
row.addTextPanel('riskWarning', {
computedValue: () => {
const risk = factorsSection.slider('recurrenceRisk')?.value();
if (!risk) return '';
if (risk <= 3) return 'Low recurrence risk - Document and monitor.';
if (risk <= 5) return 'Moderate risk - Corrective actions recommended.';
if (risk <= 7) return 'Elevated risk - Priority corrective actions needed.';
return 'High risk - Immediate action required to prevent recurrence!';
},
customStyles: () => {
const risk = factorsSection.slider('recurrenceRisk')?.value();
let bg = '#dcfce7';
if (risk && risk > 3) bg = '#fef3c7';
if (risk && risk > 5) bg = '#ffedd5';
if (risk && risk > 7) bg = '#fee2e2';
return {
backgroundColor: bg,
padding: '10px',
borderRadius: '6px',
textAlign: 'center'
};
},
isVisible: () => !!factorsSection.slider('recurrenceRisk')?.value()
});
});
factorsSection.addSpacer();
factorsSection.addRow(row => {
row.addTextarea('rootCause', {
label: 'Preliminary Root Cause Analysis',
placeholder: 'What was the underlying cause of this incident? Consider the 5 Whys technique...',
rows: 3,
autoExpand: true
});
});
// Navigation for page 4
const nav4 = page4.addSubform('nav4', { sticky: 'bottom' });
nav4.addRow(row => {
row.addButton('backBtn4', {
label: '← Back',
onClick: () => pages.goToPage('people')
}, '1fr');
row.addButton('nextBtn4', {
label: 'Continue to Review →',
onClick: () => pages.goToPage('review')
}, '1fr');
});
// ============================================
// PAGE 5: Review & Submit
// ============================================
const page5 = pages.addPage('review');
const reviewSection = page5.addSubform('reviewSection', {
title: 'Step 5: Review & Submit'
});
reviewSection.addRow(row => {
row.addTextPanel('summaryContent', {
computedValue: () => {
const type = detailsSection.dropdown('incidentType')?.value();
const date = detailsSection.datepicker('incidentDate')?.value();
const severity = detailsSection.dropdown('severity')?.value();
const location = detailsSection.textbox('location')?.value();
const reporter = reporterSection.textbox('reporterName')?.value();
const risk = factorsSection.slider('recurrenceRisk')?.value();
const typeLabels: Record<string, string> = {
'injury': 'Injury/Illness', 'near-miss': 'Near Miss', 'property': 'Property Damage',
'environmental': 'Environmental', 'security': 'Security', 'vehicle': 'Vehicle Accident', 'other': 'Other'
};
const severityLabels: Record<string, string> = {
'minor': 'Minor', 'moderate': 'Moderate', 'serious': 'Serious',
'critical': 'Critical', 'fatality': 'Fatality', 'near-miss': 'Near Miss'
};
let summary = '📋 INCIDENT REPORT SUMMARY\n';
summary += '━'.repeat(32) + '\n\n';
if (type) summary += `Type: ${typeLabels[type] || type}\n`;
if (date) summary += `Date: ${new Date(date).toLocaleDateString()}\n`;
if (location) summary += `Location: ${location}\n`;
if (severity) summary += `Severity: ${severityLabels[severity] || severity}\n`;
if (risk) summary += `Recurrence Risk: ${risk}/10\n`;
summary += '\n';
if (reporter) summary += `Reported by: ${reporter}\n`;
return summary;
},
customStyles: () => {
const severity = detailsSection.dropdown('severity')?.value();
let bg = '#f3f4f6';
let border = '#6b7280';
if (severity === 'minor' || severity === 'near-miss') { bg = '#dcfce7'; border = '#22c55e'; }
if (severity === 'moderate') { bg = '#fef3c7'; border = '#f59e0b'; }
if (severity === 'serious' || severity === 'critical' || severity === 'fatality') { bg = '#fee2e2'; border = '#ef4444'; }
return {
backgroundColor: bg,
borderLeft: `4px solid ${border}`,
padding: '16px',
borderRadius: '8px',
whiteSpace: 'pre-wrap',
fontFamily: 'monospace',
fontSize: '14px'
};
}
});
});
reviewSection.addRow(row => {
row.addTextarea('correctiveActions', {
label: 'Recommended Corrective Actions',
placeholder: 'What actions should be taken to prevent this from happening again?',
rows: 3,
autoExpand: true
});
});
reviewSection.addRow(row => {
row.addCheckbox('confirmAccuracy', {
label: 'I confirm that all information provided in this report is accurate and complete to the best of my knowledge.',
isRequired: true
});
});
// Navigation for page 5
const nav5 = page5.addSubform('nav5', { sticky: 'bottom' });
nav5.addRow(row => {
row.addButton('backBtn5', {
label: '← Back to Edit',
onClick: () => pages.goToPage('factors')
});
});
// ============================================
// FORM CONFIGURATION
// ============================================
form.configureSubmitButton({
label: 'Submit Incident Report',
isVisible: () => reviewSection.checkbox('confirmAccuracy')?.value() === true
});
form.configureCompletionScreen({
type: 'text',
title: 'Incident Report Submitted',
message: 'Your incident report has been filed. A copy has been sent to the safety department and relevant supervisors. You may be contacted for additional information during the investigation. Thank you for reporting this incident promptly.'
});
}