export function whistleblowerReportForm(form: FormTs) {
// Anonymous Whistleblower Report - Secure compliance incident reporting
// Demonstrates: Heavy conditional visibility, dynamic labels, sensitive data handling, multi-section flow
// ============================================
// HEADER
// ============================================
form.addRow(row => {
row.addTextPanel('header', {
label: 'Confidential Report',
computedValue: () => 'Report concerns safely and anonymously. Your identity is protected.',
customStyles: {
backgroundColor: '#1e3a5f',
color: 'white',
padding: '24px',
borderRadius: '12px',
textAlign: 'center'
}
});
});
// ============================================
// SECTION: Confidentiality Notice
// ============================================
const noticeSection = form.addSubform('notice', {
title: 'Before You Begin',
customStyles: { backgroundColor: '#fef3c7', padding: '16px', borderRadius: '8px', borderLeft: '4px solid #f59e0b' }
});
noticeSection.addRow(row => {
row.addTextPanel('confidentialityNotice', {
computedValue: () => `CONFIDENTIALITY NOTICE
This reporting system is designed to protect your identity. You may submit this report completely anonymously - no personal information is required.
All reports are reviewed by trained compliance personnel and handled with strict confidentiality in accordance with applicable whistleblower protection laws.
Retaliation against anyone who makes a good-faith report is strictly prohibited.`,
customStyles: {
whiteSpace: 'pre-wrap',
fontSize: '14px',
lineHeight: '1.6'
}
});
});
noticeSection.addRow(row => {
row.addCheckbox('acknowledgeNotice', {
label: 'I understand this report will be handled confidentially',
isRequired: true
});
});
// ============================================
// SECTION 1: Incident Category
// ============================================
const categorySection = form.addSubform('category', {
title: 'Report Category',
isVisible: () => noticeSection.checkbox('acknowledgeNotice')?.value() === true
});
categorySection.addRow(row => {
row.addRadioButton('incidentType', {
label: 'What type of concern are you reporting?',
options: [
{ id: 'fraud', name: 'Financial fraud or misappropriation' },
{ id: 'harassment', name: 'Harassment or hostile work environment' },
{ id: 'discrimination', name: 'Discrimination (race, gender, age, disability, etc.)' },
{ id: 'safety', name: 'Health and safety violation' },
{ id: 'conflict', name: 'Conflict of interest' },
{ id: 'data', name: 'Data privacy or security breach' },
{ id: 'policy', name: 'Company policy violation' },
{ id: 'legal', name: 'Legal or regulatory violation' },
{ id: 'retaliation', name: 'Retaliation for previous report' },
{ id: 'other', name: 'Other concern' }
],
orientation: 'vertical',
isRequired: true
});
});
categorySection.addRow(row => {
row.addTextbox('otherType', {
label: 'Please describe the type of concern:',
placeholder: 'Briefly describe the category...',
isVisible: () => categorySection.radioButton('incidentType')?.value() === 'other',
isRequired: () => categorySection.radioButton('incidentType')?.value() === 'other'
});
});
categorySection.addRow(row => {
row.addDropdown('severity', {
label: 'How would you rate the severity?',
options: [
{ id: 'low', name: 'Low - Minor policy concern' },
{ id: 'medium', name: 'Medium - Significant issue requiring attention' },
{ id: 'high', name: 'High - Serious violation or risk' },
{ id: 'critical', name: 'Critical - Immediate danger or major fraud' }
],
isRequired: true,
isVisible: () => categorySection.radioButton('incidentType')?.value() !== null
});
});
// ============================================
// SECTION 2: Incident Details
// ============================================
const detailsSection = form.addSubform('details', {
title: () => {
const type = categorySection.radioButton('incidentType')?.value();
const labels: Record<string, string> = {
'fraud': 'Fraud Details',
'harassment': 'Harassment Details',
'discrimination': 'Discrimination Details',
'safety': 'Safety Violation Details',
'conflict': 'Conflict of Interest Details',
'data': 'Data Breach Details',
'policy': 'Policy Violation Details',
'legal': 'Legal Violation Details',
'retaliation': 'Retaliation Details',
'other': 'Incident Details'
};
return labels[type || ''] || 'Incident Details';
},
isVisible: () => categorySection.dropdown('severity')?.value() !== null
});
// Date and location
detailsSection.addRow(row => {
row.addDropdown('whenOccurred', {
label: 'When did this occur?',
options: [
{ id: 'today', name: 'Today' },
{ id: 'this-week', name: 'Within the past week' },
{ id: 'this-month', name: 'Within the past month' },
{ id: 'past-months', name: '1-6 months ago' },
{ id: 'past-year', name: 'More than 6 months ago' },
{ id: 'ongoing', name: 'Ongoing/Recurring' }
],
isRequired: true
}, '1fr');
row.addTextbox('locationOccurred', {
label: 'Where did this occur?',
placeholder: 'Department, office, location, or online',
tooltip: 'Be as specific as you are comfortable with'
}, '1fr');
});
// Conditional fraud details
const fraudDetails = detailsSection.addSubform('fraudDetails', {
isVisible: () => categorySection.radioButton('incidentType')?.value() === 'fraud',
customStyles: { backgroundColor: '#fef2f2', padding: '12px', borderRadius: '6px' }
});
fraudDetails.addRow(row => {
row.addCheckboxList('fraudType', {
label: 'Type of financial misconduct:',
options: [
{ id: 'embezzlement', name: 'Embezzlement' },
{ id: 'expense', name: 'Expense fraud' },
{ id: 'vendor', name: 'Vendor/procurement fraud' },
{ id: 'payroll', name: 'Payroll fraud' },
{ id: 'financial', name: 'Financial statement manipulation' },
{ id: 'bribery', name: 'Bribery or kickbacks' },
{ id: 'theft', name: 'Asset theft' },
{ id: 'other', name: 'Other' }
],
orientation: 'vertical'
});
});
fraudDetails.addRow(row => {
row.addMoney('estimatedAmount', {
label: 'Estimated amount involved (if known)',
currency: '$',
placeholder: 'Leave blank if unknown'
});
});
// Conditional harassment details
const harassmentDetails = detailsSection.addSubform('harassmentDetails', {
isVisible: () => categorySection.radioButton('incidentType')?.value() === 'harassment',
customStyles: { backgroundColor: '#fef2f2', padding: '12px', borderRadius: '6px' }
});
harassmentDetails.addRow(row => {
row.addCheckboxList('harassmentType', {
label: 'Type of harassment:',
options: [
{ id: 'verbal', name: 'Verbal harassment' },
{ id: 'physical', name: 'Physical harassment' },
{ id: 'sexual', name: 'Sexual harassment' },
{ id: 'bullying', name: 'Bullying/intimidation' },
{ id: 'cyber', name: 'Cyber harassment' },
{ id: 'quid-pro-quo', name: 'Quid pro quo' },
{ id: 'other', name: 'Other' }
],
orientation: 'vertical'
});
});
harassmentDetails.addRow(row => {
row.addRadioButton('harassmentFrequency', {
label: 'How often has this occurred?',
options: [
{ id: 'once', name: 'Single incident' },
{ id: 'few', name: 'A few times' },
{ id: 'frequent', name: 'Frequently/Ongoing' }
],
orientation: 'horizontal'
});
});
// Conditional safety details
const safetyDetails = detailsSection.addSubform('safetyDetails', {
isVisible: () => categorySection.radioButton('incidentType')?.value() === 'safety',
customStyles: { backgroundColor: '#fef2f2', padding: '12px', borderRadius: '6px' }
});
safetyDetails.addRow(row => {
row.addCheckboxList('safetyType', {
label: 'Type of safety concern:',
options: [
{ id: 'equipment', name: 'Unsafe equipment' },
{ id: 'conditions', name: 'Hazardous conditions' },
{ id: 'training', name: 'Inadequate safety training' },
{ id: 'ppe', name: 'Missing/inadequate PPE' },
{ id: 'chemical', name: 'Chemical/substance hazard' },
{ id: 'ergonomic', name: 'Ergonomic hazard' },
{ id: 'fire', name: 'Fire safety violation' },
{ id: 'other', name: 'Other' }
],
orientation: 'vertical'
});
});
safetyDetails.addRow(row => {
row.addRadioButton('injuryOccurred', {
label: 'Has anyone been injured?',
options: [
{ id: 'yes', name: 'Yes' },
{ id: 'no', name: 'No' },
{ id: 'near-miss', name: 'Near miss' }
],
orientation: 'horizontal'
});
});
// Conditional data breach details
const dataDetails = detailsSection.addSubform('dataDetails', {
isVisible: () => categorySection.radioButton('incidentType')?.value() === 'data',
customStyles: { backgroundColor: '#fef2f2', padding: '12px', borderRadius: '6px' }
});
dataDetails.addRow(row => {
row.addCheckboxList('dataType', {
label: 'Type of data involved:',
options: [
{ id: 'personal', name: 'Personal employee data' },
{ id: 'customer', name: 'Customer data' },
{ id: 'financial', name: 'Financial data' },
{ id: 'health', name: 'Health/medical data' },
{ id: 'trade', name: 'Trade secrets/IP' },
{ id: 'credentials', name: 'Passwords/credentials' },
{ id: 'other', name: 'Other sensitive data' }
],
orientation: 'vertical'
});
});
dataDetails.addRow(row => {
row.addRadioButton('dataExposed', {
label: 'Was data exposed externally?',
options: [
{ id: 'yes', name: 'Yes, confirmed' },
{ id: 'possibly', name: 'Possibly' },
{ id: 'no', name: 'No, internal only' },
{ id: 'unknown', name: 'Unknown' }
],
orientation: 'horizontal'
});
});
// Main description (always shown)
detailsSection.addSpacer({ height: '20px' });
detailsSection.addRow(row => {
row.addTextarea('description', {
label: 'Please describe what happened:',
placeholder: 'Provide as much detail as you can about the incident. Include what you observed, when it happened, and any relevant context...',
rows: 6,
isRequired: true
});
});
// ============================================
// SECTION 3: People Involved
// ============================================
const peopleSection = form.addSubform('people', {
title: 'People Involved',
isVisible: () => (detailsSection.textarea('description')?.value()?.length ?? 0) > 0
});
peopleSection.addRow(row => {
row.addTextPanel('peopleNote', {
computedValue: () => 'Providing names is optional but helps the investigation. You may use descriptions instead (e.g., "manager in Finance department").',
customStyles: { fontSize: '13px', color: '#6b7280', marginBottom: '12px' }
});
});
peopleSection.addRow(row => {
row.addTextarea('personsInvolved', {
label: 'Who was involved in the incident?',
placeholder: 'Names, titles, or descriptions of people involved...',
rows: 3
});
});
peopleSection.addRow(row => {
row.addTextarea('witnesses', {
label: 'Were there any witnesses?',
placeholder: 'Names or descriptions of anyone who may have witnessed the incident...',
rows: 2
});
});
peopleSection.addRow(row => {
row.addRadioButton('previouslyReported', {
label: 'Have you reported this concern before?',
options: [
{ id: 'no', name: 'No, this is my first report' },
{ id: 'yes-internal', name: 'Yes, internally (manager, HR, etc.)' },
{ id: 'yes-external', name: 'Yes, to external authorities' }
],
orientation: 'vertical'
});
});
peopleSection.addRow(row => {
row.addTextarea('previousReportDetails', {
label: 'What was the outcome of your previous report?',
placeholder: 'Describe what happened when you previously reported this...',
rows: 2,
isVisible: () => {
const prev = peopleSection.radioButton('previouslyReported')?.value();
return prev === 'yes-internal' || prev === 'yes-external';
}
});
});
// ============================================
// SECTION 4: Evidence
// ============================================
const evidenceSection = form.addSubform('evidence', {
title: 'Supporting Information',
isVisible: () => (detailsSection.textarea('description')?.value()?.length ?? 0) > 0
});
evidenceSection.addRow(row => {
row.addRadioButton('hasEvidence', {
label: 'Do you have any evidence or documentation?',
options: [
{ id: 'yes', name: 'Yes' },
{ id: 'no', name: 'No' },
{ id: 'can-obtain', name: 'I could potentially obtain some' }
],
orientation: 'horizontal'
});
});
evidenceSection.addRow(row => {
row.addCheckboxList('evidenceTypes', {
label: 'What type of evidence do you have?',
options: [
{ id: 'documents', name: 'Documents/Files' },
{ id: 'emails', name: 'Emails/Messages' },
{ id: 'photos', name: 'Photos/Screenshots' },
{ id: 'recordings', name: 'Audio/Video recordings' },
{ id: 'financial', name: 'Financial records' },
{ id: 'physical', name: 'Physical evidence' },
{ id: 'other', name: 'Other' }
],
orientation: 'vertical',
isVisible: () => evidenceSection.radioButton('hasEvidence')?.value() === 'yes'
});
});
evidenceSection.addRow(row => {
row.addTextarea('evidenceDescription', {
label: 'Please describe the evidence you have:',
placeholder: 'Describe what evidence exists and where it can be found...',
rows: 3,
isVisible: () => evidenceSection.radioButton('hasEvidence')?.value() === 'yes'
});
});
// ============================================
// SECTION 5: Contact (Optional)
// ============================================
const contactSection = form.addSubform('contact', {
title: 'Follow-Up Contact (Optional)',
isVisible: () => (detailsSection.textarea('description')?.value()?.length ?? 0) > 0,
customStyles: { backgroundColor: '#f0f9ff', padding: '16px', borderRadius: '8px' }
});
contactSection.addRow(row => {
row.addTextPanel('contactNote', {
computedValue: () => 'Providing contact information is entirely optional. If you do, it allows investigators to follow up with questions or provide updates on the investigation.',
customStyles: { fontSize: '13px', color: '#6b7280', marginBottom: '12px' }
});
});
contactSection.addRow(row => {
row.addRadioButton('allowContact', {
label: 'May we contact you for follow-up?',
options: [
{ id: 'no', name: 'No, I wish to remain completely anonymous' },
{ id: 'yes-anonymous', name: 'Yes, but keep my identity confidential' },
{ id: 'yes', name: 'Yes, I\'m willing to be identified if necessary' }
],
orientation: 'vertical'
});
});
contactSection.addRow(row => {
row.addDropdown('contactMethod', {
label: 'Preferred contact method:',
options: [
{ id: 'email', name: 'Email' },
{ id: 'phone', name: 'Phone' },
{ id: 'secure', name: 'Secure messaging platform' }
],
isVisible: () => {
const allow = contactSection.radioButton('allowContact')?.value();
return allow === 'yes-anonymous' || allow === 'yes';
}
}, '1fr');
row.addTextbox('contactInfo', {
label: 'Contact information:',
placeholder: 'Email address or phone number',
isVisible: () => {
const allow = contactSection.radioButton('allowContact')?.value();
return allow === 'yes-anonymous' || allow === 'yes';
}
}, '1fr');
});
// ============================================
// SECTION 6: Final Acknowledgment
// ============================================
const finalSection = form.addSubform('final', {
title: 'Submission',
isVisible: () => (detailsSection.textarea('description')?.value()?.length ?? 0) > 0
});
finalSection.addRow(row => {
row.addCheckbox('goodFaith', {
label: 'I am submitting this report in good faith and believe the information to be true to the best of my knowledge',
isRequired: true
});
});
finalSection.addRow(row => {
row.addCheckbox('understandProcess', {
label: 'I understand that this report will be investigated and appropriate action will be taken',
isRequired: true
});
});
// Summary
finalSection.addSpacer({ height: '20px' });
finalSection.addRow(row => {
row.addTextPanel('summaryContent', {
computedValue: () => {
const incidentType = categorySection.radioButton('incidentType')?.value();
const severity = categorySection.dropdown('severity')?.value();
const when = detailsSection.dropdown('whenOccurred')?.value();
const allowContact = contactSection.radioButton('allowContact')?.value();
const typeLabels: Record<string, string> = {
'fraud': 'Financial fraud',
'harassment': 'Harassment',
'discrimination': 'Discrimination',
'safety': 'Safety violation',
'conflict': 'Conflict of interest',
'data': 'Data breach',
'policy': 'Policy violation',
'legal': 'Legal violation',
'retaliation': 'Retaliation',
'other': 'Other concern'
};
const severityLabels: Record<string, string> = {
'low': 'Low',
'medium': 'Medium',
'high': 'High',
'critical': 'Critical'
};
let summary = 'REPORT SUMMARY\n';
summary += `${'─'.repeat(25)}\n\n`;
summary += `Category: ${typeLabels[incidentType || ''] || 'Not specified'}\n`;
summary += `Severity: ${severityLabels[severity || ''] || 'Not rated'}\n`;
summary += `Timing: ${when || 'Not specified'}\n`;
summary += `\nContact: ${allowContact === 'no' ? 'Anonymous' : allowContact === 'yes-anonymous' ? 'Confidential' : 'May identify'}`;
return summary;
},
customStyles: {
whiteSpace: 'pre-wrap',
fontFamily: 'monospace',
fontSize: '13px',
padding: '12px',
backgroundColor: '#f8fafc',
borderRadius: '6px',
border: '1px solid #e2e8f0'
}
});
});
// ============================================
// FORM CONFIGURATION
// ============================================
form.configureSubmitButton({
label: 'Submit Report',
isVisible: () => {
const goodFaith = finalSection.checkbox('goodFaith')?.value();
const understand = finalSection.checkbox('understandProcess')?.value();
return goodFaith === true && understand === true;
}
});
form.configureCompletionScreen({
type: 'text',
title: 'Report Submitted Successfully',
message: 'Your report has been securely received. It will be reviewed by the appropriate compliance personnel. If you provided contact information, you may be contacted for follow-up. Thank you for helping maintain our ethical standards.'
});
}