import { FetchStateAndError, ID } from '../../../commonStateTypes/common'; import { SelectorView } from '../../../commonStateTypes/viewAndReport/viewAndReport'; import { InvoicingInvoice } from '../../../entity/invoicing/invoice/invoiceState'; import { InvoicingFieldHelpByCode, InvoicingNamedOption } from '../../../entity/invoicing/invoicingCommonPayload'; import { InvoicingCustomer, InvoicingCustomerPaymentMethod } from '../../../entity/invoicing/invoicingCustomer/invoicingCustomerState'; import { RootState } from '../../../rootStateTypes'; import { InvoicingSetupIntent } from '../customerPaymentMethod/customerPaymentMethodState'; import { InvoicingCustomerFormLocalData, InvoicingPaymentLinkEmailPreviewData } from './editInvoicingCustomerDetailViewState'; /** * Read-only view for the customer detail page: the customer entity + its fetch * state, plus everything the page renders in view mode — recent invoices, the * Add-Payment-Method dialog state (setup intent / Plaid token / save), the * payment-link send state, branding fields for the payment-email preview, and * whether Stripe is connected. Lets the detail screen depend on this single * read selector. */ export interface InvoicingCustomerRecordView extends FetchStateAndError { /** * Backend help copy for this screen's field group, keyed by field code. * Folded in here so the screen never reaches for the config view itself. */ fieldHelp: InvoicingFieldHelpByCode; invoices: InvoicingInvoice[]; paymentMethods: InvoicingCustomerPaymentMethod[]; paymentMethodSaveState: FetchStateAndError; sendLinkState: FetchStateAndError; setupIntentFetchState: FetchStateAndError; stripeConnected: boolean; brandingAccentColor?: string; brandingCompanyName?: string; brandingEmail?: string; brandingLogoUrl?: string; invoicingCustomer?: InvoicingCustomer; plaidLinkToken?: string; sentPaymentLinkEmail?: string; sentPaymentLinkMagicUrl?: string; setupIntent?: InvoicingSetupIntent; } /** * `invoicingCustomerID` is absent in create mode, where there is no record to * resolve — the view still renders, off an empty record. */ export declare const getInvoicingCustomerRecord: (state: RootState, invoicingCustomerID?: ID) => InvoicingCustomerRecordView; export interface InvoicingCustomerFormView extends SelectorView { customerTypeOptions: InvoicingNamedOption[]; /** * The payment-link email the composer previews, and the state of fetching it. * Absent until the composer is opened for this customer. */ emailPreviewFetchState: FetchStateAndError; /** * Backend help copy for this screen's field group, keyed by field code. * Folded in here so the screen never reaches for the config view itself. */ fieldHelp: InvoicingFieldHelpByCode; localData: InvoicingCustomerFormLocalData; mode: 'create' | 'edit'; netTermDayOptions: InvoicingNamedOption[]; /** * Every request the page renders from, reduced to one state: the record and * the config behind its dropdowns and field help. The page holds a skeleton * until this is `Completed`, so the form mounts once with real values. */ pageFetchState: FetchStateAndError; /** Plaid link-token fetch, folded in so the screen reads one selector. */ plaidTokenFetchState: FetchStateAndError; /** Promotional-credit submit, folded in so the screen reads one selector. */ promotionalCreditSubmitState: FetchStateAndError; /** * The record and everything the detail page renders alongside it — invoices, * payment methods, branding, Stripe state. Nested rather than flattened: it * is a page's worth of state, and spreading it here would bury this view's * own form fields. Screens read one selector and reach through this. */ record: InvoicingCustomerRecordView; taxabilityOptions: InvoicingNamedOption[]; billingAddressId?: ID; billingAddressLabel?: string; emailPreview?: InvoicingPaymentLinkEmailPreviewData; savedCustomerId?: ID; } /** * Bundled view for the customer create/edit form. Exposes the draft `localData` * (seeded from the existing customer entity in edit mode until the user edits), * the canonical option value sets (labels resolved in web-components), the save * fetch state/error, and the id of the customer last saved — so the form screen * depends on this single selector. */ export declare const getInvoicingCustomerFormView: (state: RootState, invoicingCustomerID?: ID) => InvoicingCustomerFormView;