/** * Tax form: owns state, validation (Zod), and errors. * Notifies page via onChange(formId, value) and onInteraction(). */ import { __ } from '@wordpress/i18n'; import { memo, useState, useEffect, useCallback, useRef } from '@wordpress/element'; import { Flex } from '@wordpress/components'; import { SettingsField } from './settings-field'; import type { TaxSettings } from '../../types/settings'; import type { SettingsFieldSelectOption } from './settings-field'; import { taxSettingsSchema } from './utils/schemas'; import { getSectionFieldErrors } from './utils/getSettingsFieldErrors'; export const TAX_FORM_ID = 'tax' as const; export interface TaxFormProps { defaultValue: TaxSettings; onChange: (formId: string, value: TaxSettings) => void; onInteraction?: () => void; resetTrigger?: number; submitErrors?: Record; vatStatusOptions: SettingsFieldSelectOption[]; } function TaxFormInner({ defaultValue, onChange, onInteraction, resetTrigger = 0, submitErrors, vatStatusOptions, }: TaxFormProps) { const [value, setValue] = useState(() => ({ ...defaultValue })); const [errors, setErrors] = useState>({}); const hasInteracted = useRef(false); useEffect(() => { setValue({ ...defaultValue }); setErrors({}); hasInteracted.current = false; }, [defaultValue, resetTrigger]); useEffect(() => { const result = taxSettingsSchema.safeParse(value); if (result.success) { setErrors({}); } else { setErrors(getSectionFieldErrors(result.error)); } }, [value]); const displayErrors = submitErrors ?? errors; const handleChange = useCallback( (field: keyof TaxSettings, v: string) => { if (!hasInteracted.current) { hasInteracted.current = true; onInteraction?.(); } const next = { ...value, [field]: v }; setValue(next); onChange(TAX_FORM_ID, next); }, [value, onChange, onInteraction] ); return ( handleChange('vatNumber', v)} error={displayErrors.vatNumber} /> handleChange('eori', v)} error={displayErrors.eori} /> handleChange('vatStatus', v)} options={vatStatusOptions} error={displayErrors.vatStatus} /> ); } export const TaxForm = memo(TaxFormInner);