From 001dd62aa535125d7daad08a55812ee160f356f5 Mon Sep 17 00:00:00 2001 From: shafi54 <108669266+shafi-aviz@users.noreply.github.com> Date: Sun, 1 Feb 2026 14:01:22 +0530 Subject: [PATCH] enh --- apps/user-ui/src/components/AddressForm.tsx | 56 +++++++++++++++++---- packages/ui/src/components/dialog.tsx | 35 +++++++++++-- 2 files changed, 75 insertions(+), 16 deletions(-) diff --git a/apps/user-ui/src/components/AddressForm.tsx b/apps/user-ui/src/components/AddressForm.tsx index 06e95ed..dbd3263 100644 --- a/apps/user-ui/src/components/AddressForm.tsx +++ b/apps/user-ui/src/components/AddressForm.tsx @@ -1,5 +1,5 @@ import React, { useState } from 'react'; -import { View, Alert, ScrollView } from 'react-native'; +import { View, ScrollView } from 'react-native'; import { useMutation } from '@tanstack/react-query'; import { Formik } from 'formik'; import * as Yup from 'yup'; @@ -30,39 +30,44 @@ const AddressForm: React.FC = ({ onSuccess, initialValues, isE const [locationLoading, setLocationLoading] = useState(false); const [locationError, setLocationError] = useState(null); const [isSubmitting, setIsSubmitting] = useState(false); + const [submitError, setSubmitError] = useState(null); const [showGoogleMapsField, setShowGoogleMapsField] = useState(!!initialValues?.googleMapsUrl); const [currentLocation, setCurrentLocation] = useState<{ latitude: number; longitude: number } | null>( initialValues?.latitude && initialValues?.longitude ? { latitude: initialValues.latitude, longitude: initialValues.longitude } : null ); + const [locationSuccess, setLocationSuccess] = useState(false); const createAddressMutation = trpc.user.address.createAddress.useMutation({ onSuccess: (data) => { setIsSubmitting(false); const addressId = data?.data?.id; - setTimeout(() => onSuccess(addressId), 100); + // Delay to allow modal to close animation + setTimeout(() => onSuccess(addressId), 350); }, onError: (error: any) => { setIsSubmitting(false); - Alert.alert('Error', error.message || 'Failed to save address'); + setSubmitError(error.message || 'Failed to save address'); }, }); const updateAddressMutation = trpc.user.address.updateAddress.useMutation({ onSuccess: () => { setIsSubmitting(false); - setTimeout(() => onSuccess(), 100); + // Delay to allow modal to close animation + setTimeout(() => onSuccess(), 350); }, onError: (error: any) => { setIsSubmitting(false); - Alert.alert('Error', error.message || 'Failed to update address'); + setSubmitError(error.message || 'Failed to update address'); }, }); const attachCurrentLocation = async () => { setLocationLoading(true); setLocationError(null); + setLocationSuccess(false); try { const { status } = await Location.requestForegroundPermissionsAsync(); @@ -78,7 +83,9 @@ const AddressForm: React.FC = ({ onSuccess, initialValues, isE const { latitude, longitude } = location.coords; setCurrentLocation({ latitude, longitude }); - Alert.alert('Success', 'Location attached successfully'); + setLocationSuccess(true); + // Clear success message after 3 seconds + setTimeout(() => setLocationSuccess(false), 3000); } catch (error) { setLocationError('Unable to fetch location. Please check your GPS settings.'); } finally { @@ -98,8 +105,19 @@ const AddressForm: React.FC = ({ onSuccess, initialValues, isE }); return ( - + {isEdit ? 'Edit Address' : 'Add Address'} + + {/* Submit Error Message */} + {submitError && ( + + {submitError} + + )} = ({ onSuccess, initialValues, isE }} validationSchema={validationSchema} onSubmit={(values) => { - setIsSubmitting(true); - const payload = { - ...values, + setIsSubmitting(true); + setSubmitError(null); + const payload = { + ...values, latitude: currentLocation?.latitude, longitude: currentLocation?.longitude, googleMapsUrl: values.googleMapsUrl || undefined, @@ -203,9 +222,24 @@ const AddressForm: React.FC = ({ onSuccess, initialValues, isE Fetching location... ) : locationError ? ( {locationError} + ) : locationSuccess ? ( + + + ✓ Location Attached + + attachCurrentLocation()} + disabled={locationLoading} + style={tw`ml-4`} + > + Attach Current + + ) : currentLocation ? ( - Location Attached + + ✓ Location Attached + attachCurrentLocation()} disabled={locationLoading} diff --git a/packages/ui/src/components/dialog.tsx b/packages/ui/src/components/dialog.tsx index 05ece7b..ac58985 100755 --- a/packages/ui/src/components/dialog.tsx +++ b/packages/ui/src/components/dialog.tsx @@ -1,5 +1,5 @@ import React, { ReactNode, useState } from 'react'; -import { Modal, View, TouchableOpacity, StyleSheet, Animated, Easing, Dimensions, TextInput } from 'react-native'; +import { Modal, View, TouchableOpacity, StyleSheet, Animated, Easing, Dimensions, TextInput, KeyboardAvoidingView, Platform, ScrollView } from 'react-native'; import MyText from './text'; import { MyButton } from 'common-ui'; @@ -53,7 +53,20 @@ export const BottomDialog: React.FC = ({ open, onClose, children, e ]} > - {children} + + + {children} + + ); @@ -71,19 +84,18 @@ const styles = StyleSheet.create({ position: 'absolute', left: 0, right: 0, - // top: SCREEN_HEIGHT * 0.3, bottom: 0, backgroundColor: '#fff', borderTopLeftRadius: 18, borderTopRightRadius: 18, paddingHorizontal: 20, - // paddingTop: 16, paddingBottom: 0, elevation: 8, shadowColor: '#000', shadowOffset: { width: 0, height: -2 }, shadowOpacity: 0.2, shadowRadius: 8, + maxHeight: SCREEN_HEIGHT * 0.85, // Limit max height so it doesn't cover entire screen }, handle: { width: 40, @@ -91,7 +103,20 @@ const styles = StyleSheet.create({ borderRadius: 3, backgroundColor: '#ccc', alignSelf: 'center', - // marginBottom: 12, + marginTop: 12, + marginBottom: 8, + }, + keyboardAvoidingContainer: { + flex: 1, + width: '100%', + }, + scrollContainer: { + flex: 1, + width: '100%', + }, + scrollContent: { + flexGrow: 1, + paddingBottom: Platform.OS === 'ios' ? 40 : 20, // Extra padding for iOS keyboard }, });