import { useExitFormDialog } from "@dashboard/components/Form/useExitFormDialog"; import { SingleAutocompleteChoiceType } from "@dashboard/components/SingleAutocompleteSelectField"; import { AddressTypeInput } from "@dashboard/customers/types"; import { AddressFragment, CountryWithCodeFragment, Node, } from "@dashboard/graphql"; import useForm, { CommonUseFormResultWithHandlers, FormChange, SubmitPromise, } from "@dashboard/hooks/useForm"; import useHandleFormSubmit from "@dashboard/hooks/useHandleFormSubmit"; import createSingleAutocompleteSelectHandler from "@dashboard/utils/handlers/singleAutocompleteSelectChangeHandler"; import React, { useEffect, useState } from "react"; export enum AddressInputOptionEnum { CUSTOMER_ADDRESS = "customerAddress", NEW_ADDRESS = "newAddress", } export interface OrderCustomerAddressesEditFormData { cloneAddress: boolean; shippingAddressInputOption: AddressInputOptionEnum; billingAddressInputOption: AddressInputOptionEnum; customerShippingAddress: Node; customerBillingAddress: Node; shippingAddress: AddressTypeInput; billingAddress: AddressTypeInput; } export interface OrderCustomerAddressesEditData extends OrderCustomerAddressesEditFormData { shippingCountryDisplayName: string; billingCountryDisplayName: string; } export interface OrderCustomerAddressesEditHandlers { changeFormAddress: ( event: React.ChangeEvent, addressType: "shippingAddress" | "billingAddress", ) => void; changeCustomerAddress: ( customerAddress: AddressFragment, addressType: "customerShippingAddress" | "customerBillingAddress", ) => void; selectShippingCountry: FormChange; selectBillingCountry: FormChange; } interface UseOrderCustomerAddressesEditFormResult extends CommonUseFormResultWithHandlers< OrderCustomerAddressesEditData, OrderCustomerAddressesEditHandlers > { submit: (event: React.FormEvent) => SubmitPromise; } interface UseOrderCustomerAddressesEditFormOpts { countryChoices: SingleAutocompleteChoiceType[]; countries: CountryWithCodeFragment[]; defaultShippingAddress: Node; defaultBillingAddress: Node; defaultCloneAddress: boolean; } export interface OrderCustomerAddressesEditFormProps extends UseOrderCustomerAddressesEditFormOpts { children: (props: UseOrderCustomerAddressesEditFormResult) => React.ReactNode; initial?: Partial; onSubmit: (data: OrderCustomerAddressesEditData) => void; } function useOrderCustomerAddressesEditForm( providedInitialFormData: Partial, onSubmit: (data: OrderCustomerAddressesEditData) => void, opts: UseOrderCustomerAddressesEditFormOpts, ): UseOrderCustomerAddressesEditFormResult { const emptyAddress: AddressTypeInput = { city: "", country: "", phone: "", postalCode: "", streetAddress1: "", }; const defaultInitialFormData: OrderCustomerAddressesEditFormData = { cloneAddress: opts.defaultCloneAddress, shippingAddressInputOption: AddressInputOptionEnum.CUSTOMER_ADDRESS, billingAddressInputOption: AddressInputOptionEnum.CUSTOMER_ADDRESS, customerShippingAddress: opts.defaultShippingAddress, customerBillingAddress: opts.defaultBillingAddress, shippingAddress: emptyAddress, billingAddress: emptyAddress, }; const initialData = { ...defaultInitialFormData, ...providedInitialFormData, }; const { handleChange, change, data: formData } = useForm(initialData); const { setExitDialogSubmitRef } = useExitFormDialog(); const [shippingCountryDisplayName, setShippingCountryDisplayName] = useState( opts.countries.find( country => initialData.shippingAddress.country === country.code, )?.country, ); const [billingCountryDisplayName, setBillingCountryDisplayName] = useState( opts.countries.find( country => initialData.billingAddress.country === country.code, )?.country, ); const handleFormAddressChange = ( event: React.ChangeEvent, addressType: "shippingAddress" | "billingAddress", ) => change({ target: { name: addressType, value: { ...formData[addressType], [event.target.name]: event.target.value, }, }, }); const handleCustomerAddressChange = ( customerAddress: AddressFragment, addressType: "customerShippingAddress" | "customerBillingAddress", ) => change({ target: { name: addressType, value: customerAddress, }, }); const handleShippingCountrySelect = createSingleAutocompleteSelectHandler( event => change({ target: { name: "shippingAddress", value: { ...formData.shippingAddress, [event.target.name]: event.target.value, countryArea: "", }, }, }), setShippingCountryDisplayName, opts.countryChoices, ); const handleBillingCountrySelect = createSingleAutocompleteSelectHandler( event => change({ target: { name: "billingAddress", value: { ...formData.billingAddress, [event.target.name]: event.target.value, countryArea: "", }, }, }), setBillingCountryDisplayName, opts.countryChoices, ); const data = { ...formData, shippingCountryDisplayName, billingCountryDisplayName, }; const handleFormSubmit = useHandleFormSubmit({ onSubmit, }); const handleSubmit = () => handleFormSubmit(data); const submit = (event: React.FormEvent) => { event.stopPropagation(); event.preventDefault(); return handleSubmit(); }; useEffect(() => setExitDialogSubmitRef(submit), [handleSubmit]); return { change: handleChange, submit, data, handlers: { changeCustomerAddress: handleCustomerAddressChange, changeFormAddress: handleFormAddressChange, selectShippingCountry: handleShippingCountrySelect, selectBillingCountry: handleBillingCountrySelect, }, }; } const OrderCustomerAddressesEditForm: React.FC = ({ children, initial, onSubmit, ...rest }) => { const props = useOrderCustomerAddressesEditForm( initial || {}, onSubmit, rest, ); return (
{children(props)}
); }; OrderCustomerAddressesEditForm.displayName = "OrderCustomerAddressesEditForm"; export default OrderCustomerAddressesEditForm;