import React, { useCallback, useEffect, useRef, useState } from 'react'; import { useAppDispatch, useAppSelector } from '@akinon/next/redux/hooks'; import { setCurrentStep, setSelectedShippingOptions } from '@akinon/next/redux/reducers/checkout'; import { RootState } from '@theme/redux/store'; import { useSetShippingOptionMutation, useSetAttributeBasedShippingOptionsMutation, useSetDataSourceShippingOptionsMutation } from '@akinon/next/data/client/checkout'; import { Price, Button, Radio } from '@theme/components'; import { partAttrs } from '@akinon/pz-theme/src/utils/part-styles'; import { CheckoutStep } from '@akinon/next/types'; import { useLocalization } from '@akinon/next/hooks'; const ShippingOptions: React.FC = () => { const { t } = useLocalization(); const dispatch = useAppDispatch(); const { steps, shippingOptions, attributeBasedShippingOptions, dataSourceShippingOptions, preOrder, addressList, selectedShippingOptions } = useAppSelector((state: RootState) => state.checkout); const { shipping_option, shipping_address, attribute_based_shipping_options, data_source_shipping_options } = preOrder ?? {}; const [setShippingOption] = useSetShippingOptionMutation(); const [setAttributeBasedShippingOptions] = useSetAttributeBasedShippingOptionsMutation(); const [setDataSourceShippingOption] = useSetDataSourceShippingOptionsMutation(); const prevAttributeBasedOptionsRef = useRef(attributeBasedShippingOptions); const [selectedPks, setSelectedPks] = useState< { dataSourcePk: number; optionPk: number }[] | null >(null); const initializeSelectedOptions = useCallback(() => { if (attribute_based_shipping_options) { const newSelected = { ...selectedShippingOptions }; let hasChanges = false; Object.entries(attributeBasedShippingOptions).forEach( ([color, options]) => { if ( !newSelected[color] || !options.some((opt) => opt.pk === newSelected[color]) ) { newSelected[color] = options[0].pk; hasChanges = true; } } ); if (hasChanges) { dispatch(setSelectedShippingOptions(newSelected)); setAttributeBasedShippingOptions(newSelected); } } else if (shippingOptions.length > 0 && !shipping_option) { setShippingOption(shippingOptions[0].pk); } // eslint-disable-next-line react-hooks/exhaustive-deps }, [ attributeBasedShippingOptions, selectedShippingOptions, setAttributeBasedShippingOptions, attribute_based_shipping_options, shippingOptions, shipping_option, setShippingOption ]); useEffect(() => { if (!data_source_shipping_options) return; const initialSelectedPks = data_source_shipping_options.map((option) => ({ dataSourcePk: option.data_source.pk, optionPk: option.pk })); setSelectedPks(initialSelectedPks); }, [data_source_shipping_options]); useEffect(() => { if ( JSON.stringify(prevAttributeBasedOptionsRef.current) !== JSON.stringify(attributeBasedShippingOptions) || Object.keys(selectedShippingOptions).length === 0 || (!shipping_option && shippingOptions.length > 0) ) { initializeSelectedOptions(); prevAttributeBasedOptionsRef.current = attributeBasedShippingOptions; } }, [ attributeBasedShippingOptions, selectedShippingOptions, initializeSelectedOptions, shipping_option, shippingOptions ]); const handleAttributeBasedOptionChange = useCallback( (color: string, newPk: number) => { const updatedOptions = { ...selectedShippingOptions, [color]: newPk }; dispatch(setSelectedShippingOptions(updatedOptions)); setAttributeBasedShippingOptions(updatedOptions); }, // eslint-disable-next-line react-hooks/exhaustive-deps [selectedShippingOptions, setAttributeBasedShippingOptions] ); if (addressList.length < 1) { return (
{t('checkout.address.shipping.select_address_to_continue')}
{t('checkout.address.shipping.select_address_to_continue')}
{t('checkout.address.shipping.chosen_address')}:{' '} {shipping_address?.city.name}
{shippingOptions && shippingOptions.length > 0 && ( <> {shippingOptions.map((option) => (