export function bankingBranch(form: FormTs) {
// Bank Branch Visit Feedback Form
// Demonstrates: Slider, StarRating, MatrixQuestion, RatingScale (NPS), Dropdown, ThumbRating
// ============================================
// HEADER
// ============================================
form.addRow(row => {
row.addTextPanel('header', {
label: 'Branch Visit Feedback',
computedValue: () => 'Your feedback helps us serve you better.',
customStyles: {
backgroundColor: '#1e40af',
color: 'white',
padding: '24px',
borderRadius: '12px',
textAlign: 'center'
}
});
});
// ============================================
// SECTION 1: Visit Details
// ============================================
const visitSection = form.addSubform('visit', {
title: 'Visit Details'
});
visitSection.addRow(row => {
row.addDropdown('visitPurpose', {
label: 'What was the main purpose of your visit?',
options: [
{ id: 'account', name: 'Account opening/closing' },
{ id: 'deposit-withdraw', name: 'Deposit or withdrawal' },
{ id: 'loan', name: 'Loan inquiry/application' },
{ id: 'mortgage', name: 'Mortgage services' },
{ id: 'cards', name: 'Credit/debit card services' },
{ id: 'investment', name: 'Investment advice' },
{ id: 'problem', name: 'Problem resolution' },
{ id: 'general', name: 'General inquiry' },
{ id: 'other', name: 'Other' }
],
placeholder: 'Select the purpose...',
isRequired: true
}, '1fr');
row.addDatepicker('visitDate', {
label: 'Visit date',
maxDate: () => new Date().toISOString()
}, '1fr');
});
visitSection.addRow(row => {
row.addThumbRating('issueResolved', {
label: 'Was your matter fully resolved during this visit?',
showLabels: true,
upLabel: 'Yes, fully resolved',
downLabel: 'No, not resolved',
size: 'lg',
alignment: 'center'
});
});
visitSection.addRow(row => {
row.addTextarea('unresolvedDetails', {
label: 'What remains unresolved?',
placeholder: 'Please describe what could not be completed...',
rows: 2,
isVisible: () => visitSection.thumbRating('issueResolved')?.value() === 'down',
isRequired: () => visitSection.thumbRating('issueResolved')?.value() === 'down'
});
});
// ============================================
// SECTION 2: Wait Time Experience
// ============================================
const waitSection = form.addSubform('waitTime', {
title: 'Wait Time',
customStyles: () => {
const satisfaction = waitSection.ratingScale('waitSatisfaction')?.value();
if (satisfaction !== null && satisfaction !== undefined && satisfaction <= 2) {
return { backgroundColor: '#fef2f2', padding: '16px', borderRadius: '8px' };
}
if (satisfaction !== null && satisfaction !== undefined && satisfaction >= 4) {
return { backgroundColor: '#ecfdf5', padding: '16px', borderRadius: '8px' };
}
return {};
}
});
waitSection.addRow(row => {
row.addSlider('waitMinutes', {
label: 'Approximately how long did you wait? (minutes)',
min: 0,
max: 60,
step: 5,
unit: 'min',
defaultValue: 10
});
});
waitSection.addRow(row => {
row.addRatingScale('waitSatisfaction', {
label: 'How satisfied were you with the wait time?',
preset: 'satisfaction',
alignment: 'center',
isRequired: true
});
});
waitSection.addRow(row => {
row.addRadioButton('waitComfort', {
label: 'How was the waiting environment?',
options: [
{ id: 'comfortable', name: 'Comfortable and well-organized' },
{ id: 'adequate', name: 'Adequate' },
{ id: 'crowded', name: 'Crowded but manageable' },
{ id: 'uncomfortable', name: 'Uncomfortable' }
],
orientation: 'vertical',
isVisible: () => {
const wait = waitSection.slider('waitMinutes')?.value();
return wait !== null && wait !== undefined && wait > 5;
}
});
});
// ============================================
// SECTION 3: Staff Service
// ============================================
const staffSection = form.addSubform('staff', {
title: 'Staff Service'
});
staffSection.addRow(row => {
row.addStarRating('overallStaff', {
label: 'How would you rate our staff overall?',
maxStars: 5,
size: 'lg',
alignment: 'center'
});
});
staffSection.addRow(row => {
row.addMatrixQuestion('staffAttributes', {
label: 'Please rate our staff on the following:',
rows: [
{ id: 'friendly', label: 'Friendliness and courtesy' },
{ id: 'knowledge', label: 'Product knowledge' },
{ id: 'listening', label: 'Listening to your needs' },
{ id: 'explanations', label: 'Clear explanations' },
{ id: 'efficiency', label: 'Efficiency and speed' },
{ id: 'professionalism', label: 'Professional appearance' }
],
columns: [
{ id: 'poor', label: 'Poor' },
{ id: 'fair', label: 'Fair' },
{ id: 'good', label: 'Good' },
{ id: 'excellent', label: 'Excellent' }
],
fullWidth: true
});
});
staffSection.addSpacer({ height: '16px' });
staffSection.addRow(row => {
row.addCheckbox('staffRecognition', {
label: 'Would you like to recognize a specific staff member for exceptional service?'
});
});
staffSection.addRow(row => {
row.addTextbox('staffName', {
label: 'Staff member name (if known)',
placeholder: 'Enter name...',
isVisible: () => staffSection.checkbox('staffRecognition')?.value() === true
}, '1fr');
row.addTextarea('staffPraise', {
label: 'What did they do well?',
placeholder: 'Describe the exceptional service...',
rows: 2,
isVisible: () => staffSection.checkbox('staffRecognition')?.value() === true
}, '1fr');
});
// ============================================
// SECTION 4: Branch Facilities
// ============================================
const facilitySection = form.addSubform('facilities', {
title: 'Branch Facilities'
});
facilitySection.addRow(row => {
row.addStarRating('cleanliness', {
label: 'Cleanliness',
maxStars: 5,
size: 'md',
alignment: 'center'
}, '1fr');
row.addStarRating('accessibility', {
label: 'Accessibility',
maxStars: 5,
size: 'md',
alignment: 'center'
}, '1fr');
row.addStarRating('parking', {
label: 'Parking availability',
maxStars: 5,
size: 'md',
alignment: 'center'
}, '1fr');
});
facilitySection.addRow(row => {
row.addCheckboxList('facilitiesUsed', {
label: 'Which facilities did you use?',
options: [
{ id: 'teller', name: 'Teller counter' },
{ id: 'atm', name: 'ATM/Self-service' },
{ id: 'private', name: 'Private office/consultation room' },
{ id: 'waiting', name: 'Waiting area' },
{ id: 'digital', name: 'Digital banking kiosk' }
],
orientation: 'horizontal'
});
});
// ============================================
// SECTION 5: NPS & Recommendation
// ============================================
const npsSection = form.addSubform('recommendation', {
title: 'Recommendation',
customStyles: () => {
const category = npsSection.ratingScale('nps')?.npsCategory();
if (category === 'promoter') return { backgroundColor: '#ecfdf5', padding: '16px', borderRadius: '8px' };
if (category === 'detractor') return { backgroundColor: '#fef2f2', padding: '16px', borderRadius: '8px' };
if (category === 'passive') return { backgroundColor: '#fefce8', padding: '16px', borderRadius: '8px' };
return {};
}
});
npsSection.addRow(row => {
row.addRatingScale('nps', {
label: 'How likely are you to recommend our branch to friends or family?',
preset: 'nps',
showCategoryLabel: true,
showSegmentColors: true,
isRequired: true
});
});
npsSection.addRow(row => {
row.addTextarea('npsReason', {
label: () => {
const category = npsSection.ratingScale('nps')?.npsCategory();
if (category === 'promoter') return 'Thank you! What makes you recommend us?';
if (category === 'passive') return 'What could we improve to earn a higher rating?';
if (category === 'detractor') return 'We are sorry. What went wrong?';
return 'Please share your thoughts';
},
placeholder: 'Your feedback is valuable...',
rows: 3,
isVisible: () => npsSection.ratingScale('nps')?.value() !== null
});
});
// ============================================
// SECTION 6: Additional Feedback
// ============================================
const additionalSection = form.addSubform('additional', {
title: 'Additional Feedback',
isVisible: () => visitSection.thumbRating('issueResolved')?.value() !== null
});
additionalSection.addRow(row => {
row.addRadioButton('preferredChannel', {
label: 'How do you prefer to bank with us?',
options: [
{ id: 'branch', name: 'In-branch visits' },
{ id: 'online', name: 'Online banking' },
{ id: 'mobile', name: 'Mobile app' },
{ id: 'phone', name: 'Phone banking' },
{ id: 'mix', name: 'Mix of channels' }
],
orientation: 'horizontal'
});
});
additionalSection.addSpacer({ height: '16px' });
additionalSection.addRow(row => {
row.addTextarea('generalComments', {
label: 'Any other comments or suggestions?',
placeholder: 'We welcome all feedback...',
rows: 3
});
});
// ============================================
// SECTION 7: Contact for Follow-up
// ============================================
const contactSection = form.addSubform('contact', {
title: 'Contact for Follow-up',
isVisible: () => {
const resolved = visitSection.thumbRating('issueResolved')?.value();
const npsCategory = npsSection.ratingScale('nps')?.npsCategory();
return resolved === 'down' || npsCategory === 'detractor';
},
customStyles: { backgroundColor: '#fef3c7', padding: '16px', borderRadius: '8px' }
});
contactSection.addRow(row => {
row.addTextPanel('contactInfo', {
computedValue: () => 'We would like to address your concerns. May we contact you?',
customStyles: { fontSize: '14px', color: '#92400e' }
});
});
contactSection.addRow(row => {
row.addCheckbox('wantsContact', {
label: 'Yes, please contact me to resolve my issue'
});
});
contactSection.addRow(row => {
row.addTextbox('contactPhone', {
label: 'Phone number',
placeholder: 'Your phone number...',
isVisible: () => contactSection.checkbox('wantsContact')?.value() === true
}, '1fr');
row.addEmail('contactEmail', {
label: 'Email address',
placeholder: 'Your email...',
isVisible: () => contactSection.checkbox('wantsContact')?.value() === true
}, '1fr');
});
// ============================================
// SECTION 8: Summary
// ============================================
const summarySection = form.addSubform('summary', {
title: 'Visit Summary',
isVisible: () => {
const staff = staffSection.starRating('overallStaff')?.value();
const nps = npsSection.ratingScale('nps')?.value();
return staff !== null && nps !== null;
}
});
summarySection.addRow(row => {
row.addTextPanel('summaryContent', {
computedValue: () => {
const purpose = visitSection.dropdown('visitPurpose')?.value();
const resolved = visitSection.thumbRating('issueResolved')?.value();
const waitTime = waitSection.slider('waitMinutes')?.value();
const waitSat = waitSection.ratingScale('waitSatisfaction')?.value();
const staffRating = staffSection.starRating('overallStaff')?.value();
const nps = npsSection.ratingScale('nps')?.value();
const npsCategory = npsSection.ratingScale('nps')?.npsCategory();
const purposeLabels: Record<string, string> = {
'account': 'Account services',
'deposit-withdraw': 'Deposit/Withdrawal',
'loan': 'Loan inquiry',
'mortgage': 'Mortgage services',
'cards': 'Card services',
'investment': 'Investment advice',
'problem': 'Problem resolution',
'general': 'General inquiry',
'other': 'Other'
};
let summary = 'Branch Visit Summary\n';
summary += '═'.repeat(30) + '\n\n';
if (purpose) {
summary += `Purpose: ${purposeLabels[purpose] || purpose}\n`;
}
if (resolved) {
summary += `Resolved: ${resolved === 'up' ? 'Yes' : 'No'}\n`;
}
if (waitTime !== null && waitTime !== undefined) {
summary += `\nWait Time: ${waitTime} minutes\n`;
if (waitSat) {
const satLabels = ['', 'Very Dissatisfied', 'Dissatisfied', 'Neutral', 'Satisfied', 'Very Satisfied'];
summary += `Wait Satisfaction: ${satLabels[waitSat]}\n`;
}
}
if (staffRating) {
summary += `\nStaff Rating: ${'★'.repeat(staffRating)}${'☆'.repeat(5 - staffRating)} (${staffRating}/5)\n`;
}
if (nps !== null && nps !== undefined) {
summary += `\nNPS: ${nps}/10 (${npsCategory})\n`;
}
return summary;
},
customStyles: () => {
const npsCategory = npsSection.ratingScale('nps')?.npsCategory();
const baseStyles = {
padding: '16px',
borderRadius: '8px',
whiteSpace: 'pre-wrap',
fontFamily: 'monospace',
fontSize: '14px'
};
if (npsCategory === 'promoter') {
return { ...baseStyles, backgroundColor: '#ecfdf5', borderLeft: '4px solid #10b981' };
} else if (npsCategory === 'detractor') {
return { ...baseStyles, backgroundColor: '#fef2f2', borderLeft: '4px solid #ef4444' };
}
return { ...baseStyles, backgroundColor: '#f0f9ff', borderLeft: '4px solid #1e40af' };
}
});
});
// ============================================
// FORM CONFIGURATION
// ============================================
form.configureSubmitButton({
label: 'Submit Feedback',
isVisible: () => {
const staff = staffSection.starRating('overallStaff')?.value();
const nps = npsSection.ratingScale('nps')?.value();
return staff !== null && nps !== null;
}
});
form.configureCompletionScreen({
type: 'text',
title: 'Thank you for your feedback!',
message: 'Your input helps us improve our branch services. We value your business and are committed to serving you better.'
});
}