'use client'; import {useState} from 'react'; import {VStack, HStack} from '@astryxdesign/core/Layout'; import {FormLayout} from '@astryxdesign/core/FormLayout'; import {TextInput} from '@astryxdesign/core/TextInput'; import {NumberInput} from '@astryxdesign/core/NumberInput'; import {Button} from '@astryxdesign/core/Button'; import {Text} from '@astryxdesign/core/Text'; import {Divider} from '@astryxdesign/core/Divider'; import {useToast} from '@astryxdesign/core/Toast'; import {StaticPanel} from '@/shared/components/patterns/PanelCard'; import {settingsService} from '@/features/settings/services/settingsService'; import type {ProfileFieldErrors} from '@/features/settings/services/settingsService'; import type {MerchantProfile} from '@/features/settings/types/settings'; /** * Merchant profile. * * `initialData` arrives from a Server Component that read the record * DIRECTLY — no HTTP round trip — so the form paints filled on first render * rather than flashing empty inputs. This is the hybrid path the data layer * was designed for: dashboards fetch on the client because their scope * changes constantly, but a settings form has exactly one server-known state * at page load and should use it. * * Status is only ever set on submit, never at initial paint — Astryx's * FieldStatus breaks SSR hydration when it is server-rendered with a status * already applied (see AGENTS.md). */ export function ProfileForm({initialData}: {initialData: MerchantProfile}) { const toast = useToast(); const [form, setForm] = useState(initialData); const [isSaving, setIsSaving] = useState(false); const [errors, setErrors] = useState({}); const set = ( key: K, value: MerchantProfile[K], ) => setForm((f) => ({...f, [key]: value})); const isDirty = JSON.stringify(form) !== JSON.stringify(initialData); async function save() { // Validation and transport both live in settingsService — this component // decides what to render, never what a valid profile is or where it goes. // The raw fetch that used to sit here was the last one in the codebase. setIsSaving(true); const result = await settingsService.saveProfile(form); setIsSaving(false); if (result.ok) { setErrors({}); toast({body: 'Profile saved'}); return; } setErrors(result.errors); if (result.message) { toast({type: 'error', body: result.message}); } } return ( {isDirty ? ( Unsaved changes ) : null}