export function vendorEvaluation(form: FormTs) {
// Vendor Evaluation Form - Professional B2B supplier assessment
// Demonstrates: MatrixQuestion, Slider, StarRating, RatingScale (NPS), SuggestionChips, dynamic styling, conditional visibility
// ============================================
// HEADER
// ============================================
form.addRow(row => {
row.addTextPanel('header', {
label: 'Vendor Evaluation Form',
computedValue: () => 'Assess supplier performance across key business criteria',
customStyles: {
backgroundColor: '#0f766e',
color: 'white',
padding: '24px',
borderRadius: '12px',
textAlign: 'center'
}
});
});
// ============================================
// SECTION 1: Vendor Information
// ============================================
const vendorInfo = form.addSubform('vendorInfo', {
title: 'Vendor Information'
});
vendorInfo.addRow(row => {
row.addTextbox('vendorName', {
label: 'Vendor/Supplier Name',
placeholder: 'Enter vendor company name',
isRequired: true
}, '1fr');
row.addDropdown('vendorCategory', {
label: 'Vendor Category',
options: [
{ id: 'raw-materials', name: 'Raw Materials' },
{ id: 'components', name: 'Components/Parts' },
{ id: 'equipment', name: 'Equipment/Machinery' },
{ id: 'software', name: 'Software/Technology' },
{ id: 'services', name: 'Professional Services' },
{ id: 'logistics', name: 'Logistics/Shipping' },
{ id: 'facilities', name: 'Facilities/Maintenance' },
{ id: 'other', name: 'Other' }
],
placeholder: 'Select category',
isRequired: true
}, '1fr');
});
vendorInfo.addRow(row => {
row.addDropdown('relationshipLength', {
label: 'Relationship Duration',
options: [
{ id: 'new', name: 'New (< 6 months)' },
{ id: '6-12', name: '6-12 months' },
{ id: '1-2', name: '1-2 years' },
{ id: '2-5', name: '2-5 years' },
{ id: '5+', name: 'More than 5 years' }
],
placeholder: 'Select duration'
}, '1fr');
row.addDropdown('contractValue', {
label: 'Annual Contract Value',
options: [
{ id: 'small', name: 'Under $10,000' },
{ id: 'medium', name: '$10,000 - $50,000' },
{ id: 'large', name: '$50,000 - $250,000' },
{ id: 'strategic', name: 'Over $250,000' }
],
placeholder: 'Select value range'
}, '1fr');
});
vendorInfo.addRow(row => {
row.addTextbox('evaluatorName', {
label: 'Your Name',
placeholder: 'Enter your name'
}, '1fr');
row.addDropdown('evaluatorRole', {
label: 'Your Role',
options: [
{ id: 'procurement', name: 'Procurement/Purchasing' },
{ id: 'operations', name: 'Operations' },
{ id: 'quality', name: 'Quality Assurance' },
{ id: 'finance', name: 'Finance' },
{ id: 'management', name: 'Management' },
{ id: 'other', name: 'Other' }
],
placeholder: 'Select your role'
}, '1fr');
});
// ============================================
// SECTION 2: Performance Matrix
// ============================================
const performanceSection = form.addSubform('performance', {
title: 'Performance Evaluation',
isVisible: () => vendorInfo.textbox('vendorName')?.value() !== null && vendorInfo.textbox('vendorName')?.value() !== ''
});
performanceSection.addRow(row => {
row.addTextPanel('matrixInstructions', {
computedValue: () => 'Rate the vendor on each criterion based on your experience over the evaluation period.',
customStyles: {
backgroundColor: '#f0fdfa',
padding: '12px 16px',
borderRadius: '8px',
borderLeft: '4px solid #0f766e',
fontSize: '14px'
}
});
});
performanceSection.addRow(row => {
row.addMatrixQuestion('performanceMatrix', {
label: 'Performance Scorecard',
rows: [
{ id: 'quality', label: 'Product/Service Quality', description: 'Meets specifications, consistency, defect rate', isRequired: true },
{ id: 'delivery', label: 'On-Time Delivery', description: 'Meets deadlines, lead time accuracy', isRequired: true },
{ id: 'pricing', label: 'Pricing & Value', description: 'Competitive pricing, cost stability, value for money', isRequired: true },
{ id: 'communication', label: 'Communication', description: 'Responsiveness, clarity, proactive updates', isRequired: true },
{ id: 'support', label: 'Technical Support', description: 'Problem resolution, expertise, availability', isRequired: false },
{ id: 'compliance', label: 'Compliance & Documentation', description: 'Certifications, regulatory compliance, accurate invoicing', isRequired: false },
{ id: 'flexibility', label: 'Flexibility', description: 'Handles changes, rush orders, customization', isRequired: false },
{ id: 'innovation', label: 'Innovation', description: 'Continuous improvement, new solutions, technology adoption', isRequired: false }
],
columns: [
{ id: '1', label: 'Poor' },
{ id: '2', label: 'Below Average' },
{ id: '3', label: 'Average' },
{ id: '4', label: 'Good' },
{ id: '5', label: 'Excellent' }
],
striped: true,
fullWidth: true
});
});
// ============================================
// SECTION 3: Risk Assessment
// ============================================
const riskSection = form.addSubform('risk', {
title: 'Risk Assessment',
isVisible: () => vendorInfo.textbox('vendorName')?.value() !== null && vendorInfo.textbox('vendorName')?.value() !== '',
customStyles: () => {
const risk = riskSection.slider('riskLevel')?.value() || 0;
if (risk >= 70) return { backgroundColor: '#fee2e2', padding: '16px', borderRadius: '8px' };
if (risk >= 40) return { backgroundColor: '#fef3c7', padding: '16px', borderRadius: '8px' };
return { backgroundColor: '#d1fae5', padding: '16px', borderRadius: '8px' };
}
});
riskSection.addRow(row => {
row.addSlider('riskLevel', {
label: () => {
const risk = riskSection.slider('riskLevel')?.value() || 0;
if (risk >= 70) return 'Overall Vendor Risk Level: HIGH RISK';
if (risk >= 40) return 'Overall Vendor Risk Level: MEDIUM RISK';
return 'Overall Vendor Risk Level: LOW RISK';
},
min: 0,
max: 100,
step: 5,
defaultValue: 25,
unit: '%',
showValue: true
});
});
riskSection.addRow(row => {
row.addCheckboxList('riskFactors', {
label: 'Risk Factors Present (select all that apply)',
options: [
{ id: 'single-source', name: 'Single source dependency' },
{ id: 'financial', name: 'Financial stability concerns' },
{ id: 'geographic', name: 'Geographic/geopolitical risks' },
{ id: 'capacity', name: 'Capacity constraints' },
{ id: 'quality-history', name: 'History of quality issues' },
{ id: 'compliance', name: 'Compliance/regulatory risks' },
{ id: 'technology', name: 'Technology obsolescence risk' },
{ id: 'none', name: 'No significant risk factors' }
],
orientation: 'vertical'
});
});
riskSection.addSpacer();
riskSection.addRow(row => {
row.addTextarea('riskMitigation', {
label: 'Risk Mitigation Notes',
placeholder: 'Describe any risk mitigation strategies in place or recommended...',
rows: 2,
autoExpand: true,
isVisible: () => {
const risk = riskSection.slider('riskLevel')?.value() || 0;
return risk >= 40;
}
});
});
// ============================================
// SECTION 4: Strengths & Improvement Areas
// ============================================
const feedbackSection = form.addSubform('feedback', {
title: 'Strengths & Areas for Improvement',
isVisible: () => vendorInfo.textbox('vendorName')?.value() !== null && vendorInfo.textbox('vendorName')?.value() !== ''
});
feedbackSection.addRow(row => {
row.addSuggestionChips('strengths', {
label: 'Key Strengths (select up to 4)',
suggestions: [
{ id: 'reliable', name: 'Highly Reliable' },
{ id: 'quality', name: 'Superior Quality' },
{ id: 'price', name: 'Competitive Pricing' },
{ id: 'responsive', name: 'Very Responsive' },
{ id: 'innovative', name: 'Innovative' },
{ id: 'flexible', name: 'Flexible' },
{ id: 'technical', name: 'Strong Technical Expertise' },
{ id: 'partnership', name: 'True Partnership Mindset' }
],
max: 4,
alignment: 'left'
}, '1fr');
row.addSuggestionChips('improvements', {
label: 'Areas Needing Improvement',
suggestions: [
{ id: 'delivery', name: 'Delivery Times' },
{ id: 'quality', name: 'Quality Consistency' },
{ id: 'pricing', name: 'Pricing Transparency' },
{ id: 'communication', name: 'Communication' },
{ id: 'support', name: 'Technical Support' },
{ id: 'documentation', name: 'Documentation' },
{ id: 'flexibility', name: 'Flexibility' },
{ id: 'innovation', name: 'Innovation' }
],
max: 4,
alignment: 'left'
}, '1fr');
});
feedbackSection.addSpacer();
feedbackSection.addRow(row => {
row.addTextarea('feedbackComments', {
label: 'Additional Performance Comments',
placeholder: 'Provide specific examples of performance highlights or issues...',
rows: 3,
autoExpand: true
});
});
// ============================================
// SECTION 5: Overall Rating & Recommendation
// ============================================
const overallSection = form.addSubform('overall', {
title: 'Overall Assessment',
isVisible: () => vendorInfo.textbox('vendorName')?.value() !== null && vendorInfo.textbox('vendorName')?.value() !== '',
customStyles: () => {
const stars = overallSection.starRating('overallRating')?.value() || 0;
if (stars >= 4) return { backgroundColor: '#d1fae5', padding: '16px', borderRadius: '8px' };
if (stars >= 3) return { backgroundColor: '#fef3c7', padding: '16px', borderRadius: '8px' };
if (stars >= 1) return { backgroundColor: '#fee2e2', padding: '16px', borderRadius: '8px' };
return { padding: '16px', borderRadius: '8px', border: '1px dashed #cbd5e1' };
}
});
overallSection.addRow(row => {
row.addStarRating('overallRating', {
label: 'Overall Vendor Performance Rating',
maxStars: 5,
size: 'xl',
alignment: 'center',
showConfettiOnMax: true
});
});
overallSection.addRow(row => {
row.addRatingScale('recommendLikelihood', {
preset: 'nps',
label: 'How likely are you to recommend this vendor to colleagues?',
showSegmentColors: true,
showCategoryLabel: true,
alignment: 'center',
size: 'md'
});
});
overallSection.addRow(row => {
row.addRadioButton('recommendation', {
label: () => {
const vendorName = vendorInfo.textbox('vendorName')?.value() || 'this vendor';
return `What is your recommendation for ${vendorName}?`;
},
options: [
{ id: 'preferred', name: 'Preferred Vendor - Expand relationship' },
{ id: 'approved', name: 'Approved Vendor - Continue as is' },
{ id: 'conditional', name: 'Conditional - Requires improvement plan' },
{ id: 'probation', name: 'Probation - Significant concerns' },
{ id: 'terminate', name: 'Terminate - Seek alternative vendors' }
],
orientation: 'vertical',
isRequired: true
});
});
// Conditional improvement plan section
const improvementPlan = form.addSubform('improvementPlan', {
title: 'Required Improvement Plan',
isVisible: () => {
const rec = overallSection.radioButton('recommendation')?.value();
return rec === 'conditional' || rec === 'probation';
},
customStyles: {
backgroundColor: '#fef3c7',
padding: '16px',
borderRadius: '8px',
borderLeft: '4px solid #f59e0b'
}
});
improvementPlan.addRow(row => {
row.addTextarea('improvementActions', {
label: 'Required Actions for Improvement',
placeholder: 'List specific actions the vendor must take to address concerns...',
rows: 3,
autoExpand: true,
isRequired: () => {
const rec = overallSection.radioButton('recommendation')?.value();
return rec === 'conditional' || rec === 'probation';
}
});
});
improvementPlan.addRow(row => {
row.addDropdown('reviewTimeline', {
label: 'Review Timeline',
options: [
{ id: '30', name: '30 days' },
{ id: '60', name: '60 days' },
{ id: '90', name: '90 days' },
{ id: '180', name: '6 months' }
],
placeholder: 'Select review period'
});
});
// ============================================
// SECTION 6: Summary
// ============================================
const summarySection = form.addSubform('summary', {
title: 'Evaluation Summary',
isVisible: () => overallSection.starRating('overallRating')?.value() !== null
});
summarySection.addRow(row => {
row.addTextPanel('summaryContent', {
computedValue: () => {
const vendorName = vendorInfo.textbox('vendorName')?.value() || 'Vendor';
const category = vendorInfo.dropdown('vendorCategory')?.value() || '';
const overall = overallSection.starRating('overallRating')?.value();
const nps = overallSection.ratingScale('recommendLikelihood')?.npsCategory();
const risk = riskSection.slider('riskLevel')?.value() || 0;
const recommendation = overallSection.radioButton('recommendation')?.value();
const strengths = feedbackSection.suggestionChips('strengths')?.value() || [];
if (!overall) return 'Please provide Overall Assessment first...';
const recLabels: Record<string, string> = {
'preferred': 'PREFERRED - Expand',
'approved': 'APPROVED - Continue',
'conditional': 'CONDITIONAL - Improve',
'probation': 'PROBATION - At Risk',
'terminate': 'TERMINATE - Exit'
};
const riskLevel = risk >= 70 ? 'HIGH' : risk >= 40 ? 'MEDIUM' : 'LOW';
let summary = `VENDOR SCORECARD\n`;
summary += `${'═'.repeat(30)}\n\n`;
summary += `Vendor: ${vendorName}\n`;
if (category) {
const catNames: Record<string, string> = {
'raw-materials': 'Raw Materials',
'components': 'Components/Parts',
'equipment': 'Equipment',
'software': 'Software/Tech',
'services': 'Professional Services',
'logistics': 'Logistics',
'facilities': 'Facilities',
'other': 'Other'
};
summary += `Category: ${catNames[category] || category}\n`;
}
summary += `\n${'─'.repeat(30)}\n\n`;
summary += `Overall Rating: ${'★'.repeat(overall)}${'☆'.repeat(5 - overall)} (${overall}/5)\n`;
summary += `Risk Level: ${riskLevel} (${risk}%)\n`;
if (nps) {
summary += `NPS Category: ${nps.charAt(0).toUpperCase() + nps.slice(1)}\n`;
}
summary += `\nRecommendation: ${recLabels[recommendation || ''] || 'Pending'}\n`;
if (strengths.length > 0) {
summary += `\nKey Strengths: ${strengths.length} identified`;
}
return summary;
},
customStyles: () => {
const overall = overallSection.starRating('overallRating')?.value() || 0;
const baseStyles = {
padding: '16px',
borderRadius: '8px',
whiteSpace: 'pre-wrap',
fontFamily: 'monospace',
fontSize: '13px'
};
if (overall >= 4) {
return { ...baseStyles, backgroundColor: '#d1fae5', borderLeft: '4px solid #10b981' };
} else if (overall >= 3) {
return { ...baseStyles, backgroundColor: '#fef3c7', borderLeft: '4px solid #f59e0b' };
} else if (overall >= 1) {
return { ...baseStyles, backgroundColor: '#fee2e2', borderLeft: '4px solid #ef4444' };
}
return { ...baseStyles, backgroundColor: '#f8fafc', borderLeft: '4px solid #64748b' };
}
});
});
// ============================================
// FORM CONFIGURATION
// ============================================
form.configureSubmitButton({
label: 'Submit Evaluation',
isVisible: () => overallSection.radioButton('recommendation')?.value() !== null
});
form.configureCompletionScreen({
type: 'text',
title: 'Evaluation Submitted',
message: () => {
const vendorName = vendorInfo.textbox('vendorName')?.value() || 'the vendor';
return `Your evaluation of ${vendorName} has been recorded. This feedback will be used to inform vendor management decisions and continuous improvement initiatives.`;
}
});
}