139 lines
4.5 KiB
TypeScript
139 lines
4.5 KiB
TypeScript
import React, { useState, useMemo } from 'react';
|
|
import { View, Text, TouchableOpacity, ScrollView } from 'react-native';
|
|
import { useNavigation } from '@react-navigation/native';
|
|
import { StackNavigationProp } from '@react-navigation/stack';
|
|
import { getStyles } from './checkoutAddressScreen.styles';
|
|
import { Header, StepProgress, PrimaryButton } from '@components';
|
|
import { useAppTheme } from '@theme';
|
|
import { useAppSelector } from '@store';
|
|
import { AddressLabel, CustomerAddress } from '@interfaces';
|
|
import { AppStackParamList } from '@navigation/appStack';
|
|
|
|
type CheckoutAddressNavProp = StackNavigationProp<
|
|
AppStackParamList,
|
|
'CheckoutAddressScreen'
|
|
>;
|
|
|
|
const CHECKOUT_STEPS = [
|
|
{ key: 'address', label: 'Address' },
|
|
{ key: 'payment', label: 'Payment' },
|
|
{ key: 'confirm', label: 'Confirm' },
|
|
];
|
|
|
|
const LABEL_ICON: Record<AddressLabel, string> = {
|
|
Home: '🏠',
|
|
Work: '💼',
|
|
Other: '📍',
|
|
};
|
|
|
|
export const CheckoutAddressScreen: React.FC = () => {
|
|
const { colors } = useAppTheme();
|
|
const styles = getStyles(colors);
|
|
const navigation = useNavigation<CheckoutAddressNavProp>();
|
|
const { customerDetails } = useAppSelector(state => state.customerProfile);
|
|
|
|
const addresses: CustomerAddress[] = customerDetails?.addresses ?? [];
|
|
|
|
const defaultAddressId = useMemo(() => {
|
|
const def = addresses.find(a => a.isDefault);
|
|
return def?.id ?? addresses[0]?.id ?? null;
|
|
}, [addresses]);
|
|
|
|
const [selectedAddressId, setSelectedAddressId] = useState<string | null>(
|
|
defaultAddressId,
|
|
);
|
|
|
|
const handleContinue = () => {
|
|
if (!selectedAddressId) return;
|
|
navigation.navigate('CheckoutPaymentScreen', {
|
|
selectedAddressId,
|
|
});
|
|
};
|
|
|
|
return (
|
|
<View style={styles.container}>
|
|
<Header title="Checkout" onBack={() => navigation.goBack()} />
|
|
<StepProgress steps={CHECKOUT_STEPS} activeStep={0} />
|
|
<ScrollView contentContainerStyle={styles.content}>
|
|
<Text style={styles.sectionTitle}>Deliver to</Text>
|
|
|
|
{addresses.length === 0 && (
|
|
<View style={styles.emptyState}>
|
|
<Text style={styles.emptyStateText}>No saved addresses yet.</Text>
|
|
</View>
|
|
)}
|
|
|
|
{addresses.map(address => {
|
|
const isSelected = selectedAddressId === address.id;
|
|
return (
|
|
<TouchableOpacity
|
|
key={address.id}
|
|
style={[
|
|
styles.addressCard,
|
|
isSelected && styles.addressCardSelected,
|
|
]}
|
|
activeOpacity={0.7}
|
|
onPress={() => setSelectedAddressId(address.id)}
|
|
>
|
|
<View style={styles.addressCardHeader}>
|
|
<View style={styles.labelBadge}>
|
|
<Text style={styles.labelBadgeIcon}>
|
|
{LABEL_ICON[address.label] ?? '📍'}
|
|
</Text>
|
|
<Text style={styles.labelBadgeText}>{address.label}</Text>
|
|
</View>
|
|
|
|
{address.isDefault && (
|
|
<View style={styles.defaultBadge}>
|
|
<Text style={styles.defaultBadgeText}>DEFAULT</Text>
|
|
</View>
|
|
)}
|
|
|
|
<View
|
|
style={[styles.radio, isSelected && styles.radioSelected]}
|
|
>
|
|
{isSelected && <View style={styles.radioInner} />}
|
|
</View>
|
|
</View>
|
|
|
|
<Text style={styles.addressText} numberOfLines={2}>
|
|
{address.houseNumber ? `${address.houseNumber}, ` : ''}
|
|
{address.addressLine1}
|
|
</Text>
|
|
|
|
{!!address.landmark && (
|
|
<Text style={styles.addressSubtext} numberOfLines={1}>
|
|
Landmark: {address.landmark}
|
|
</Text>
|
|
)}
|
|
|
|
<Text style={styles.addressSubtext} numberOfLines={1}>
|
|
{address.city}, {address.state} - {address.postalCode}
|
|
</Text>
|
|
|
|
<Text style={styles.addressPhone}>📞 {address.phone}</Text>
|
|
</TouchableOpacity>
|
|
);
|
|
})}
|
|
|
|
<TouchableOpacity
|
|
style={styles.addAddressButton}
|
|
activeOpacity={0.7}
|
|
onPress={() => {
|
|
// navigation.navigate('AddAddressScreen');
|
|
}}
|
|
>
|
|
<Text style={styles.addAddressButtonText}>+ Add New Address</Text>
|
|
</TouchableOpacity>
|
|
</ScrollView>
|
|
<View style={styles.footer}>
|
|
<PrimaryButton
|
|
title="Continue to Payment"
|
|
onPress={handleContinue}
|
|
disabled={!selectedAddressId}
|
|
/>
|
|
</View>
|
|
</View>
|
|
);
|
|
};
|