import React, { useState, useEffect } from 'react'; import { View, Text, TouchableOpacity, SafeAreaView, Linking, Image, } from 'react-native'; // Explicit .native imports so TypeScript (tsconfig.native.json) resolves the // correct platform files — Metro handles implicit resolution at bundle time. import MapPinSelector from './MapPinSelector.native'; import AddressForm from './AddressForm.native'; import type { CheckoutEvent, CheckoutWidgetProps, CompleteAddress } from '../core/types'; import CodAvailabilityBanner from './CodAvailabilityBanner'; import { styles, COLORS } from '../styles/checkout.native'; // ─── Types ──────────────────────────────────────────────────────────────────── type Step = 'map' | 'form' | 'done'; interface ConfirmedLocation { lat: number; lng: number; digipin: string; } // ─── Success screen ─────────────────────────────────────────────────────────── interface SuccessScreenProps { address: CompleteAddress; onEditAddress: () => void; isDark: boolean; } const SuccessScreen: React.FC = ({ address, onEditAddress, isDark }) => ( Address Saved! {address.formattedAddress} {/* DigiPin badge */} DigiPin {address.digipin} Change Address ); // ─── Main Widget ────────────────────────────────────────────────────────────── /** * QuantaRoute Checkout Widget — native (iOS/Android) version. * * Two-step address collection: * Step 1 – Map: drag pin to exact location (DigiPin computed offline, real-time) * Step 2 – Form: auto-filled address + manual flat/building details * * Metro resolves this file on native; CheckoutWidget.tsx is used on web. * * Usage in Expo: * import { CheckoutWidget } from '@quantaroute/checkout'; * console.log(addr)} /> */ const CheckoutWidget: React.FC = ({ apiKey, apiBaseUrl = 'https://api.quantaroute.com', onComplete, onError, defaultLat, defaultLng, theme = 'light', style, mapHeight = 380, title = 'Add Delivery Address', brandColor, logoUrl, headerBanner, onCheckoutEvent, merchantId = '', supabaseFunctionBaseUrl = '', enableCod = false, enableServiceabilityCheck = false, showIndiaPostDeliveryWarning = false, serviceabilityBlockCheckout, codCartTotalPaise, codSessionToken = '', }) => { const [step, setStep] = useState('map'); const [confirmedLocation, setConfirmedLocation] = useState(null); const [completedAddress, setCompletedAddress] = useState(null); const checkoutConfig = { functionBaseUrl: supabaseFunctionBaseUrl, merchantId, }; const codSession = codSessionToken; const isDark = theme === 'dark'; const accent = brandColor ?? COLORS.primary; /** Fire an analytics event without blocking the UI. */ const emit = (partial: Omit) => { if (!onCheckoutEvent) return; try { onCheckoutEvent({ ...partial, timestamp: new Date().toISOString() }); } catch { // Never let analytics crash the checkout } }; useEffect(() => { const viewedMap: Record = { map: 'map_step_viewed', form: 'form_step_viewed', done: 'address_completed', }; emit({ type: viewedMap[step], step }); // eslint-disable-next-line react-hooks/exhaustive-deps }, [step]); // ── Handlers ────────────────────────────────────────────────────────────── const handleLocationConfirm = (lat: number, lng: number, digipin: string) => { setConfirmedLocation({ lat, lng, digipin }); emit({ type: 'location_confirmed', step: 'form', digipin }); setStep('form'); }; const handleAddressComplete = (address: CompleteAddress) => { setCompletedAddress(address); emit({ type: 'address_completed', step: 'done', digipin: address.digipin }); setStep('done'); onComplete(address); }; const handleBack = () => setStep('map'); const handleEditAddress = () => { emit({ type: 'widget_reset', step: 'map' }); setStep('map'); setConfirmedLocation(null); setCompletedAddress(null); }; // ── Step indicator ───────────────────────────────────────────────────────── const renderStepDots = () => ( ); // ── Render ───────────────────────────────────────────────────────────────── return ( {/* Widget header (hidden on success screen) */} {step !== 'done' ? ( <> {logoUrl ? ( ) : ( 📍 )} {title} {renderStepDots()} {headerBanner ? ( {headerBanner} ) : null} ) : null} {/* ── Step 1: Map ── */} {step === 'map' ? ( ) : null} {/* ── Step 2: Form ── */} {step === 'form' && confirmedLocation ? ( ) : null} {/* ── Step 3: Done ── */} {step === 'done' && completedAddress ? ( <> {enableCod && merchantId && supabaseFunctionBaseUrl && codSession ? ( ) : null} ) : null} {/* Powered-by footer */} Powered by void Linking.openURL('https://quantaroute.com')} accessibilityRole="link" accessibilityLabel="QuantaRoute website" > QuantaRoute 🇮🇳 ); }; export default CheckoutWidget;