feat: multi-select AI types in configurator
Some checks failed
Build & Push / build-and-push (push) Failing after 34s
Some checks failed
Build & Push / build-and-push (push) Failing after 34s
- Changed aiType (string|null) to aiTypes (string[]) across all components - StepServices: chips now toggle on/off independently, descriptions show for all selected - StepContact: summary tags show all selected AI types - API route: handles array of AI types for both AI and fallback brief generation Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -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] : []),
|
||||
];
|
||||
|
||||
@@ -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
|
||||
}}
|
||||
>
|
||||
<Chip
|
||||
active={formData.aiType === aiId}
|
||||
onClick={() => selectAIType(aiId)}
|
||||
active={formData.aiTypes.includes(aiId)}
|
||||
onClick={() => toggleAIType(aiId)}
|
||||
>
|
||||
{t(`aiTypes.${aiId}.title`)}
|
||||
</Chip>
|
||||
@@ -286,17 +288,22 @@ export default function StepServices({ formData, setFormData, onNext }: StepProp
|
||||
</div>
|
||||
|
||||
<AnimatePresence mode="wait">
|
||||
{formData.aiType && (
|
||||
<motion.p
|
||||
key={formData.aiType}
|
||||
{formData.aiTypes.length > 0 && (
|
||||
<motion.div
|
||||
key={formData.aiTypes.join(',')}
|
||||
initial={{ opacity: 0, y: 4 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
exit={{ opacity: 0, y: -4 }}
|
||||
transition={{ duration: 0.2 }}
|
||||
className="text-xs text-outline leading-relaxed px-1"
|
||||
className="flex flex-col gap-1.5 px-1"
|
||||
>
|
||||
{t(`aiTypes.${formData.aiType}.description`)}
|
||||
</motion.p>
|
||||
{formData.aiTypes.map((aiId) => (
|
||||
<p key={aiId} className="text-xs text-outline leading-relaxed">
|
||||
<strong className="text-on-surface font-medium">{t(`aiTypes.${aiId}.title`)}:</strong>{' '}
|
||||
{t(`aiTypes.${aiId}.description`)}
|
||||
</p>
|
||||
))}
|
||||
</motion.div>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
</div>
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user