import { useCallback, useMemo, useRef } from 'react'; import clsx from 'clsx'; import { useAppSelector } from '@akinon/next/redux/hooks'; import { useSetPaymentOptionMutation } from '@akinon/next/data/client/checkout'; import { usePaymentOptions } from '@akinon/next/hooks/use-payment-options'; import { useLocalization } from '@akinon/next/hooks'; import { partAttrs } from '@akinon/pz-theme/src/utils/part-styles'; import { Icon } from '@theme/components'; import type { RootState } from '@theme/redux/store'; import type { CheckoutPaymentOption } from '@akinon/next/types'; const PAYMENT_TYPE_ICON: Record = { credit_card: 'cvc', funds_transfer: 'file', pay_on_delivery: 'address', bkm_express: 'akinon', masterpass: 'cvc', masterpass_rest: 'cvc', saved_card: 'cvc', gpay: 'google', google_pay: 'google', apple_pay: 'apple', wallet: 'akinon', redirection: 'globe', credit_payment: 'installment', loyalty: 'heart-full', hepsipay: 'akinon', tabby: 'installment', tamara: 'installment', iyzico: 'cvc', cybersource_uc: 'cvc', flow_payment: 'installment' }; const SLUG_KEYWORD_ICON: Array<[string, string]> = [ ['apple', 'apple'], ['google', 'google'], ['gpay', 'google'], ['hepsi', 'akinon'], ['tabby', 'installment'], ['tamara', 'installment'], ['flow', 'installment'], ['saved', 'cvc'], ['credit', 'cvc'], ['transfer', 'file'], ['delivery', 'address'], ['wallet', 'akinon'] ]; const getOptionIcon = (option: CheckoutPaymentOption): string => { if (PAYMENT_TYPE_ICON[option.payment_type]) { return PAYMENT_TYPE_ICON[option.payment_type]; } const slug = option.slug?.toLowerCase() || ''; for (const [keyword, icon] of SLUG_KEYWORD_ICON) { if (slug.includes(keyword)) return icon; } return 'default'; }; const PaymentOptionsGrid = () => { const { t } = useLocalization(); const { preOrder, attributeBasedShippingOptions } = useAppSelector( (state: RootState) => state.checkout ); const [setPaymentOption, { isLoading }] = useSetPaymentOptionMutation(); const { filteredPaymentOptions } = usePaymentOptions(); const containerRef = useRef(null); const visibleOptions = useMemo(() => { if ( attributeBasedShippingOptions && Object.keys(attributeBasedShippingOptions).length > 0 ) { return filteredPaymentOptions.filter( (option) => option.slug?.toLowerCase() !== 'pay-on-delivery' ); } return filteredPaymentOptions; }, [filteredPaymentOptions, attributeBasedShippingOptions]); const handleKeyDown = useCallback( (event: React.KeyboardEvent) => { if ( !['ArrowRight', 'ArrowLeft', 'ArrowDown', 'ArrowUp', 'Home', 'End'].includes( event.key ) ) { return; } event.preventDefault(); const buttons = Array.from( containerRef.current?.querySelectorAll( 'button[role="radio"]' ) ?? [] ); if (buttons.length === 0) return; const currentIndex = buttons.findIndex( (btn) => btn === document.activeElement ); let nextIndex = currentIndex; switch (event.key) { case 'ArrowRight': case 'ArrowDown': nextIndex = (currentIndex + 1 + buttons.length) % buttons.length; break; case 'ArrowLeft': case 'ArrowUp': nextIndex = (currentIndex - 1 + buttons.length) % buttons.length; break; case 'Home': nextIndex = 0; break; case 'End': nextIndex = buttons.length - 1; break; } buttons[nextIndex]?.focus(); }, [] ); if (visibleOptions.length === 0) { return (

{t('checkout.one_page.payment.no_options')}

); } return (
{visibleOptions.map((option, index) => { const selected = preOrder?.payment_option?.pk === option.pk; return ( ); })}
); }; export default PaymentOptionsGrid;