import React, { useState } from 'react'; import { View, Alert, ScrollView } from 'react-native'; import { useMutation } from '@tanstack/react-query'; import { Formik } from 'formik'; import * as Yup from 'yup'; import * as Location from 'expo-location'; import { tw, MyText, MyTouchableOpacity , Checkbox , MyTextInput , LoadingDialog } from 'common-ui'; import { trpc } from '../trpc-client'; interface AddressFormProps { onSuccess: () => void; initialValues?: { id?: number; name: string; phone: string; addressLine1: string; addressLine2: string; city: string; state: string; pincode: string; isDefault: boolean; latitude?: number; longitude?: number; googleMapsLocation?: string; }; isEdit?: boolean; } const AddressForm: React.FC = ({ onSuccess, initialValues, isEdit = false }) => { const [locationLoading, setLocationLoading] = useState(false); const [locationError, setLocationError] = useState(null); const [isSubmitting, setIsSubmitting] = useState(false); const [showGoogleMapsField, setShowGoogleMapsField] = useState(false); const [currentLocation, setCurrentLocation] = useState<{ latitude: number; longitude: number } | null>( initialValues?.latitude && initialValues?.longitude ? { latitude: initialValues.latitude, longitude: initialValues.longitude } : null ); const createAddressMutation = trpc.user.address.createAddress.useMutation({ onSuccess: () => { setIsSubmitting(false); setTimeout(() => onSuccess(), 100); }, onError: (error: any) => { setIsSubmitting(false); Alert.alert('Error', error.message || 'Failed to save address'); }, }); const updateAddressMutation = trpc.user.address.updateAddress.useMutation({ onSuccess: () => { setIsSubmitting(false); setTimeout(() => onSuccess(), 100); }, onError: (error: any) => { setIsSubmitting(false); Alert.alert('Error', error.message || 'Failed to update address'); }, }); const attachCurrentLocation = async () => { setLocationLoading(true); setLocationError(null); try { const { status } = await Location.requestForegroundPermissionsAsync(); if (status !== 'granted') { setLocationError('Location Permission denied'); return; } const location = await Location.getCurrentPositionAsync({ accuracy: Location.Accuracy.High, }); const { latitude, longitude } = location.coords; setCurrentLocation({ latitude, longitude }); } catch (error) { console.error('Location error:', error); setLocationError('Unable to fetch location. Please check your GPS settings.'); } finally { setLocationLoading(false); } }; const validationSchema = Yup.object({ name: Yup.string().required('Name is required'), phone: Yup.string().required('Phone is required').matches(/^\d{10}$/, 'Phone must be 10 digits'), addressLine1: Yup.string().required('Address Line 1 is required'), addressLine2: Yup.string(), city: Yup.string().required('City is required'), state: Yup.string().required('State is required'), pincode: Yup.string().required('Pincode is required').matches(/^\d{6}$/, 'Pincode must be 6 digits'), isDefault: Yup.boolean(), }); return ( {isEdit ? 'Edit Address' : 'Add Address'} { setIsSubmitting(true); const payload = { ...values, latitude: currentLocation?.latitude, longitude: currentLocation?.longitude, googleMapsLocation: values.googleMapsLocation || undefined, }; if (isEdit && initialValues?.id) { updateAddressMutation.mutate({ id: initialValues.id, ...payload }); } else { createAddressMutation.mutate(payload); } }} > {({ handleChange, handleBlur, handleSubmit, values, errors, touched, setFieldValue }) => ( {touched.name && errors.name && {errors.name}} {touched.phone && errors.phone && {errors.phone}} {touched.addressLine1 && errors.addressLine1 && {errors.addressLine1}} {touched.city && errors.city && {errors.city}} {touched.state && errors.state && {errors.state}} {touched.pincode && errors.pincode && {errors.pincode}} {locationLoading ? ( Fetching location... ) : locationError ? ( {locationError} ) : currentLocation ? ( Current Location Attached attachCurrentLocation()} disabled={locationLoading} style={tw`ml-4`} > Change ) : ( attachCurrentLocation()} disabled={locationLoading} style={tw`mb-4`} > Attach Current Location )} setShowGoogleMapsField(true)} disabled={false} style={tw`mb-1`} > Attach with Google Maps {showGoogleMapsField && ( 1. Open Google Maps and Find location{'\n'} 2. Long press the desired location{'\n'} 3. Click on Share and Click on Copy{'\n'} 4. Paste the copied url here in the field. )} setFieldValue('isDefault', !values.isDefault)} /> Set as default address handleSubmit()} disabled={isSubmitting} > {isSubmitting ? (isEdit ? 'Updating...' : 'Adding...') : (isEdit ? 'Update Address' : 'Add Address')} )} ); }; export default AddressForm;