'use client'; import { useState } from 'react'; import type { ProductCustomizationField } from 'brainerce'; import { useTranslations } from '@/core/lib/translations'; import { LoadingSpinner } from '@/ui/shared/loading-spinner'; import { Checkbox } from '@/components/ui/checkbox'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from '@/components/ui/select'; import { Textarea } from '@/components/ui/textarea'; import type { CustomizationValues } from '@/core/lib/product-options'; // The pure validation logic lives in core (zero markup) so that // `core/hooks/use-product-page` never imports from `ui/`. Re-exported here // for backward compatibility with existing imports. export { validateCustomization } from '@/core/lib/product-options'; export type { CustomizationValues } from '@/core/lib/product-options'; interface CustomizationFieldsProps { fields: ProductCustomizationField[]; values: CustomizationValues; onChange: (values: CustomizationValues) => void; errors?: Record; } export function CustomizationFields({ fields, values, onChange, errors = {}, }: CustomizationFieldsProps) { const t = useTranslations('customization'); if (fields.length === 0) return null; const sorted = [...fields].sort((a, b) => a.position - b.position); const setValue = (key: string, value: unknown) => { onChange({ ...values, [key]: value }); }; return (

{t('title')}

{sorted.map((field) => ( setValue(field.key, v)} /> ))}
); } interface RowProps { field: ProductCustomizationField; value: unknown; error?: string; onChange: (value: unknown) => void; } /** Radix Select items can't carry an empty-string value, so "no choice" * round-trips through this sentinel and is written back as undefined. */ const NONE = '__none__'; function CustomizationFieldRow({ field, value, error, onChange }: RowProps) { const t = useTranslations('customization'); const labelText = ( ); const help = field.description ? (

{field.description}

) : null; const errorHint = error ?

{error}

: null; switch (field.type) { case 'TEXTAREA': return (
{labelText}