import { __, sprintf } from '@wordpress/i18n'; import React, { useCallback, useEffect, useMemo, useState } from 'react'; import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; import { Smartphone, Shield, Timer, Check } from 'lucide-react'; import { Card, Input, Page, Spinner, Toggle } from './UI/index.jsx'; import { api } from '../api/index.js'; export default function CheckoutEditor() { const pageHeader = { title: __( 'Checkout Manager', 'arrayfunnel' ), subtitle: __( 'Optimize checkout flow and reduce abandonment with cleaner UX patterns.', 'arrayfunnel' ), }; const qc = useQueryClient(); const [ settings, setSettings ] = useState( null ); const [ original, setOriginal ] = useState( null ); const { data: settingsData, isLoading } = useQuery( { queryKey: [ 'settings' ], queryFn: api.getSettings, staleTime: 30_000, gcTime: 5 * 60_000, } ); useEffect( () => { if ( ! settingsData ) { return; } setSettings( settingsData ); setOriginal( JSON.stringify( settingsData ) ); }, [ settingsData ] ); const { mutateAsync: save, isPending: savingSettings } = useMutation( { mutationFn: ( { changes } ) => api.saveSettings( changes ), onSuccess( response, { changes, snapshot } ) { const saved = { ...snapshot, ...( response?.saved || {} ) }; setOriginal( JSON.stringify( saved ) ); qc.setQueryData( [ 'settings' ], ( current ) => ( { ...current, ...changes, ...( response?.saved || {} ), } ) ); }, } ); const set = ( key, val ) => setSettings( ( s ) => ( { ...s, [ key ]: val, } ) ); const hasChanges = settings && JSON.stringify( settings ) !== original; useEffect( () => { if ( typeof window === 'undefined' ) { return; } window.dispatchEvent( new window.CustomEvent( 'arrayfunnel:dirty-state', { detail: { dirty: Boolean( hasChanges ), }, } ) ); return () => { window.dispatchEvent( new window.CustomEvent( 'arrayfunnel:dirty-state', { detail: { dirty: false, }, } ) ); }; }, [ hasChanges ] ); useEffect( () => { const handleDiscard = () => { if ( ! savingSettings && original !== null ) { setSettings( JSON.parse( original ) ); } }; window.addEventListener( 'arrayfunnel:discard-current-page', handleDiscard ); return () => window.removeEventListener( 'arrayfunnel:discard-current-page', handleDiscard ); }, [ original, savingSettings ] ); const saveCurrentPage = useCallback( async () => { if ( ! hasChanges || savingSettings ) { return; } const baseline = JSON.parse( original ); const changes = Object.fromEntries( Object.entries( settings ).filter( ( [ key, value ] ) => JSON.stringify( value ) !== JSON.stringify( baseline[ key ] ) ) ); await save( { changes, snapshot: settings } ); }, [ hasChanges, original, save, savingSettings, settings ] ); useEffect( () => { const handleHeaderSave = ( event ) => { if ( ! hasChanges ) { return; } const task = saveCurrentPage(); event?.detail?.register?.( task ); }; window.addEventListener( 'arrayfunnel:save-current-page', handleHeaderSave ); return () => window.removeEventListener( 'arrayfunnel:save-current-page', handleHeaderSave ); }, [ hasChanges, saveCurrentPage ] ); const countdownMinutes = Number.parseInt( settings?.arrayfunnel_checkout_countdown_mins, 10 ) || 15; const checkoutModules = useMemo( () => [ { id: 'trust-badges', title: __( 'Connection Badges', 'arrayfunnel' ), description: __( 'Shows HTTPS connection details below the order summary.', 'arrayfunnel' ), icon: Shield, enabled: settings?.arrayfunnel_checkout_trust_badges === 'yes', }, { id: 'fomo-countdown', title: __( 'Checkout Timer', 'arrayfunnel' ), description: __( 'Displays an informational timer during checkout.', 'arrayfunnel' ), icon: Timer, enabled: settings?.arrayfunnel_checkout_countdown === 'yes', }, ], [ settings ] ); if ( isLoading || ! settings ) { return (
); } return (
set( 'arrayfunnel_checkout_optimized', v ? 'yes' : 'no' ) } label={ __( 'Enable Checkout Optimization', 'arrayfunnel' ) } description={ __( 'Activates all checkout enhancements and form refinements.', 'arrayfunnel' ) } /> set( 'arrayfunnel_checkout_trust_badges', v ? 'yes' : 'no' ) } label={ __( 'Show Connection Badges', 'arrayfunnel' ) } description={ __( 'Displays HTTPS connection markers near the submit action.', 'arrayfunnel' ) } /> set( 'arrayfunnel_checkout_countdown', v ? 'yes' : 'no' ) } label={ __( 'Enable Countdown Timer', 'arrayfunnel' ) } description={ __( 'Displays an informational timer above checkout totals.', 'arrayfunnel' ) } /> { settings.arrayfunnel_checkout_countdown === 'yes' && (
set( 'arrayfunnel_checkout_countdown_mins', Number.parseInt( v, 10 ) || 15 ) } type="number" suffix={ __( 'minutes', 'arrayfunnel' ) } description={ __( 'Choose how long the informational timer runs.', 'arrayfunnel' ) } />
) }
{ __( 'Checkout', 'arrayfunnel' ) }
{ settings.arrayfunnel_checkout_countdown === 'yes' && (
{ sprintf( /* translators: %d: timer duration in minutes. */ __( 'Checkout timer: %d minutes', 'arrayfunnel' ), countdownMinutes ) }
) } { settings.arrayfunnel_checkout_trust_badges === 'yes' && (
{ __( 'HTTPS badges appear on secure checkout pages.', 'arrayfunnel' ) }
) }
    { checkoutModules.map( ( module ) => { const Icon = module.icon; return (
  • { module.title }

    { module.description }

    { module.enabled && (
  • ); } ) }
); }