diff --git a/src/app/(frontend)/api/configure/route.ts b/src/app/(frontend)/api/configure/route.ts index 1b1cd76..df85e97 100644 --- a/src/app/(frontend)/api/configure/route.ts +++ b/src/app/(frontend)/api/configure/route.ts @@ -6,7 +6,7 @@ import { sendBriefToClient, sendLeadNotification } from '@/lib/email'; interface ConfigureRequestBody { services: string[]; aiEnabled: boolean; - aiType: string | null; + aiTypes: string[]; industry: string | null; scope: string; timeline: string | null; @@ -52,7 +52,9 @@ function buildContext(body: ConfigureRequestBody): string { const industry = body.industry ? INDUSTRY_NAMES[body.industry] ?? body.industry : 'Not specified'; const timeline = body.timeline ? TIMELINE_NAMES[body.timeline] ?? body.timeline : 'Not specified'; const company = body.company.trim() || 'Not specified'; - const aiType = body.aiEnabled && body.aiType ? AI_TYPE_NAMES[body.aiType] ?? body.aiType : null; + const aiTypeNames = body.aiEnabled && body.aiTypes.length > 0 + ? body.aiTypes.map((t) => AI_TYPE_NAMES[t] ?? t).join(', ') + : null; let context = `Client Name: ${body.name} Company: ${company} @@ -61,7 +63,7 @@ Industry: ${industry} Timeline: ${timeline}`; if (body.aiEnabled) { - context += `\nAI Integration: Yes — ${aiType ?? 'type to be determined'}`; + context += `\nAI Integration: Yes — ${aiTypeNames ?? 'type to be determined'}`; } if (body.scope.trim()) { @@ -150,7 +152,7 @@ ${context}`; // ─── Fallback Brief (no API key or API failure) ────────────────────────────── function generateFallbackBrief(body: ConfigureRequestBody): string { - const { services, aiEnabled, aiType, industry, scope, timeline, name, company } = body; + const { services, aiEnabled, aiTypes, industry, scope, timeline, name, company } = body; const serviceNames = services.map((s) => SERVICE_NAMES[s] ?? s); const servicesList = serviceNames.length <= 2 @@ -179,9 +181,11 @@ function generateFallbackBrief(body: ConfigureRequestBody): string { if (hasInfra) { sections += `\n**Private Infrastructure**\nWe'll set up a dedicated server environment for ${displayCompany} with email, cloud storage, and business tools that you fully own and control.\n`; } - if (aiEnabled && aiType) { - const aiLabel = AI_TYPE_NAMES[aiType] ?? 'AI integration'; - sections += `\n**AI Integration**\nWe'll layer ${aiLabel.toLowerCase()} into your systems — deeply integrated, not bolted on. The exact approach will be scoped during discovery.\n`; + if (aiEnabled && aiTypes.length > 0) { + const aiLabels = aiTypes.map((t) => AI_TYPE_NAMES[t] ?? t).join(', '); + sections += `\n**AI Integration**\nWe'll layer ${aiLabels.toLowerCase()} into your systems — deeply integrated, not bolted on. The exact approach will be scoped during discovery.\n`; + } else if (aiEnabled) { + sections += `\n**AI Integration**\nWe'll layer AI integration into your systems — deeply integrated, not bolted on. The exact approach will be scoped during discovery.\n`; } if (scope?.trim()) { sections += `\n**Your Goals**\nYou shared: "${scope.trim()}" — we'll frame our discovery sessions around these priorities.\n`; diff --git a/src/components/configurator/StepContact.tsx b/src/components/configurator/StepContact.tsx index 4a6cfc7..5696908 100644 --- a/src/components/configurator/StepContact.tsx +++ b/src/components/configurator/StepContact.tsx @@ -122,14 +122,14 @@ export default function StepContact({ variant: 'primary' as const, })); - const aiTag = formData.aiEnabled - ? { - label: formData.aiType - ? t(`aiTypes.${formData.aiType}.title`) - : t('summary.aiEnhancement'), - variant: 'primary' as const, - } - : null; + const aiTags = formData.aiEnabled + ? formData.aiTypes.length > 0 + ? formData.aiTypes.map((id) => ({ + label: t(`aiTypes.${id}.title`), + variant: 'primary' as const, + })) + : [{ label: t('summary.aiEnhancement'), variant: 'primary' as const }] + : []; const industryTag = formData.industry ? { label: t(`industries.${formData.industry}`), variant: 'neutral' as const } @@ -141,7 +141,7 @@ export default function StepContact({ const allTags = [ ...serviceTags, - ...(aiTag ? [aiTag] : []), + ...aiTags, ...(industryTag ? [industryTag] : []), ...(timelineTag ? [timelineTag] : []), ]; diff --git a/src/components/configurator/StepServices.tsx b/src/components/configurator/StepServices.tsx index 295c1db..cecc854 100644 --- a/src/components/configurator/StepServices.tsx +++ b/src/components/configurator/StepServices.tsx @@ -193,14 +193,16 @@ export default function StepServices({ formData, setFormData, onNext }: StepProp setFormData((prev) => ({ ...prev, aiEnabled: !prev.aiEnabled, - aiType: prev.aiEnabled ? null : prev.aiType, + aiTypes: prev.aiEnabled ? [] : prev.aiTypes, })); }; - const selectAIType = (id: string) => { + const toggleAIType = (id: string) => { setFormData((prev) => ({ ...prev, - aiType: prev.aiType === id ? null : id, + aiTypes: prev.aiTypes.includes(id) + ? prev.aiTypes.filter((t) => t !== id) + : [...prev.aiTypes, id], })); }; @@ -276,8 +278,8 @@ export default function StepServices({ formData, setFormData, onNext }: StepProp }} > selectAIType(aiId)} + active={formData.aiTypes.includes(aiId)} + onClick={() => toggleAIType(aiId)} > {t(`aiTypes.${aiId}.title`)} @@ -286,17 +288,22 @@ export default function StepServices({ formData, setFormData, onNext }: StepProp - {formData.aiType && ( - 0 && ( + - {t(`aiTypes.${formData.aiType}.description`)} - + {formData.aiTypes.map((aiId) => ( +

+ {t(`aiTypes.${aiId}.title`)}:{' '} + {t(`aiTypes.${aiId}.description`)} +

+ ))} + )}
diff --git a/src/components/configurator/WizardContainer.tsx b/src/components/configurator/WizardContainer.tsx index d8ba313..802889c 100644 --- a/src/components/configurator/WizardContainer.tsx +++ b/src/components/configurator/WizardContainer.tsx @@ -13,7 +13,7 @@ import StepComplete from './StepComplete'; export interface WizardFormData { services: string[]; aiEnabled: boolean; - aiType: string | null; + aiTypes: string[]; industry: string | null; scope: string; timeline: string | null; @@ -59,7 +59,7 @@ const makeVariants = (direction: 1 | -1) => ({ const DEFAULT_FORM_DATA: WizardFormData = { services: [], aiEnabled: false, - aiType: null, + aiTypes: [], industry: null, scope: '', timeline: null,