export function foodDeliveryFeedback(form: FormTs) {
// Food Delivery Feedback Form - Complete delivery experience rating
// Demonstrates: StarRating, EmojiRating, RatingScale, MatrixQuestion, Slider, conditional sections
// ============================================
// HEADER
// ============================================
form.addRow(row => {
row.addTextPanel('header', {
label: 'Rate Your Delivery',
computedValue: () => 'How was your food delivery experience?',
customStyles: {
backgroundColor: '#f97316',
color: 'white',
padding: '24px',
borderRadius: '12px',
textAlign: 'center'
}
});
});
// ============================================
// SECTION 1: Quick Overall Rating
// ============================================
const quickSection = form.addSubform('quickSection', {
title: 'Quick Rating',
customStyles: () => {
const rating = quickSection.starRating('overallDelivery')?.value();
if (rating !== null && rating !== undefined) {
if (rating >= 4) return { backgroundColor: '#d1fae5', padding: '16px', borderRadius: '8px' };
if (rating >= 3) return { backgroundColor: '#fef3c7', padding: '16px', borderRadius: '8px' };
return { backgroundColor: '#fee2e2', padding: '16px', borderRadius: '8px' };
}
return { padding: '16px', borderRadius: '8px', border: '1px dashed #f97316' };
}
});
quickSection.addRow(row => {
row.addStarRating('overallDelivery', {
label: 'Overall delivery experience',
maxStars: 5,
size: 'xl',
alignment: 'center',
showConfettiOnMax: true
});
});
quickSection.addRow(row => {
row.addEmojiRating('deliveryMood', {
label: 'How did you feel when your order arrived?',
preset: 'satisfaction',
size: 'lg',
showLabels: true,
alignment: 'center'
});
});
// ============================================
// SECTION 2: Order Accuracy
// ============================================
const accuracySection = form.addSubform('accuracySection', {
title: 'Order Accuracy',
isVisible: () => quickSection.starRating('overallDelivery')?.value() !== null,
customStyles: { padding: '16px', borderRadius: '8px', border: '1px solid #e2e8f0' }
});
accuracySection.addRow(row => {
row.addRadioButton('orderCorrect', {
label: 'Was your order complete and correct?',
options: [
{ id: 'perfect', name: 'Yes, everything was perfect' },
{ id: 'minor', name: 'Minor issues (correct items, small mistakes)' },
{ id: 'issues', name: 'Some items were wrong or missing' },
{ id: 'major', name: 'Major problems with my order' }
],
orientation: 'vertical'
});
});
// Conditional: Issues with order
const issuesSubform = accuracySection.addSubform('issuesSubform', {
isVisible: () => {
const accuracy = accuracySection.radioButton('orderCorrect')?.value();
return accuracy === 'minor' || accuracy === 'issues' || accuracy === 'major';
},
customStyles: { backgroundColor: '#fef3c7', padding: '16px', borderRadius: '8px', marginTop: '12px' }
});
issuesSubform.addRow(row => {
row.addCheckboxList('issueTypes', {
label: 'What issues did you experience?',
options: [
{ id: 'missing', name: 'Missing items' },
{ id: 'wrong', name: 'Wrong items received' },
{ id: 'quantity', name: 'Incorrect quantity' },
{ id: 'customization', name: 'Special instructions not followed' },
{ id: 'damaged', name: 'Damaged or spilled' },
{ id: 'packaging', name: 'Poor packaging' }
],
orientation: 'vertical'
});
});
issuesSubform.addRow(row => {
row.addTextarea('issueDetails', {
label: 'Please describe the issue',
placeholder: 'Tell us what went wrong so we can make it right...',
rows: 2,
autoExpand: true
});
});
// ============================================
// SECTION 3: Food Quality
// ============================================
const foodSection = form.addSubform('foodSection', {
title: 'Food Quality',
isVisible: () => quickSection.starRating('overallDelivery')?.value() !== null
});
foodSection.addRow(row => {
row.addMatrixQuestion('foodRatings', {
label: 'Rate the following aspects of your food:',
rows: [
{ id: 'temperature', label: 'Temperature on Arrival', description: 'Hot food hot, cold food cold', isRequired: true },
{ id: 'freshness', label: 'Freshness & Quality', description: 'Taste and appearance', isRequired: true },
{ id: 'portion', label: 'Portion Size', description: 'Amount of food for price', isRequired: false },
{ id: 'packaging', label: 'Packaging Quality', description: 'Protection and presentation', isRequired: false }
],
columns: [
{ id: '1', label: 'Poor' },
{ id: '2', label: 'Fair' },
{ id: '3', label: 'Good' },
{ id: '4', label: 'Very Good' },
{ id: '5', label: 'Excellent' }
],
striped: true,
fullWidth: true
});
});
// Temperature slider for detailed feedback
const tempSection = foodSection.addSubform('tempSection', {
isVisible: () => {
const rating = foodSection.matrixQuestion('foodRatings')?.getRowValue('temperature');
return rating === '1' || rating === '2';
},
customStyles: { backgroundColor: '#fee2e2', padding: '16px', borderRadius: '8px', marginTop: '12px' }
});
tempSection.addRow(row => {
row.addRadioButton('tempIssue', {
label: 'What was the temperature issue?',
options: [
{ id: 'cold', name: 'Hot food arrived cold/lukewarm' },
{ id: 'warm', name: 'Cold food arrived warm' },
{ id: 'both', name: 'Both hot and cold items had issues' }
],
orientation: 'vertical'
});
});
// ============================================
// SECTION 4: Delivery Experience
// ============================================
const deliverySection = form.addSubform('deliverySection', {
title: 'Delivery Speed & Driver',
isVisible: () => quickSection.starRating('overallDelivery')?.value() !== null
});
deliverySection.addRow(row => {
row.addRatingScale('deliverySpeed', {
preset: 'likert-5',
label: 'The delivery arrived on time or faster than expected',
lowLabel: 'Very Late',
highLabel: 'Early/On Time',
alignment: 'center'
});
});
deliverySection.addRow(row => {
row.addSlider('waitTime', {
label: 'Approximately how long did you wait? (minutes)',
min: 0,
max: 120,
step: 5,
showValue: true,
unit: 'min',
defaultValue: 30
});
});
// Driver ratings
const driverSection = deliverySection.addSubform('driverSection', {
title: 'Delivery Driver'
});
driverSection.addRow(row => {
row.addStarRating('driverRating', {
label: 'Driver professionalism',
maxStars: 5,
size: 'lg',
alignment: 'center'
}, '1fr');
row.addStarRating('communicationRating', {
label: 'Communication (updates, finding address)',
maxStars: 5,
size: 'lg',
alignment: 'center'
}, '1fr');
});
driverSection.addRow(row => {
row.addSuggestionChips('driverPositives', {
label: 'What did the driver do well?',
suggestions: [
{ id: 'friendly', name: 'Friendly' },
{ id: 'fast', name: 'Fast' },
{ id: 'careful', name: 'Careful with food' },
{ id: 'communication', name: 'Good updates' },
{ id: 'instructions', name: 'Followed delivery instructions' },
{ id: 'contactless', name: 'Proper contactless delivery' }
],
max: 4,
alignment: 'center'
});
});
// ============================================
// SECTION 5: Would Order Again
// ============================================
const intentSection = form.addSubform('intentSection', {
title: 'Would You Order Again?',
isVisible: () => quickSection.starRating('overallDelivery')?.value() !== null,
customStyles: () => {
const thumbs = intentSection.thumbRating('orderAgain')?.value();
if (thumbs === 'up') return { backgroundColor: '#d1fae5', padding: '16px', borderRadius: '8px' };
if (thumbs === 'down') return { backgroundColor: '#fee2e2', padding: '16px', borderRadius: '8px' };
return { padding: '16px', borderRadius: '8px', border: '1px dashed #cbd5e1' };
}
});
intentSection.addRow(row => {
row.addThumbRating('orderAgain', {
label: 'Would you order from us again?',
showLabels: true,
upLabel: 'Yes!',
downLabel: 'No',
alignment: 'center',
size: 'lg'
});
});
intentSection.addRow(row => {
row.addRatingScale('recommendLikelihood', {
preset: 'nps',
label: 'How likely are you to recommend us to friends?',
showSegmentColors: true,
showCategoryLabel: true,
alignment: 'center',
isVisible: () => intentSection.thumbRating('orderAgain')?.value() !== null
});
});
// ============================================
// SECTION 6: Additional Feedback
// ============================================
const feedbackSection = form.addSubform('feedbackSection', {
title: 'Additional Feedback',
isVisible: () => quickSection.starRating('overallDelivery')?.value() !== null
});
feedbackSection.addSpacer();
feedbackSection.addRow(row => {
row.addTextarea('comments', {
label: 'Any other comments or suggestions?',
placeholder: 'Tell us how we can improve your next delivery...',
rows: 3,
autoExpand: true
});
});
// Contact for issues
const contactSection = feedbackSection.addSubform('contactSection', {
isVisible: () => {
const accuracy = accuracySection.radioButton('orderCorrect')?.value();
return accuracy === 'issues' || accuracy === 'major';
},
customStyles: { backgroundColor: '#fef3c7', padding: '16px', borderRadius: '8px', marginTop: '12px' }
});
contactSection.addRow(row => {
row.addTextPanel('contactPrompt', {
label: 'We want to make this right!',
computedValue: () => "We're sorry about the issues with your order. Leave your contact info and we'll reach out to resolve this."
});
});
contactSection.addRow(row => {
row.addEmail('contactEmail', {
label: 'Email for follow-up',
placeholder: 'your@email.com'
}, '1fr');
row.addTextbox('orderNumber', {
label: 'Order number (if known)',
placeholder: 'e.g., #12345'
}, '1fr');
});
// ============================================
// SECTION 7: Summary
// ============================================
const summarySection = form.addSubform('summarySection', {
title: 'Feedback Summary',
isVisible: () => quickSection.starRating('overallDelivery')?.value() !== null
});
summarySection.addRow(row => {
row.addTextPanel('summary', {
computedValue: () => {
const overall = quickSection.starRating('overallDelivery')?.value();
const mood = quickSection.emojiRating('deliveryMood')?.value();
const accuracy = accuracySection.radioButton('orderCorrect')?.value();
const driverRating = driverSection.starRating('driverRating')?.value();
const waitTime = deliverySection.slider('waitTime')?.value();
const orderAgain = intentSection.thumbRating('orderAgain')?.value();
const nps = intentSection.ratingScale('recommendLikelihood')?.npsCategory();
if (overall === null || overall === undefined) return '';
const accuracyLabels: Record<string, string> = {
'perfect': 'Perfect order',
'minor': 'Minor issues',
'issues': 'Some problems',
'major': 'Major problems'
};
const moodLabels: Record<string, string> = {
'very-bad': '😢',
'bad': '😕',
'neutral': '😐',
'good': '🙂',
'excellent': '😍'
};
let emoji = overall >= 4 ? '🎉' : overall >= 3 ? '😐' : '😟';
let summary = `${emoji} DELIVERY FEEDBACK\n`;
summary += `${'═'.repeat(25)}\n\n`;
summary += `Overall: ${'★'.repeat(overall)}${'☆'.repeat(5 - overall)} (${overall}/5)\n`;
if (mood) {
summary += `Mood: ${moodLabels[mood] || mood}\n`;
}
if (accuracy) {
summary += `\nOrder: ${accuracyLabels[accuracy]}\n`;
}
if (waitTime !== null && waitTime !== undefined) {
summary += `Wait: ${waitTime} minutes\n`;
}
if (driverRating) {
summary += `Driver: ${'★'.repeat(driverRating)}${'☆'.repeat(5 - driverRating)}\n`;
}
if (orderAgain) {
summary += `\nOrder again: ${orderAgain === 'up' ? '👍 Yes' : '👎 No'}`;
}
if (nps) {
summary += `\nNPS: ${nps.charAt(0).toUpperCase() + nps.slice(1)}`;
}
return summary;
},
customStyles: () => {
const overall = quickSection.starRating('overallDelivery')?.value();
const baseStyles = {
padding: '16px',
borderRadius: '8px',
whiteSpace: 'pre-wrap',
fontFamily: 'monospace',
fontSize: '13px'
};
if (overall !== null && overall !== undefined) {
if (overall >= 4) {
return { ...baseStyles, backgroundColor: '#d1fae5', borderLeft: '4px solid #10b981' };
} else if (overall >= 3) {
return { ...baseStyles, backgroundColor: '#fef3c7', borderLeft: '4px solid #f59e0b' };
} else {
return { ...baseStyles, backgroundColor: '#fee2e2', borderLeft: '4px solid #ef4444' };
}
}
return { ...baseStyles, backgroundColor: '#fff7ed', borderLeft: '4px solid #f97316' };
}
});
});
// ============================================
// FORM CONFIGURATION
// ============================================
form.configureSubmitButton({
label: 'Submit Rating',
isVisible: () => quickSection.starRating('overallDelivery')?.value() !== null
});
form.configureCompletionScreen({
type: 'text',
title: 'Thanks for Your Feedback!',
message: 'Your rating helps us deliver better experiences. We appreciate you taking the time to share your thoughts!'
});
}