import { useState, useRef, useCallback, useEffect } from 'react'; import { Box, Button, InputBase, InputAdornment, Stack, Typography } from '@mui/material'; import { useLocaleContext } from '@arcblock/ux/lib/Locale/context'; import CountrySelect from '../../../components/country-select'; import PhoneField from '../../../components/phone-field'; import { countryCodeToFlag } from '../../utils/format'; interface FieldConfig { name: string; type: string; required: boolean; } interface CustomerInfoCardProps { form: { fields: FieldConfig[]; values: Record; onChange: (field: string, value: string | boolean | Record) => void; errors: Partial>; checkValid: () => Promise; validateField: (field: string) => Promise; prefetched: boolean; }; isLoggedIn: boolean; } const fieldLabelMap = (t: (key: string) => string) => ({ customer_name: t('payment.checkout.customer.name'), customer_email: t('payment.checkout.customer.email'), customer_phone: t('payment.checkout.customer.phone'), 'billing_address.country': t('payment.checkout.billing.country'), 'billing_address.state': t('payment.checkout.billing.state'), 'billing_address.city': t('payment.checkout.billing.city'), 'billing_address.line1': t('payment.checkout.billing.line1'), 'billing_address.line2': t('payment.checkout.billing.line2'), 'billing_address.postal_code': t('payment.checkout.billing.postal_code'), }) as Record; export default function CustomerInfoCard({ form, isLoggedIn }: CustomerInfoCardProps) { const { t } = useLocaleContext(); const labels = fieldLabelMap(t); // Don't render until first validation completes — avoids flash. // Valid → show collapsed summary; invalid → show expanded form. // After first check, only manual "Edit"/"Confirm" toggles. const [showEditForm, setShowEditForm] = useState(false); const [ready, setReady] = useState(false); const checkedRef = useRef(false); useEffect(() => { if (checkedRef.current) return; // Wait for data to arrive before making a decision if (!form.prefetched && !form.values.customer_name && !form.values.customer_email) return; checkedRef.current = true; form.checkValid().then((valid) => { setShowEditForm(!valid); setReady(true); }); }, [form.prefetched]); // eslint-disable-line react-hooks/exhaustive-deps // Wrap onChange to delegate to parent form const handleChange: typeof form.onChange = useCallback( (field, value) => form.onChange(field, value), [form.onChange] // eslint-disable-line react-hooks/exhaustive-deps ); // Auto-expand to edit mode when validation errors appear (e.g. after submit click) useEffect(() => { if (ready && !showEditForm && Object.keys(form.errors).length > 0) { setShowEditForm(true); } }, [form.errors]); // eslint-disable-line react-hooks/exhaustive-deps if (!isLoggedIn || !ready) return null; // Summary view if (!showEditForm) { return ( {/* Header — outside the card */} {t('payment.checkout.customerInfo')} {/* Card body */} {form.values.customer_name && ( {form.values.customer_name} )} {form.values.customer_email && ( {form.values.customer_email} )} {form.fields.some((f) => f.name === 'customer_phone') && form.values.customer_phone && ( {form.values.customer_phone} )} {(form.values.billing_address?.country || form.values.billing_address?.state || form.values.billing_address?.postal_code) && ( {form.values.billing_address?.country && ( {countryCodeToFlag(form.values.billing_address.country)} )} {form.values.billing_address?.state || ''} {form.values.billing_address?.postal_code ? ` [ ${t('payment.checkout.billing.postal_code')}: ${form.values.billing_address.postal_code} ]` : ''} )} ); } // Edit form — v1 style: bold label above, grey background input return ( {/* Header — outside the card */} {t('payment.checkout.customerInfo')} {/* Card body */} {form.fields .filter((f) => f.name !== 'billing_address.country') .map((field) => { const { name } = field; const label = labels[name] || name; const value = name.includes('.') ? name.split('.').reduce((o: any, k) => o?.[k], form.values) : form.values[name]; const isPostalCode = name === 'billing_address.postal_code'; const isPhone = name === 'customer_phone'; // Phone field — with country flag + dial code selector if (isPhone) { return ( handleChange('customer_phone', phone)} onCountryChange={(c) => handleChange('billing_address.country', c)} onBlur={() => form.validateField(name)} label={label} error={form.errors[name]} /> ); } return ( {label} handleChange(name, e.target.value)} onBlur={() => form.validateField(name)} startAdornment={ isPostalCode ? ( handleChange('billing_address.country', v)} sx={{ '.MuiOutlinedInput-notchedOutline': { borderColor: 'transparent !important' }, '& .MuiSelect-select': { py: 0, pr: '20px !important' }, }} /> ) : undefined } sx={{ bgcolor: (theme) => (theme.palette.mode === 'dark' ? 'rgba(255,255,255,0.06)' : 'grey.50'), borderRadius: '8px', px: 1.5, py: 0.75, fontSize: 14, '& .MuiInputBase-input': { p: 0 }, }} /> {form.errors[name] && ( {form.errors[name]} )} ); })} ); }