From db9619eb1f80f4ccb204f80adde885e3c6b58339 Mon Sep 17 00:00:00 2001 From: Gaurav598 Date: Wed, 23 Sep 2026 01:15:32 +0530 Subject: [PATCH] Fix UI glitches, notification duplication, and duplicate bids --- admin-dashboard/index.html | 1 + admin-dashboard/public/favicon.svg | 9 +++++++++ .../src/components/PopupNotifications.tsx | 16 ++++++++++------ .../src/context/NotificationContext.tsx | 13 +++++++------ .../src/screens/AvailableBookingsScreen.tsx | 17 ++++++++++++----- .../src/screens/RideTrackingScreen.tsx | 9 ++++++++- mobile/FluxRider/src/store/slices/riderSlice.ts | 3 ++- .../src/components/PopupNotifications.tsx | 16 ++++++++++------ .../src/context/NotificationContext.tsx | 13 +++++++------ .../src/screens/ActiveBookingScreen.tsx | 12 +----------- mobile/FluxUser/src/screens/RatingScreen.tsx | 14 +++++++++----- 11 files changed, 76 insertions(+), 47 deletions(-) create mode 100644 admin-dashboard/public/favicon.svg diff --git a/admin-dashboard/index.html b/admin-dashboard/index.html index 48223c9..12c45f9 100644 --- a/admin-dashboard/index.html +++ b/admin-dashboard/index.html @@ -4,6 +4,7 @@ Flux Admin Dashboard +
diff --git a/admin-dashboard/public/favicon.svg b/admin-dashboard/public/favicon.svg new file mode 100644 index 0000000..81a8e6d --- /dev/null +++ b/admin-dashboard/public/favicon.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/mobile/FluxRider/src/components/PopupNotifications.tsx b/mobile/FluxRider/src/components/PopupNotifications.tsx index b77b0c7..8daed24 100644 --- a/mobile/FluxRider/src/components/PopupNotifications.tsx +++ b/mobile/FluxRider/src/components/PopupNotifications.tsx @@ -10,6 +10,7 @@ import { import {X, Bell, CheckCircle, AlertCircle} from 'lucide-react-native'; import {useNotification} from '../context/NotificationContext'; import {colors} from '../theme'; +import CardGradient from './CardGradient'; const NotificationItem: React.FC<{ id: string; @@ -68,7 +69,7 @@ const NotificationItem: React.FC<{ }; const getBgColor = () => { - return colors.surface; + return colors.surfaceAlt; }; const getBorderColor = () => { @@ -89,12 +90,15 @@ const NotificationItem: React.FC<{ style={[ styles.container, { - backgroundColor: getBgColor(), + backgroundColor: colors.bg, borderColor: getBorderColor(), transform: [{translateY}], opacity, }, ]}> + + + ( export const NotificationProvider: React.FC<{children: React.ReactNode}> = ({ children, }) => { + const seenIds = useRef>(new Set()); const [notifications, setNotifications] = useState([]); const hideNotification = useCallback((id: string) => { @@ -32,12 +33,12 @@ export const NotificationProvider: React.FC<{children: React.ReactNode}> = ({ (notification: Notification | Omit) => { const id = 'id' in notification && notification.id ? notification.id : Math.random().toString(36).substring(7); + if (seenIds.current.has(id)) { + return; // Ignore if we've already shown this + } + seenIds.current.add(id); + setNotifications(prev => { - // Deduplicate: if a notification with this ID already exists, don't add it again - if (prev.some(n => n.id === id)) { - return prev; - } - // Auto hide after 5 seconds for new notifications setTimeout(() => { hideNotification(id); diff --git a/mobile/FluxRider/src/screens/AvailableBookingsScreen.tsx b/mobile/FluxRider/src/screens/AvailableBookingsScreen.tsx index bdaf076..9b4c8a4 100644 --- a/mobile/FluxRider/src/screens/AvailableBookingsScreen.tsx +++ b/mobile/FluxRider/src/screens/AvailableBookingsScreen.tsx @@ -58,6 +58,15 @@ const AvailableBookingsScreen = ({navigation}: any) => { return Number.isFinite(num) && Math.abs(num) <= 180; }; + + useEffect(() => { + if (availableBookings.length > 0 && currentIndex >= availableBookings.length) { + setCurrentIndex(availableBookings.length - 1); + } else if (availableBookings.length === 0 && currentIndex !== 0) { + setCurrentIndex(0); + } + }, [availableBookings.length, currentIndex]); + const fetchAvailableBookings = useCallback( async (lat?: number, lng?: number) => { const latitude = lat || currentLocation?.latitude || 28.6139; @@ -125,7 +134,6 @@ const AvailableBookingsScreen = ({navigation}: any) => { .filter(Boolean); dispatch(setAvailableBookings(bookings)); - setCurrentIndex(0); } catch (error: any) { console.log('Error fetching bookings:', error); Alert.alert( @@ -231,7 +239,6 @@ const AvailableBookingsScreen = ({navigation}: any) => { dispatch(addBid(response.data)); Alert.alert('Success', 'Bid placed successfully!'); setBidAmount(''); - handleNext(); } catch (error: any) { Alert.alert( 'Error', @@ -249,7 +256,7 @@ const AvailableBookingsScreen = ({navigation}: any) => { const response = await api.post(`/bookings/${currentBooking.id}/accept-user-price`); Alert.alert('Success', 'You have accepted this ride!'); dispatch(setAvailableBookings([])); - navigation.navigate('ActiveBooking'); + (navigation as any).replace('RideTracking', { bookingId: currentBooking.id }); } catch (error: any) { Alert.alert( 'Error', @@ -655,10 +662,10 @@ const styles = StyleSheet.create({ elevation: 10, }, cardScroll: { - maxHeight: 404, + maxHeight: 600, }, cardScrollContent: { - paddingBottom: 6, + paddingBottom: 24, }, bidInputContainer: { flex: 1, diff --git a/mobile/FluxRider/src/screens/RideTrackingScreen.tsx b/mobile/FluxRider/src/screens/RideTrackingScreen.tsx index c30bcc9..054a94e 100644 --- a/mobile/FluxRider/src/screens/RideTrackingScreen.tsx +++ b/mobile/FluxRider/src/screens/RideTrackingScreen.tsx @@ -97,7 +97,14 @@ const RideTrackingScreen = () => { try { const response = await api.get(`/bookings/${resolvedBookingId}`); setBooking(response.data); - const nextStatus = String(response.data?.status || 'ACCEPTED') as + const status = response.data?.status; + if (status === 'CANCELLED_BY_USER' || status === 'CANCELLED') { + Alert.alert('Ride Cancelled', 'The user has cancelled the ride.'); + (navigation as any).replace('Home'); + return; + } + + const nextStatus = String(status || 'ACCEPTED') as | 'ACCEPTED' | 'RIDER_EN_ROUTE' | 'RIDER_ARRIVED' diff --git a/mobile/FluxRider/src/store/slices/riderSlice.ts b/mobile/FluxRider/src/store/slices/riderSlice.ts index 9bda0b8..9db7d9e 100644 --- a/mobile/FluxRider/src/store/slices/riderSlice.ts +++ b/mobile/FluxRider/src/store/slices/riderSlice.ts @@ -90,7 +90,8 @@ const riderSlice = createSlice({ state.currentLocation = action.payload; }, setAvailableBookings: (state, action: PayloadAction) => { - state.availableBookings = action.payload; + const biddedIds = new Set(state.myBids.map(bid => bid.bookingId)); + state.availableBookings = action.payload.filter(b => !biddedIds.has(b.id)); }, addAvailableBooking: (state, action: PayloadAction) => { const exists = state.availableBookings.find( diff --git a/mobile/FluxUser/src/components/PopupNotifications.tsx b/mobile/FluxUser/src/components/PopupNotifications.tsx index 27ca0e3..be13975 100644 --- a/mobile/FluxUser/src/components/PopupNotifications.tsx +++ b/mobile/FluxUser/src/components/PopupNotifications.tsx @@ -10,6 +10,7 @@ import { import {X, Bell, CheckCircle, AlertCircle} from 'lucide-react-native'; import {useNotification} from '../context/NotificationContext'; import {colors} from '../theme'; +import CardGradient from './CardGradient'; const NotificationItem: React.FC<{ id: string; @@ -69,7 +70,7 @@ const NotificationItem: React.FC<{ }; const getBgColor = () => { - return colors.surface; + return colors.surfaceAlt; }; const getBorderColor = () => { @@ -90,12 +91,15 @@ const NotificationItem: React.FC<{ style={[ styles.container, { - backgroundColor: getBgColor(), + backgroundColor: colors.bg, borderColor: getBorderColor(), transform: [{translateY}], opacity, }, ]}> + + + ( export const NotificationProvider: React.FC<{children: React.ReactNode}> = ({ children, }) => { + const seenIds = useRef>(new Set()); const [notifications, setNotifications] = useState([]); const hideNotification = useCallback((id: string) => { @@ -32,12 +33,12 @@ export const NotificationProvider: React.FC<{children: React.ReactNode}> = ({ (notification: Notification | Omit) => { const id = 'id' in notification && notification.id ? notification.id : Math.random().toString(36).substring(7); + if (seenIds.current.has(id)) { + return; // Ignore if we've already shown this + } + seenIds.current.add(id); + setNotifications(prev => { - // Deduplicate: if a notification with this ID already exists, don't add it again - if (prev.some(n => n.id === id)) { - return prev; - } - // Auto hide after 5 seconds for new notifications setTimeout(() => { hideNotification(id); diff --git a/mobile/FluxUser/src/screens/ActiveBookingScreen.tsx b/mobile/FluxUser/src/screens/ActiveBookingScreen.tsx index 6487362..3b3015b 100644 --- a/mobile/FluxUser/src/screens/ActiveBookingScreen.tsx +++ b/mobile/FluxUser/src/screens/ActiveBookingScreen.tsx @@ -164,17 +164,7 @@ const ActiveBookingScreen = () => { if (intervalRef.current) { clearInterval(intervalRef.current); } - Alert.alert( - 'Rider Cancelled', - 'The rider has cancelled. Finding another rider for you...', - [ - { - text: 'OK', - onPress: () => - (navigation as any).replace('BidSelection', {bookingId}), - }, - ], - ); + (navigation as any).replace('BidSelection', {bookingId}); } } catch (error) { console.log('Error fetching booking:', error); diff --git a/mobile/FluxUser/src/screens/RatingScreen.tsx b/mobile/FluxUser/src/screens/RatingScreen.tsx index cc1a1b1..6dc93de 100644 --- a/mobile/FluxUser/src/screens/RatingScreen.tsx +++ b/mobile/FluxUser/src/screens/RatingScreen.tsx @@ -6,6 +6,8 @@ import { TextInput, Alert, SafeAreaView, + KeyboardAvoidingView, + Platform, ScrollView, Animated, ActivityIndicator, @@ -137,8 +139,9 @@ const RatingScreen = ({navigation, route}: any) => { return ( - - + + + navigation.goBack()} className="p-2.5 rounded-xl border self-start mb-10" @@ -149,7 +152,7 @@ const RatingScreen = ({navigation, route}: any) => { - + @@ -166,7 +169,7 @@ const RatingScreen = ({navigation, route}: any) => { { )} - + + ); };