import { useEffect, useMemo, useState } from 'react'; import clsx from 'clsx'; import { useAppSelector } from '@akinon/next/redux/hooks'; import { useSetAddressesMutation } from '@akinon/next/data/client/checkout'; import { useAddAddressMutation } from '@akinon/next/data/client/address'; import { Button, Checkbox, Icon, Modal, Radio } from '@theme/components'; import { partAttrs } from '@akinon/pz-theme/src/utils/part-styles'; import { AddressForm } from '@theme/views/account/address-form'; import { useLocalization } from '@akinon/next/hooks'; import PluginModule, { Component } from '@akinon/next/components/plugin-module'; import type { RootState } from '@theme/redux/store'; import type { Address } from '@akinon/next/types'; import AccordionSection, { SectionStatus } from '../accordion-section'; import { AddressListSkeleton } from '../skeletons/address-skeleton'; interface AddressSectionProps { status: SectionStatus; onEdit: () => void; onComplete: () => void; editable?: boolean; } const AddressSection = ({ status, onEdit, onComplete, editable = true }: AddressSectionProps) => { const { t } = useLocalization(); const [isModalOpen, setIsModalOpen] = useState(false); const addressList = useAppSelector( (state: RootState) => state.checkout.addressList ); const preOrder = useAppSelector( (state: RootState) => state.checkout.preOrder ); const { shipping_address, billing_address, billing_and_shipping_same, delivery_option } = preOrder ?? {}; const [setAddresses, { isLoading: isSetting }] = useSetAddressesMutation(); const [addAddress, { isLoading: isAdding }] = useAddAddressMutation(); const [billingSameAsShipping, setBillingSameAsShipping] = useState( billing_and_shipping_same ?? true ); useEffect(() => { setBillingSameAsShipping(billing_and_shipping_same ?? true); }, [billing_and_shipping_same]); const isRetailStore = delivery_option?.delivery_option_type === 'retail_store'; const billingMatchesShipping = !!shipping_address?.pk && !!billing_address?.pk && shipping_address.pk === billing_address.pk; const handleSelectShipping = async (address: Address) => { const billingPk = billingSameAsShipping ? address.pk : billing_address?.pk ?? address.pk; await setAddresses({ shippingAddressPk: address.pk, billingAddressPk: billingPk }) .unwrap() .catch(() => null); }; const handleSelectBilling = async (address: Address) => { if (!shipping_address?.pk) return; await setAddresses({ shippingAddressPk: shipping_address.pk, billingAddressPk: address.pk }) .unwrap() .catch(() => null); }; const handleSameAddressToggle = async () => { const next = !billingSameAsShipping; setBillingSameAsShipping(next); if (next && shipping_address?.pk) { await setAddresses({ shippingAddressPk: shipping_address.pk, billingAddressPk: shipping_address.pk }) .unwrap() .catch(() => null); } }; const handleAddAddress = async (data: Record) => { const response = await addAddress({ ...data, invalidateTag: 'Checkout' }) .unwrap() .catch(() => null); setIsModalOpen(false); if (response?.pk) { const billingPk = billingSameAsShipping ? response.pk : billing_address?.pk ?? response.pk; await setAddresses({ shippingAddressPk: response.pk, billingAddressPk: billingPk }) .unwrap() .catch(() => null); } }; const summary = useMemo(() => { if (!shipping_address) return null; return (
{shipping_address.title} {shipping_address.line} — {shipping_address.township?.name},{' '} {shipping_address.city?.name} {!billingSameAsShipping && billing_address && !billingMatchesShipping && ( {t('checkout.one_page.address.billing_label')}: {billing_address.title} )}
); }, [ shipping_address, billing_address, billingSameAsShipping, billingMatchesShipping, t ]); const renderAddressCard = ( address: Address, selected: boolean, onClick: () => void, name: string, options?: { showSameBadge?: boolean } ) => ( ); const isLoadingFirstLoad = !preOrder && addressList.length === 0; return ( {isLoadingFirstLoad ? ( ) : (

{t('checkout.one_page.address.shipping_label')}

{!isRetailStore && ( {t('checkout.one_page.address.use_for_billing')} )}
{addressList.map((address) => renderAddressCard( address, shipping_address?.pk === address.pk, () => handleSelectShipping(address), 'one-page-shipping' ) )}
{!billingSameAsShipping && !isRetailStore && (

{t('checkout.one_page.address.billing_label')}

{billingMatchesShipping && ( {t('checkout.one_page.address.pick_different_billing')} )}
{addressList.map((address) => renderAddressCard( address, billing_address?.pk === address.pk, () => handleSelectBilling(address), 'one-page-billing', { showSameBadge: billingMatchesShipping && billing_address?.pk === address.pk } ) )}
)}
)}
); }; export default AddressSection;