export function siteSafetyChecklistForm(form: FormTs) {
// Site Safety Audit Checklist
// Demonstrates: Datepicker, Textbox, Dropdown, CheckboxList, MatrixQuestion, RadioButton, Slider, Textarea
// Focus: Construction site safety compliance and hazard assessment
// ============================================
// HEADER
// ============================================
form.addRow(row => {
row.addTextPanel('header', {
label: 'Site Safety Audit Checklist',
computedValue: () => 'Complete this checklist to document site safety conditions and identify hazards.',
customStyles: {
backgroundColor: '#f97316',
color: 'white',
padding: '24px',
borderRadius: '12px',
textAlign: 'center'
}
});
});
// ============================================
// SECTION 1: Inspection Details
// ============================================
const detailsSection = form.addSubform('detailsSection', {
title: 'Inspection Details'
});
detailsSection.addRow(row => {
row.addDatepicker('inspectionDate', {
label: 'Inspection Date',
isRequired: true,
maxDate: () => new Date().toISOString()
}, '1fr');
row.addTimepicker('inspectionTime', {
label: 'Time'
}, '1fr');
});
detailsSection.addRow(row => {
row.addTextbox('siteName', {
label: 'Site Name / Project',
placeholder: 'Enter job site name or project number',
isRequired: true
}, '1fr');
row.addTextbox('siteAddress', {
label: 'Site Address',
placeholder: 'Full address'
}, '1fr');
});
detailsSection.addRow(row => {
row.addTextbox('inspectorName', {
label: 'Inspector Name',
placeholder: 'Your full name',
isRequired: true
}, '1fr');
row.addTextbox('inspectorTitle', {
label: 'Title/Role',
placeholder: 'Safety Manager, Supervisor, etc.'
}, '1fr');
});
detailsSection.addRow(row => {
row.addDropdown('inspectionType', {
label: 'Type of Inspection',
options: [
{ id: 'daily', name: 'Daily Safety Check' },
{ id: 'weekly', name: 'Weekly Audit' },
{ id: 'monthly', name: 'Monthly Comprehensive' },
{ id: 'pre-work', name: 'Pre-Work Inspection' },
{ id: 'incident', name: 'Post-Incident Inspection' },
{ id: 'regulatory', name: 'Regulatory Compliance Audit' }
],
placeholder: 'Select type'
}, '1fr');
row.addDropdown('weatherConditions', {
label: 'Weather Conditions',
options: [
{ id: 'clear', name: 'Clear / Sunny' },
{ id: 'cloudy', name: 'Cloudy' },
{ id: 'rain', name: 'Rain / Wet' },
{ id: 'snow', name: 'Snow / Ice' },
{ id: 'wind', name: 'High Winds' },
{ id: 'extreme-heat', name: 'Extreme Heat' },
{ id: 'extreme-cold', name: 'Extreme Cold' }
],
placeholder: 'Select conditions'
}, '1fr');
});
// ============================================
// SECTION 2: Personal Protective Equipment (PPE)
// ============================================
const ppeSection = form.addSubform('ppeSection', {
title: 'Personal Protective Equipment (PPE)',
isVisible: () => !!detailsSection.textbox('siteName')?.value()
});
ppeSection.addRow(row => {
row.addMatrixQuestion('ppeCompliance', {
label: 'Verify PPE compliance for all workers on site:',
rows: [
{ id: 'hard-hats', label: 'Hard hats worn in required areas' },
{ id: 'safety-glasses', label: 'Safety glasses/goggles where required' },
{ id: 'hearing', label: 'Hearing protection in high-noise areas' },
{ id: 'gloves', label: 'Appropriate gloves for task' },
{ id: 'footwear', label: 'Steel-toe boots/safety footwear' },
{ id: 'high-vis', label: 'High-visibility vests worn' },
{ id: 'respiratory', label: 'Respiratory protection where needed' },
{ id: 'fall-harness', label: 'Fall protection harnesses (when required)' }
],
columns: [
{ id: 'compliant', label: 'Compliant' },
{ id: 'non-compliant', label: 'Non-Compliant' },
{ id: 'na', label: 'N/A' }
],
striped: true,
fullWidth: true
});
});
ppeSection.addRow(row => {
row.addTextarea('ppeIssues', {
label: 'PPE Issues Observed',
placeholder: 'Describe any PPE violations or issues...',
rows: 2,
autoExpand: true,
isVisible: () => {
const matrix = ppeSection.matrixQuestion('ppeCompliance')?.value();
if (!matrix) return false;
return Object.values(matrix).some(v => v === 'non-compliant');
}
});
});
// ============================================
// SECTION 3: Fall Protection & Scaffolding
// ============================================
const fallSection = form.addSubform('fallSection', {
title: 'Fall Protection & Scaffolding',
isVisible: () => !!detailsSection.textbox('siteName')?.value()
});
fallSection.addRow(row => {
row.addCheckboxList('fallProtection', {
label: 'Fall Protection Checklist (mark all that are compliant)',
options: [
{ id: 'guardrails', name: 'Guardrails installed at 6ft+ edges' },
{ id: 'floor-holes', name: 'Floor holes covered or guarded' },
{ id: 'ladders', name: 'Ladders secured and in good condition' },
{ id: 'scaffold-complete', name: 'Scaffolding fully planked and secured' },
{ id: 'scaffold-inspected', name: 'Scaffolding inspected by competent person' },
{ id: 'anchor-points', name: 'Adequate anchor points for harnesses' },
{ id: 'roofing', name: 'Roof work fall protection in place' },
{ id: 'training', name: 'Workers trained on fall protection' }
],
orientation: 'vertical'
});
});
fallSection.addRow(row => {
row.addRadioButton('fallProtectionStatus', {
label: 'Overall Fall Protection Status',
options: [
{ id: 'compliant', name: 'Fully Compliant' },
{ id: 'minor', name: 'Minor Issues - Corrective Action Needed' },
{ id: 'major', name: 'Major Violations - Work Stoppage Required' },
{ id: 'na', name: 'N/A - No elevated work' }
],
orientation: 'vertical'
});
});
// ============================================
// SECTION 4: Electrical Safety
// ============================================
const electricalSection = form.addSubform('electricalSection', {
title: 'Electrical Safety',
isVisible: () => !!detailsSection.textbox('siteName')?.value()
});
electricalSection.addRow(row => {
row.addCheckboxList('electricalItems', {
label: 'Electrical Safety Checklist (mark all that are compliant)',
options: [
{ id: 'gfci', name: 'GFCI protection for all outlets' },
{ id: 'cords', name: 'Extension cords in good condition' },
{ id: 'lockout', name: 'Lockout/tagout procedures followed' },
{ id: 'panel-access', name: 'Electrical panels accessible (3ft clearance)' },
{ id: 'temp-power', name: 'Temporary power safely installed' },
{ id: 'wet-areas', name: 'No electrical hazards in wet areas' },
{ id: 'overhead', name: 'Overhead power line awareness' }
],
orientation: 'vertical'
});
});
// ============================================
// SECTION 5: Housekeeping & General Site
// ============================================
const housekeepingSection = form.addSubform('housekeepingSection', {
title: 'Housekeeping & Site Conditions',
isVisible: () => !!detailsSection.textbox('siteName')?.value()
});
housekeepingSection.addRow(row => {
row.addMatrixQuestion('siteConditions', {
label: 'Evaluate general site conditions:',
rows: [
{ id: 'walkways', label: 'Walkways clear of debris' },
{ id: 'materials', label: 'Materials properly stored' },
{ id: 'waste', label: 'Waste disposed properly' },
{ id: 'spills', label: 'No oil/chemical spills' },
{ id: 'lighting', label: 'Adequate lighting' },
{ id: 'signage', label: 'Safety signage visible' },
{ id: 'fire-ext', label: 'Fire extinguishers accessible' },
{ id: 'first-aid', label: 'First aid kit stocked' }
],
columns: [
{ id: 'good', label: 'Good' },
{ id: 'needs-attention', label: 'Needs Attention' },
{ id: 'critical', label: 'Critical Issue' },
{ id: 'na', label: 'N/A' }
],
striped: true,
fullWidth: true
});
});
// ============================================
// SECTION 6: Hazard Identification
// ============================================
const hazardSection = form.addSubform('hazardSection', {
title: 'Hazard Identification',
isVisible: () => !!detailsSection.textbox('siteName')?.value(),
customStyles: { backgroundColor: '#fef2f2', padding: '20px', borderRadius: '12px' }
});
hazardSection.addRow(row => {
row.addCheckboxList('hazardsIdentified', {
label: 'Check any hazards observed on site',
options: [
{ id: 'fall', name: 'Fall hazards' },
{ id: 'electrical', name: 'Electrical hazards' },
{ id: 'struck-by', name: 'Struck-by hazards' },
{ id: 'caught-in', name: 'Caught-in/between hazards' },
{ id: 'confined', name: 'Confined space hazards' },
{ id: 'chemical', name: 'Chemical/hazmat exposure' },
{ id: 'noise', name: 'Excessive noise' },
{ id: 'heat', name: 'Heat stress conditions' },
{ id: 'trenching', name: 'Excavation/trenching hazards' },
{ id: 'equipment', name: 'Heavy equipment hazards' }
],
orientation: 'vertical'
});
});
hazardSection.addSpacer();
hazardSection.addRow(row => {
row.addSlider('overallRiskLevel', {
label: 'Overall Site Risk Level Assessment',
min: 1,
max: 10,
step: 1,
defaultValue: 3,
showValue: true,
unit: '/10'
});
});
hazardSection.addRow(row => {
row.addTextPanel('riskNote', {
computedValue: () => {
const risk = hazardSection.slider('overallRiskLevel')?.value();
if (!risk) return '';
if (risk <= 3) return '✅ LOW RISK - Continue normal operations with standard precautions.';
if (risk <= 5) return '⚠️ MODERATE RISK - Address identified issues promptly.';
if (risk <= 7) return '🔶 ELEVATED RISK - Immediate corrective action required.';
return '🛑 HIGH RISK - Consider work stoppage until issues resolved.';
},
customStyles: () => {
const risk = hazardSection.slider('overallRiskLevel')?.value();
let bg = '#dcfce7';
let border = '#22c55e';
if (risk && risk > 3) { bg = '#fef3c7'; border = '#f59e0b'; }
if (risk && risk > 5) { bg = '#ffedd5'; border = '#f97316'; }
if (risk && risk > 7) { bg = '#fee2e2'; border = '#ef4444'; }
return {
backgroundColor: bg,
borderLeft: `4px solid ${border}`,
padding: '12px',
borderRadius: '6px',
fontWeight: 'bold'
};
},
isVisible: () => !!hazardSection.slider('overallRiskLevel')?.value()
});
});
// ============================================
// SECTION 7: Corrective Actions
// ============================================
const actionsSection = form.addSubform('actionsSection', {
title: 'Corrective Actions Required',
isVisible: () => {
const hazards = hazardSection.checkboxList('hazardsIdentified')?.value() || [];
const risk = hazardSection.slider('overallRiskLevel')?.value() || 0;
return hazards.length > 0 || risk > 3;
},
customStyles: { backgroundColor: '#fef9c3', padding: '16px', borderRadius: '8px' }
});
actionsSection.addRow(row => {
row.addTextarea('correctiveActions', {
label: 'Describe required corrective actions',
placeholder: 'List specific actions needed to address identified hazards...',
rows: 4,
autoExpand: true,
isRequired: () => {
const risk = hazardSection.slider('overallRiskLevel')?.value() || 0;
return risk > 5;
}
});
});
actionsSection.addRow(row => {
row.addTextbox('assignedTo', {
label: 'Assigned To',
placeholder: 'Name/Role responsible for corrections'
}, '1fr');
row.addDatepicker('dueDate', {
label: 'Due Date',
minDate: () => new Date().toISOString()
}, '1fr');
});
// ============================================
// SECTION 8: Inspector Notes & Sign-off
// ============================================
const signoffSection = form.addSubform('signoffSection', {
title: 'Inspector Notes & Sign-off',
isVisible: () => !!detailsSection.textbox('siteName')?.value()
});
signoffSection.addRow(row => {
row.addTextarea('inspectorNotes', {
label: 'Additional Inspector Notes',
placeholder: 'General observations, commendations, or concerns...',
rows: 3,
autoExpand: true
});
});
signoffSection.addRow(row => {
row.addCheckbox('confirmAccuracy', {
label: 'I confirm this inspection was conducted thoroughly and all information is accurate to the best of my knowledge.',
isRequired: true
});
});
// ============================================
// SECTION 9: Summary
// ============================================
const summarySection = form.addSubform('summarySection', {
title: 'Audit Summary',
isVisible: () => signoffSection.checkbox('confirmAccuracy')?.value() === true
});
summarySection.addRow(row => {
row.addTextPanel('summaryContent', {
computedValue: () => {
const site = detailsSection.textbox('siteName')?.value();
const date = detailsSection.datepicker('inspectionDate')?.value();
const inspector = detailsSection.textbox('inspectorName')?.value();
const risk = hazardSection.slider('overallRiskLevel')?.value();
const hazards = hazardSection.checkboxList('hazardsIdentified')?.value() || [];
const fallStatus = fallSection.radioButton('fallProtectionStatus')?.value();
let summary = '📋 SITE SAFETY AUDIT SUMMARY\n';
summary += '━'.repeat(32) + '\n\n';
if (site) summary += `Site: ${site}\n`;
if (date) summary += `Date: ${new Date(date).toLocaleDateString()}\n`;
if (inspector) summary += `Inspector: ${inspector}\n`;
summary += '\n';
if (risk) summary += `Risk Level: ${risk}/10\n`;
summary += `Hazards Found: ${hazards.length}\n`;
const statusLabels: Record<string, string> = {
'compliant': '✅ Compliant',
'minor': '⚠️ Minor Issues',
'major': '🛑 Major Violations',
'na': 'N/A'
};
if (fallStatus) summary += `Fall Protection: ${statusLabels[fallStatus] || fallStatus}\n`;
return summary;
},
customStyles: () => {
const risk = hazardSection.slider('overallRiskLevel')?.value() || 0;
let bg = '#dcfce7';
let border = '#22c55e';
if (risk > 3) { bg = '#fef3c7'; border = '#f59e0b'; }
if (risk > 5) { bg = '#ffedd5'; border = '#f97316'; }
if (risk > 7) { bg = '#fee2e2'; border = '#ef4444'; }
return {
backgroundColor: bg,
borderLeft: `4px solid ${border}`,
padding: '16px',
borderRadius: '8px',
whiteSpace: 'pre-wrap',
fontFamily: 'monospace',
fontSize: '14px'
};
}
});
});
// ============================================
// FORM CONFIGURATION
// ============================================
form.configureSubmitButton({
label: 'Submit Safety Audit',
isVisible: () => signoffSection.checkbox('confirmAccuracy')?.value() === true
});
form.configureCompletionScreen({
type: 'text',
title: 'Safety Audit Submitted',
message: 'Thank you for completing this safety audit. The report has been recorded. Please ensure all corrective actions are addressed by their due dates and schedule a follow-up inspection if needed.'
});
}