import { Debit, Plaid, Ribbit } from '@greenpay/models' import { dispatchStore, selectStore, useDispatchStore, useSelectStore } from '@greenpay/utils' import { validationActions } from '@greenpay/store' // Define the name of the WP-Data store namespace const STORE_NAME = 'green-pay/validation' /** * Shape of the validation state */ export interface ValidationState { /** Manages validation error strings per control */ errors: { plaid: string routing: string account: string } /** Manage validation pristine/touch status */ touched: { plaid: boolean routing: boolean account: boolean } status: { tan: boolean plaid: boolean } /** General error message */ errorMessage: string /** MUI snackbar notification */ snackbar: { open: boolean message: string } } /** * Actions available for the validation store */ export interface ValidationActions { /** * Set the general error message * @param message error message */ setErrorMessage(message: string): void /** * Show an error snackbar notification */ showSnackbar(message: string): void /** * Hide the snackbar notification */ hideSnackbar(): void /** * Set the plaid error message * @param message error message */ setPlaidError(message: string): void /** * Set the plaid validation control as touched */ setPlaidTouched(touched: boolean): void /** * Set the manual debit routing error message * @param message error message */ setRoutingError(message: string): void /** * Set the routing number control as touched * @param touched boolean true => touched false => pristine */ setRoutingTouched(touched: boolean): void /** * Set the manual debit account error message * @param message error message */ setAccountError(message: string): void /** * Set the account number control as touched * @param touched boolean true => touched false => pristine */ setAccountTouched(touched: boolean): void /** * Sets both routing and account number as touched * @param touched boolean true => touched false => pristine */ setDebitTouched(touched: boolean): void /** * Sets the status of the TAN verification * @param status boolean true => Tan handled false => Tan not handled */ setTanStatus(status: boolean): void /** * Sets the status of the plaid widget visibility * @param status boolean true => Plaid widget opened false => not opened */ setPlaidOpen(status: boolean): void /** * Validate the provided Plaid data * @param data Plaid response data */ validatePlaid(data: Plaid | null): boolean /** * Validate the provided Ribbit data */ validateRibbit(data: Ribbit | null): boolean /** * Validate the provided debit data * @param data Debit data routing and account number * @returns boolean */ validateDebit(data: Debit | null): boolean /** * Valdate the debit routing number * @param routing Routing number * @returns boolean */ validateRouting(routing?: string): boolean /** * Validate the debit account number * @param account Account number * @returns boolean */ validateAccount(account?: string): boolean } /** * Selectors available for the validation store */ export interface ValidationSelectors { /** * Get the general error message * @returns string */ getErrorMessage(): string getSnackbarOpen(): boolean getSnackbarMessage(): string /** * Get the Plaid error message * @returns string */ getPlaidError(): string /** * Get the debit error message * @returns string */ getDebitError(): string /** * Get the debit routing number error message * @returns string */ getRoutingError(): string /** * Get the debit account number error message * @returns string */ getAccountError(): string /** * Get the touched status of the Plaid data component * @returns boolean true => touched false => pristine */ getPlaidTouched(): boolean /** * Get the touched status of the routing number control * @returns boolean true => touched false => pristine */ getRoutingTouched(): boolean /** * Get the touched status of the account number control * @returns boolean true => touched false => pristine */ getAccountTouched(): boolean /** * Get the tan handled status * @returns boolean true => Tan handled false => Tan not handled */ getTanStatus(): boolean /** * Get the Plaid widget visibility status * @return boolean true => visible false => hidden */ getPlaidOpen(): boolean } /** * Direct dispatch helper: use outside React components. * @returns ValidationActions bound to select */ export const validationDispatch = (): ValidationActions => { const dispatch = dispatchStore(STORE_NAME) const actions = validationActions return { ...dispatch, validatePlaid: (data: Plaid | null): boolean => actions.validatePlaid(data)(), validateRibbit: (data: Ribbit | null): boolean => actions.validateRibbit(data)(), validateDebit: (data: Debit | null): boolean => actions.validateDebit(data)(), validateRouting: (routing?: string): boolean => actions.validateRouting(routing)(), validateAccount: (account?: string): boolean => actions.validateAccount(account)(), } } /** * Direct selector helper: use outside React components. * @returns ValidationSelectors bound to select */ export const validationSelect = () => selectStore(STORE_NAME) /** * React hook to access validation store actions. * @returns ValidationActions from useDispatch */ export const useValidationDispatch = (): ValidationActions => { const dispatch = dispatchStore(STORE_NAME) const actions = validationActions return { ...dispatch, validatePlaid: (data: Plaid | null): boolean => actions.validatePlaid(data)(), validateRibbit: (data: Ribbit | null): boolean => actions.validateRibbit(data)(), validateDebit: (data: Debit | null): boolean => actions.validateDebit(data)(), validateRouting: (routing?: string): boolean => actions.validateRouting(routing)(), validateAccount: (account?: string): boolean => actions.validateAccount(account)(), } } /** * React hook to access validation store selectors. * @returns ValidationSelectors from useSelect */ export const useValidationSelect = () => useSelectStore(STORE_NAME)