import { DateFormatOrder } from '../../types/FieldDescriptor'; import { Locale } from '../../types/Locale'; import { CurableIssueType } from './curableIssues'; /** * Six reasonable-explanation categories the curing form supports. Mirrors * the BE's `ExplanationTypeEnum` (no PascalCase ↔ SCREAMING_SNAKE mapping — * both ends use the same enum). Lives here (and not in * `buildCuringRequestData.ts`) because it's curing-domain data consumed by * descriptors, state, and the submit builder alike. */ export declare const reasonableExplanationTypes: readonly ["STUDENT", "TEACHER_OR_TRAINEE", "DIPLOMAT", "SPOUSE_OR_CHILD", "DO_NOT_MEET_SUBSTANTIAL_PRESENCE_TEST", "CLOSER_CONNECTION_EXCEPTION"]; export type ReasonableExplanationType = (typeof reasonableExplanationTypes)[number]; /** * Flat form state for the curing widget. Holds everything the user can * directly edit. Derived values (`sptWeightedTotal`) and server-supplied * values (`curingSignatureName` etc.) live elsewhere — see `derived` and * `serverData` on `CuringDescriptorState`. */ export type CuringFormState = { file: File | null; explanationOption?: ReasonableExplanationType; sptCurrentYearDays: string; sptPriorYearDays: string; sptTwoPriorYearDays: string; /** * Closer-connection certification checkbox. Stored as the checkbox's * `value` attribute — `'yes'` when checked, `undefined` when not. * `'yes'` (lowercase) matches what the SDK's `CheckBoxRenderer` writes * via `onChange`. Submit-time conversion to the BE's boolean shape lives * in `buildCuringRequestData`. */ closerConnectionCert?: 'yes'; closerConnectionCountry: string; closerConnectionReason: string; /** * User-typed signature. Named to align with the questionnaire's * `QuestionnaireState.signature` slot for cross-flow consistency; * `buildCuringRequestData` maps this to the BE's `signatureName` / * wire-side `signature_name` on submit. * * Populated only when the host mounts the widget with * `collectSignatureName={true}`, which hides the server-fetch path and * shows a signature field on the review screen instead. Stays blank in * the default flow — the signature name comes from the previously- * submitted W-Form via `serverData.curingSignatureName`. */ signature: string; }; export type CuringFormStateKey = keyof CuringFormState; /** Server data the curing widget reads (passed in as props from Persist). */ export type CuringIssue = { issueType: CurableIssueType; status: 'OPEN' | 'IN_REVIEW' | 'RESOLVED'; }; export type CuringData = { curingIssues: CuringIssue[]; curingDocType: 'W-8BEN' | 'W-8BEN-E' | 'W-8IMY'; curingSignatureName?: string; }; /** * State shape that curing descriptors are typed against. Mirrors the * structural constraint of `HydratableState` — both * `useCuringState` and the descriptors work against this shape, and * `hydrateField` accepts it via its `TState extends HydratableState` * generic. */ export type CuringDescriptorState = { fields: CuringFormState; derived: { sptWeightedTotal: number; }; serverData: CuringData; ui: { language: Locale; isShowingErrors: boolean; setValue: (key: CuringFormStateKey, value: string | undefined) => void; setFile: (key: CuringFormStateKey, file: File | null) => void; hideErrors: () => void; }; /** * Durable widget config — set once at mount, threaded through descriptor * state so the chrome (Stage 8) can render the "Powered by Taxbit" badge. * Descriptors don't read this; it's chrome-level metadata that rides on * the state for the same reason `DescriptorConfig.poweredByTaxbit` does * in the questionnaire path. `dateFormat` is unused by curing (no date * inputs) but kept in the shape so it satisfies the `hydrateField` * `HydratableState` constraint without a cast. */ config: { dateFormat?: DateFormatOrder; poweredByTaxbit?: boolean; /** * When true, the widget skips fetching the previously-submitted * W-Form (via `useTaxbitStatus` with `prepopulateWithSavedData: false`) * and shows an editable signature-name field on the review screen. The * descriptor gates its own visibility on this flag; when false, the * field is hidden and the signature name flows in via * `serverData.curingSignatureName` as before. */ collectSignatureName?: boolean; }; };