export function foodSafetyChecklist(form: FormTs) {
// Food Safety Audit Checklist - HACCP Compliance Form
// Demonstrates: MatrixQuestion, CheckboxList, Datepicker, conditional visibility, computed values
// ============================================
// STATE - Track compliance scores
// ============================================
const hygieneScore = form.state({ passed: 0, total: 0 });
const temperatureScore = form.state({ passed: 0, total: 0 });
const storageScore = form.state({ passed: 0, total: 0 });
const cleaningScore = form.state({ passed: 0, total: 0 });
// ============================================
// HEADER
// ============================================
form.addRow(row => {
row.addTextPanel('header', {
label: 'Food Safety Audit Checklist',
computedValue: () => 'HACCP Compliance Inspection Form',
customStyles: {
backgroundColor: '#059669',
color: 'white',
padding: '24px',
borderRadius: '12px',
textAlign: 'center'
}
});
});
// ============================================
// SECTION 1: Audit Information
// ============================================
const auditInfo = form.addSubform('auditInfo', {
title: 'Audit Information'
});
auditInfo.addRow(row => {
row.addTextbox('facilityName', {
label: 'Facility Name',
placeholder: 'Enter facility name',
isRequired: true
}, '1fr');
row.addTextbox('facilityLocation', {
label: 'Location/Address',
placeholder: 'Enter address'
}, '1fr');
});
auditInfo.addRow(row => {
row.addTextbox('auditorName', {
label: 'Auditor Name',
placeholder: 'Enter your name',
isRequired: true
}, '1fr');
row.addDatepicker('auditDate', {
label: 'Audit Date',
isRequired: true,
defaultValue: new Date().toISOString().slice(0, 10)
}, '1fr');
});
auditInfo.addRow(row => {
row.addDropdown('auditType', {
label: 'Audit Type',
options: [
{ id: 'routine', name: 'Routine Inspection' },
{ id: 'followup', name: 'Follow-up Audit' },
{ id: 'complaint', name: 'Complaint Investigation' },
{ id: 'pre-opening', name: 'Pre-Opening Inspection' }
],
isRequired: true
}, '1fr');
row.addTimepicker('auditTime', {
label: 'Audit Start Time'
}, '1fr');
});
// ============================================
// SECTION 2: Personal Hygiene & Staff Practices
// ============================================
const hygieneSection = form.addSubform('hygieneSection', {
title: 'Personal Hygiene & Staff Practices',
customStyles: { backgroundColor: '#f0fdf4', padding: '16px', borderRadius: '8px' }
});
hygieneSection.addRow(row => {
row.addMatrixQuestion('hygieneChecks', {
label: 'Evaluate each hygiene checkpoint:',
rows: [
{ id: 'handwashing', label: 'Proper handwashing procedures followed', isRequired: true },
{ id: 'gloves', label: 'Gloves used appropriately and changed regularly', isRequired: true },
{ id: 'uniforms', label: 'Clean uniforms and appropriate attire', isRequired: true },
{ id: 'jewelry', label: 'No jewelry/watches in food prep areas', isRequired: true },
{ id: 'illness', label: 'Staff illness reporting policy enforced', isRequired: true },
{ id: 'hairnets', label: 'Hair restraints worn properly', isRequired: true }
],
columns: [
{ id: 'pass', label: 'Pass' },
{ id: 'fail', label: 'Fail' },
{ id: 'na', label: 'N/A' }
],
fullWidth: true,
onValueChange: (value) => {
if (!value) return;
let passed = 0, total = 0;
Object.values(value).forEach(v => {
if (v === 'pass') { passed++; total++; }
else if (v === 'fail') { total++; }
});
hygieneScore.set({ passed, total });
}
});
});
hygieneSection.addSpacer();
hygieneSection.addRow(row => {
row.addTextarea('hygieneNotes', {
label: () => {
const score = hygieneScore();
if (score.total > 0 && score.passed < score.total) {
return 'Describe non-compliant items and corrective actions needed:';
}
return 'Additional hygiene observations (optional):';
},
placeholder: 'Enter any notes or observations...',
rows: 3,
isRequired: () => {
const score = hygieneScore();
return score.total > 0 && score.passed < score.total;
}
});
});
// ============================================
// SECTION 3: Temperature Control & Monitoring
// ============================================
const tempSection = form.addSubform('temperatureSection', {
title: 'Temperature Control & Monitoring',
customStyles: { backgroundColor: '#eff6ff', padding: '16px', borderRadius: '8px' }
});
tempSection.addRow(row => {
row.addMatrixQuestion('tempChecks', {
label: 'Evaluate temperature control practices:',
rows: [
{ id: 'coldStorage', label: 'Cold storage at 5°C (41°F) or below', isRequired: true },
{ id: 'freezer', label: 'Freezer at -18°C (0°F) or below', isRequired: true },
{ id: 'hotHolding', label: 'Hot holding at 60°C (140°F) or above', isRequired: true },
{ id: 'thermometers', label: 'Calibrated thermometers available', isRequired: true },
{ id: 'tempLogs', label: 'Temperature logs maintained daily', isRequired: true },
{ id: 'coolingProcess', label: 'Proper cooling procedures followed', isRequired: true }
],
columns: [
{ id: 'pass', label: 'Pass' },
{ id: 'fail', label: 'Fail' },
{ id: 'na', label: 'N/A' }
],
fullWidth: true,
onValueChange: (value) => {
if (!value) return;
let passed = 0, total = 0;
Object.values(value).forEach(v => {
if (v === 'pass') { passed++; total++; }
else if (v === 'fail') { total++; }
});
temperatureScore.set({ passed, total });
}
});
});
tempSection.addRow(row => {
row.addDecimal('fridgeTemp', {
label: 'Current Refrigerator Temperature (°C)',
placeholder: 'e.g., 4.0',
min: -10,
max: 20
}, '1fr');
row.addDecimal('freezerTemp', {
label: 'Current Freezer Temperature (°C)',
placeholder: 'e.g., -18.0',
min: -30,
max: 0
}, '1fr');
});
tempSection.addSpacer();
tempSection.addRow(row => {
row.addTextarea('tempNotes', {
label: () => {
const score = temperatureScore();
if (score.total > 0 && score.passed < score.total) {
return 'Describe temperature violations and corrective actions:';
}
return 'Additional temperature observations (optional):';
},
placeholder: 'Enter any notes...',
rows: 3,
isRequired: () => {
const score = temperatureScore();
return score.total > 0 && score.passed < score.total;
}
});
});
// ============================================
// SECTION 4: Food Storage & Handling
// ============================================
const storageSection = form.addSubform('storageSection', {
title: 'Food Storage & Handling',
customStyles: { backgroundColor: '#fefce8', padding: '16px', borderRadius: '8px' }
});
storageSection.addRow(row => {
row.addMatrixQuestion('storageChecks', {
label: 'Evaluate food storage practices:',
rows: [
{ id: 'fifo', label: 'FIFO (First In, First Out) practiced', isRequired: true },
{ id: 'labeling', label: 'All items properly labeled and dated', isRequired: true },
{ id: 'separation', label: 'Raw and cooked foods stored separately', isRequired: true },
{ id: 'containers', label: 'Food stored in approved containers', isRequired: true },
{ id: 'floorStorage', label: 'No food stored directly on floor', isRequired: true },
{ id: 'pestFree', label: 'Storage areas pest-free', isRequired: true }
],
columns: [
{ id: 'pass', label: 'Pass' },
{ id: 'fail', label: 'Fail' },
{ id: 'na', label: 'N/A' }
],
fullWidth: true,
onValueChange: (value) => {
if (!value) return;
let passed = 0, total = 0;
Object.values(value).forEach(v => {
if (v === 'pass') { passed++; total++; }
else if (v === 'fail') { total++; }
});
storageScore.set({ passed, total });
}
});
});
storageSection.addSpacer();
storageSection.addRow(row => {
row.addTextarea('storageNotes', {
label: () => {
const score = storageScore();
if (score.total > 0 && score.passed < score.total) {
return 'Describe storage issues and corrective actions:';
}
return 'Additional storage observations (optional):';
},
placeholder: 'Enter any notes...',
rows: 3,
isRequired: () => {
const score = storageScore();
return score.total > 0 && score.passed < score.total;
}
});
});
// ============================================
// SECTION 5: Cleaning & Sanitation
// ============================================
const cleaningSection = form.addSubform('cleaningSection', {
title: 'Cleaning & Sanitation',
customStyles: { backgroundColor: '#fdf4ff', padding: '16px', borderRadius: '8px' }
});
cleaningSection.addRow(row => {
row.addMatrixQuestion('cleaningChecks', {
label: 'Evaluate cleaning and sanitation:',
rows: [
{ id: 'surfaces', label: 'Food contact surfaces clean and sanitized', isRequired: true },
{ id: 'schedule', label: 'Cleaning schedule posted and followed', isRequired: true },
{ id: 'sanitizer', label: 'Proper sanitizer concentration used', isRequired: true },
{ id: 'waste', label: 'Waste disposed of properly', isRequired: true },
{ id: 'drains', label: 'Floor drains clean and functioning', isRequired: true },
{ id: 'handSinks', label: 'Handwashing sinks stocked and accessible', isRequired: true }
],
columns: [
{ id: 'pass', label: 'Pass' },
{ id: 'fail', label: 'Fail' },
{ id: 'na', label: 'N/A' }
],
fullWidth: true,
onValueChange: (value) => {
if (!value) return;
let passed = 0, total = 0;
Object.values(value).forEach(v => {
if (v === 'pass') { passed++; total++; }
else if (v === 'fail') { total++; }
});
cleaningScore.set({ passed, total });
}
});
});
cleaningSection.addSpacer();
cleaningSection.addRow(row => {
row.addTextarea('cleaningNotes', {
label: () => {
const score = cleaningScore();
if (score.total > 0 && score.passed < score.total) {
return 'Describe sanitation issues and corrective actions:';
}
return 'Additional cleaning observations (optional):';
},
placeholder: 'Enter any notes...',
rows: 3,
isRequired: () => {
const score = cleaningScore();
return score.total > 0 && score.passed < score.total;
}
});
});
// ============================================
// SECTION 6: Overall Assessment
// ============================================
const overallSection = form.addSubform('overallSection', {
title: 'Overall Assessment'
});
overallSection.addRow(row => {
row.addRatingScale('overallRating', {
label: 'Overall Facility Compliance Rating',
preset: 'satisfaction',
size: 'lg',
alignment: 'center'
});
});
overallSection.addRow(row => {
row.addCheckboxList('criticalIssues', {
label: 'Critical Issues Identified (select all that apply):',
options: [
{ id: 'pest', name: 'Pest infestation' },
{ id: 'crossContam', name: 'Cross-contamination risk' },
{ id: 'tempAbuse', name: 'Temperature abuse' },
{ id: 'poorHygiene', name: 'Poor personal hygiene' },
{ id: 'noRecords', name: 'Missing required records' },
{ id: 'none', name: 'No critical issues found' }
],
orientation: 'vertical'
});
});
overallSection.addSpacer();
overallSection.addRow(row => {
row.addTextarea('recommendations', {
label: 'Recommendations and Follow-up Actions',
placeholder: 'Enter recommendations for improvement...',
rows: 4
});
});
// ============================================
// SECTION 7: Compliance Summary
// ============================================
const summarySection = form.addSubform('summarySection', {
title: 'Compliance Summary',
isVisible: () => {
const h = hygieneScore();
const t = temperatureScore();
const s = storageScore();
const c = cleaningScore();
return (h.total + t.total + s.total + c.total) > 0;
}
});
summarySection.addRow(row => {
row.addTextPanel('complianceScore', {
label: 'Audit Results',
computedValue: () => {
const h = hygieneScore();
const t = temperatureScore();
const s = storageScore();
const c = cleaningScore();
const totalPassed = h.passed + t.passed + s.passed + c.passed;
const totalChecks = h.total + t.total + s.total + c.total;
if (totalChecks === 0) return '';
const percentage = Math.round((totalPassed / totalChecks) * 100);
let grade = '';
let emoji = '';
if (percentage >= 95) { grade = 'A - Excellent'; emoji = ''; }
else if (percentage >= 85) { grade = 'B - Good'; emoji = ''; }
else if (percentage >= 75) { grade = 'C - Acceptable'; emoji = ''; }
else if (percentage >= 60) { grade = 'D - Needs Improvement'; emoji = ''; }
else { grade = 'F - Critical Issues'; emoji = ''; }
let summary = `${emoji} COMPLIANCE SCORE: ${percentage}%\n`;
summary += `${''.repeat(30)}\n\n`;
summary += `Grade: ${grade}\n\n`;
summary += `SECTION BREAKDOWN:\n`;
summary += ` Hygiene: ${h.passed}/${h.total} checkpoints passed\n`;
summary += ` Temperature: ${t.passed}/${t.total} checkpoints passed\n`;
summary += ` Storage: ${s.passed}/${s.total} checkpoints passed\n`;
summary += ` Cleaning: ${c.passed}/${c.total} checkpoints passed\n`;
summary += `\n TOTAL: ${totalPassed}/${totalChecks} checkpoints passed`;
return summary;
},
customStyles: () => {
const h = hygieneScore();
const t = temperatureScore();
const s = storageScore();
const c = cleaningScore();
const totalPassed = h.passed + t.passed + s.passed + c.passed;
const totalChecks = h.total + t.total + s.total + c.total;
const percentage = totalChecks > 0 ? (totalPassed / totalChecks) * 100 : 0;
const baseStyles = {
padding: '20px',
borderRadius: '8px',
whiteSpace: 'pre-wrap',
fontFamily: 'monospace',
fontSize: '14px'
};
if (percentage >= 85) {
return { ...baseStyles, backgroundColor: '#d1fae5', borderLeft: '4px solid #059669' };
} else if (percentage >= 60) {
return { ...baseStyles, backgroundColor: '#fef3c7', borderLeft: '4px solid #d97706' };
}
return { ...baseStyles, backgroundColor: '#fee2e2', borderLeft: '4px solid #dc2626' };
}
});
});
// ============================================
// SECTION 8: Auditor Verification
// ============================================
const verificationSection = form.addSubform('verification', {
title: 'Auditor Verification'
});
verificationSection.addRow(row => {
row.addCheckbox('auditComplete', {
label: 'I confirm this audit was conducted thoroughly and all findings are accurate',
isRequired: true
});
});
verificationSection.addRow(row => {
row.addCheckbox('followUpRequired', {
label: 'Follow-up inspection required'
});
});
verificationSection.addRow(row => {
row.addDatepicker('followUpDate', {
label: 'Scheduled Follow-up Date',
isVisible: () => verificationSection.checkbox('followUpRequired')?.value() === true,
isRequired: () => verificationSection.checkbox('followUpRequired')?.value() === true
});
});
// ============================================
// FORM CONFIGURATION
// ============================================
form.configureSubmitButton({
label: 'Submit Audit Report'
});
form.configureCompletionScreen({
type: 'text',
title: 'Audit Report Submitted',
message: 'Your food safety audit has been recorded. A copy of the report will be sent to the facility management. Thank you for helping maintain food safety standards.'
});
}