diff --git a/features/marketplace/frontend-public/src/features/onboarding/components/DynamicFormRenderer.tsx b/features/marketplace/frontend-public/src/features/onboarding/components/DynamicFormRenderer.tsx new file mode 100644 index 000000000..50c282a4f --- /dev/null +++ b/features/marketplace/frontend-public/src/features/onboarding/components/DynamicFormRenderer.tsx @@ -0,0 +1,115 @@ +/** + * DynamicFormRenderer - Renders form fields from server-defined configuration + * + * Used for steps where the server defines the form shape dynamically. + * Clean onboarding steps use their existing hardcoded components; + * this renderer handles any additional steps the server may add. + */ + +import { useState, useCallback } from 'react'; +import type { OnboardingFieldDto } from '../hooks/onboarding.types'; + +interface DynamicFormRendererProps { + fields: OnboardingFieldDto[]; + onSubmit: (data: Record) => void; + onChange?: (data: Record) => void; +} + +export function DynamicFormRenderer({ fields, onSubmit, onChange }: DynamicFormRendererProps) { + const [formData, setFormData] = useState>({}); + + const updateField = useCallback((name: string, value: unknown) => { + setFormData((prev) => { + const next = { ...prev, [name]: value }; + onChange?.(next); + return next; + }); + }, [onChange]); + + const handleSubmit = useCallback((e: React.FormEvent) => { + e.preventDefault(); + onSubmit(formData); + }, [formData, onSubmit]); + + return ( +
+ {fields.map((field) => ( +
+ + + {field.type === 'textarea' ? ( +