diff --git a/app/(tabs)/payments.tsx b/app/(tabs)/payments.tsx index 5d3c927..cfc695c 100644 --- a/app/(tabs)/payments.tsx +++ b/app/(tabs)/payments.tsx @@ -429,15 +429,23 @@ export default function PaymentsTabScreen() { router.push("/payments/selectAmount")} + disabled={isLoading || !emiDetails} > Pay EMI router.push("/payments/myPlan")} + disabled={isLoading || !emiDetails} > View Plan diff --git a/app/(tabs)/service.tsx b/app/(tabs)/service.tsx index 1e78f93..dc849ea 100644 --- a/app/(tabs)/service.tsx +++ b/app/(tabs)/service.tsx @@ -8,6 +8,8 @@ import { StyleSheet, GestureResponderEvent, ScrollView, + KeyboardAvoidingView, + Platform, } from "react-native"; import { Dropdown } from "react-native-element-dropdown"; import { DateTimePickerAndroid } from "@react-native-community/datetimepicker"; @@ -85,7 +87,7 @@ export default function ServiceFormScreen(): JSX.Element { DateTimePickerAndroid.open({ value: now, mode: "date", - is24Hour: true, + is24Hour: false, display: "default", onChange: (event, selectedDate) => { if (event.type === "set" && selectedDate) { @@ -93,7 +95,7 @@ export default function ServiceFormScreen(): JSX.Element { DateTimePickerAndroid.open({ value: selectedDate, mode: "time", - is24Hour: true, + is24Hour: false, display: "default", onChange: (timeEvent, selectedTime) => { if (timeEvent.type === "set" && selectedTime) { @@ -115,8 +117,17 @@ export default function ServiceFormScreen(): JSX.Element { }; return ( - <> - + + - {values.comments.length}/100 words + {values.comments?.length || 0}/100 words @@ -312,17 +323,20 @@ export default function ServiceFormScreen(): JSX.Element { )} - + ); } -// styles stay unchanged - const styles = StyleSheet.create({ + container: { + flex: 1, + }, inputContainer: {}, screen: { flex: 1, backgroundColor: "#F3F5F8", + }, + scrollContent: { paddingBottom: 116, }, topBar: { diff --git a/app/payments/Confirmation.tsx b/app/payments/Confirmation.tsx index 028adb3..959945b 100644 --- a/app/payments/Confirmation.tsx +++ b/app/payments/Confirmation.tsx @@ -5,6 +5,8 @@ import { useSelector } from "react-redux"; import { RootState } from "@/store/rootReducer"; import Header from "@/components/common/Header"; import CheckCircle from "@/assets/icons/check_circle.svg"; +import Pending from "@/assets/icons/pending.svg"; +import Failed from "@/assets/icons/cancel.svg"; import { useSafeAreaInsets } from "react-native-safe-area-context"; const PaymentConfirmationScreen = () => { @@ -15,6 +17,9 @@ const PaymentConfirmationScreen = () => { const insets = useSafeAreaInsets(); + // Get payment status - assuming it comes from paymentOrder.status + const paymentStatus = paymentOrder?.status || "confirmed"; + // Format amount with currency const formatAmount = (amount: number | null) => { if (!amount) return "₹0"; @@ -45,6 +50,43 @@ const PaymentConfirmationScreen = () => { }); }; + // Get icon and text based on status + const getStatusDisplay = () => { + switch (paymentStatus) { + case "confirmed": + return { + icon: , + text: "Payment successful", + iconContainerStyle: styles.successIconContainer, + }; + case "failure": + return { + icon: , + text: "Payment failed", + iconContainerStyle: styles.failureIconContainer, + }; + case "pending": + return { + icon: , + text: "Payment pending", + iconContainerStyle: styles.pendingIconContainer, + }; + default: + return { + icon: , + text: "Payment successful", + iconContainerStyle: styles.successIconContainer, + }; + } + }; + + const statusDisplay = getStatusDisplay(); + + // Helper function to display value or "--" if missing + const displayValue = (value: any) => { + return value ? String(value) : "--"; + }; + return (
@@ -52,15 +94,15 @@ const PaymentConfirmationScreen = () => { - - + + {statusDisplay.icon} {formatAmount(paymentOrder?.amount || due_amount)} - Payment successful + {statusDisplay.text} {formatDate(paymentOrder?.transaction_date)} @@ -75,42 +117,43 @@ const PaymentConfirmationScreen = () => { Payment mode - {paymentOrder?.payment_mode?.[0] || "UPI"} + {displayValue(paymentOrder?.payment_mode?.[0])} Paid to - {paymentOrder?.upi_handle || "randomupiid@vecpay"} + {displayValue(paymentOrder?.upi_handle)} Paid by - {paymentOrder?.paid_by_upi_handle || "amar.kesari@vecpay"} + {displayValue(paymentOrder?.paid_by_upi_handle)} Order ID - {paymentOrder?.order_id || "1000516861984940"} + {displayValue(paymentOrder?.order_id)} Transaction ID - {paymentOrder?.transaction_id || - paymentOrder?.transaction_order_id || - "1000516861984940"} + {displayValue( + paymentOrder?.transaction_id || + paymentOrder?.transaction_order_id + )} RRN - {paymentOrder?.payment_reference_id || "1000516861984940"} + {displayValue(paymentOrder?.payment_reference_id)} @@ -153,6 +196,14 @@ const styles = StyleSheet.create({ marginBottom: 16, alignItems: "center", }, + failureIconContainer: { + marginBottom: 16, + alignItems: "center", + }, + pendingIconContainer: { + marginBottom: 16, + alignItems: "center", + }, successIcon: { // Icon styling handled by Ionicons }, diff --git a/app/payments/payEmi.tsx b/app/payments/payEmi.tsx index 4a9fa5c..6882453 100644 --- a/app/payments/payEmi.tsx +++ b/app/payments/payEmi.tsx @@ -143,26 +143,6 @@ const UpiPaymentScreen = () => { } }; - const sharePaymentDetails = async (): Promise => { - try { - const shareMessage = - `Payment Request\n\n` + - `Amount: ${formatAmount(paymentOrder.amount)}\n` + - `UPI ID: ${paymentOrder.upi_handle}\n` + - `Order ID: ${paymentOrder.order_id}\n` + - `Transaction ID: ${paymentOrder.transaction_id}\n` + - `Expires: ${getExpiryTime()}\n\n` + - `UPI Link: ${getUpiUrl()}`; - - await Share.share({ - message: shareMessage, - title: "UPI Payment Details", - }); - } catch (error) { - showSnackbar("Failed to share payment details", "error"); - } - }; - const shareQR = async (): Promise => { try { if (await Sharing.isAvailableAsync()) { @@ -207,6 +187,10 @@ const UpiPaymentScreen = () => { } }; + function handlePaymentDone() { + router.push("/(tabs)/payments"); + } + return (
@@ -216,13 +200,13 @@ const UpiPaymentScreen = () => { Amount to be paid - {formatAmount(paymentOrder.amount)} + {formatAmount(paymentOrder?.amount)} @@ -242,20 +226,53 @@ const UpiPaymentScreen = () => { Download QR + + Pay using UPI app + + + + + Confirm once your payment is completed. + + handlePaymentDone()} + style={styles.paymentDone} + > + Payment Done + - - - Pay using UPI app - ); }; const styles = StyleSheet.create({ + doneText: { + textAlign: "center", + fontWeight: "500", + fontSize: 14, + lineHeight: 20, + }, + paymentDone: { + padding: 16, + borderWidth: 1, + borderColor: "#DCE1E9", + }, + confirmTitle: { + fontWeight: "400", + fontSize: 14, + lineHeight: 14, + color: "#252A34", + }, + confirm: { + padding: 16, + flexDirection: "column", + backgroundColor: "#FCFCFC", + gap: 16, + }, container: { flex: 1, backgroundColor: "#F3F5F8", @@ -288,9 +305,9 @@ const styles = StyleSheet.create({ }, content: { flex: 1, - justifyContent: "space-between", paddingHorizontal: 16, paddingBottom: 16, + justifyContent: "space-between", }, qrFrame: { backgroundColor: "#FCFCFC", @@ -327,19 +344,18 @@ const styles = StyleSheet.create({ color: "#FFFFFF", }, qrCodeContainer: { - width: 200, - height: 200, - justifyContent: "center", - alignItems: "center", marginBottom: 16, borderWidth: 2, borderColor: "#E5E9F0", - padding: 12, + padding: 16, borderRadius: 8, + width: "100%", + height: "auto", }, qrCode: { width: "100%", - height: "100%", + aspectRatio: 1, + alignSelf: "center", }, upiIdSection: { flexDirection: "row", @@ -398,6 +414,8 @@ const styles = StyleSheet.create({ paddingVertical: 12, paddingHorizontal: 16, borderRadius: 4, + marginTop: 16, + width: "100%", alignItems: "center", }, primaryButtonText: { diff --git a/app/user/MyVechicle.tsx b/app/user/MyVechicle.tsx new file mode 100644 index 0000000..a96f6bb --- /dev/null +++ b/app/user/MyVechicle.tsx @@ -0,0 +1,186 @@ +import React, { useEffect } from "react"; +import { + View, + Text, + StyleSheet, + TouchableOpacity, + SafeAreaView, + StatusBar, + ActivityIndicator, +} from "react-native"; +import { useDispatch, useSelector } from "react-redux"; +import { RootState } from "../../store/rootReducer"; // Adjust path as needed +import { getUserDetails } from "../../store/userSlice"; +import { AppDispatch } from "@/store"; +import Header from "@/components/common/Header"; + +interface MyVehicleScreenProps { + navigation?: any; // Replace with proper navigation type +} + +const MyVehicleScreen: React.FC = ({ navigation }) => { + const dispatch = useDispatch(); + const { + data: userData, + loading, + error, + } = useSelector((state: RootState) => state.user); + + useEffect(() => { + // Fetch user details when component mounts + if (!userData) { + dispatch(getUserDetails()); + } + }, [dispatch, userData]); + + // Get the first vehicle from the user data + const vehicle = userData?.vehicles?.[0]; + + if (loading) { + return ( + + + + + Loading vehicle details... + + + ); + } + + if (error) { + return ( + + + + Error: {error} + + + ); + } + + return ( + <> +
+ + + {/* OEM - Model */} + + OEM - Model + + {vehicle?.model ? `Yatri - ${vehicle.model}` : "--"} + + + + + + {/* Chassis Number */} + + Chassis Number + {vehicle?.chasis_number || "--"} + + + + + {/* Vehicle ID */} + + Vehicle ID + + {vehicle?.vehicle_id ? vehicle.vehicle_id.toString() : "--"} + + + + + + ); +}; + +const styles = StyleSheet.create({ + container: { + flex: 1, + backgroundColor: "#ffffff", + }, + header: { + flexDirection: "row", + alignItems: "center", + paddingHorizontal: 16, + paddingVertical: 12, + borderBottomWidth: 1, + borderBottomColor: "#f0f0f0", + }, + backButton: { + marginRight: 12, + padding: 4, + }, + backIcon: { + width: 24, + height: 24, + justifyContent: "center", + alignItems: "center", + }, + backIconText: { + fontSize: 20, + fontWeight: "600", + color: "#25324B", + }, + headerTitle: { + fontSize: 18, + fontWeight: "600", + color: "#25324B", + }, + content: { + flex: 1, + paddingHorizontal: 16, + paddingTop: 16, + }, + itemContainer: { + backgroundColor: "#FCFCFC", + borderRadius: 8, + overflow: "hidden", + }, + item: { + paddingHorizontal: 16, + paddingVertical: 16, + }, + label: { + fontSize: 14, + color: "#25324B", + fontWeight: "400", + marginBottom: 4, + lineHeight: 20, + }, + value: { + fontSize: 14, + color: "#25324B", + fontWeight: "600", + lineHeight: 20, + }, + divider: { + height: 1, + backgroundColor: "#E5E9F0", + marginHorizontal: 16, + }, + loadingContainer: { + flex: 1, + justifyContent: "center", + alignItems: "center", + }, + loadingText: { + marginTop: 16, + fontSize: 16, + color: "#25324B", + }, + errorContainer: { + flex: 1, + justifyContent: "center", + alignItems: "center", + paddingHorizontal: 16, + }, + errorText: { + fontSize: 16, + color: "#FF6B6B", + textAlign: "center", + }, +}); + +export default MyVehicleScreen; diff --git a/app/user/_layout.tsx b/app/user/_layout.tsx index 3699e76..9df44da 100644 --- a/app/user/_layout.tsx +++ b/app/user/_layout.tsx @@ -12,7 +12,7 @@ export default function UserLayout() { +
- {menuItem("My Vehicle")} + {menuItem("My Vehicle", () => router.push("/user/MyVechicle"))} {menuItem("Language", () => toggleLanguageModal())}