Fix Ui
parent
9dd62f9377
commit
c5a3e5b8a0
|
|
@ -429,15 +429,23 @@ export default function PaymentsTabScreen() {
|
||||||
|
|
||||||
<View style={styles.buttonContainer}>
|
<View style={styles.buttonContainer}>
|
||||||
<TouchableOpacity
|
<TouchableOpacity
|
||||||
style={styles.primaryButton}
|
style={[
|
||||||
|
styles.primaryButton,
|
||||||
|
(isLoading || !emiDetails) && { opacity: 0.5 }, // dim if disabled
|
||||||
|
]}
|
||||||
onPress={() => router.push("/payments/selectAmount")}
|
onPress={() => router.push("/payments/selectAmount")}
|
||||||
|
disabled={isLoading || !emiDetails}
|
||||||
>
|
>
|
||||||
<Text style={styles.primaryButtonText}>Pay EMI</Text>
|
<Text style={styles.primaryButtonText}>Pay EMI</Text>
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
|
|
||||||
<TouchableOpacity
|
<TouchableOpacity
|
||||||
style={styles.tertiaryButton}
|
style={[
|
||||||
|
styles.tertiaryButton,
|
||||||
|
(isLoading || !emiDetails) && { opacity: 0.5 },
|
||||||
|
]}
|
||||||
onPress={() => router.push("/payments/myPlan")}
|
onPress={() => router.push("/payments/myPlan")}
|
||||||
|
disabled={isLoading || !emiDetails}
|
||||||
>
|
>
|
||||||
<Text style={styles.tertiaryButtonText}>View Plan</Text>
|
<Text style={styles.tertiaryButtonText}>View Plan</Text>
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,8 @@ import {
|
||||||
StyleSheet,
|
StyleSheet,
|
||||||
GestureResponderEvent,
|
GestureResponderEvent,
|
||||||
ScrollView,
|
ScrollView,
|
||||||
|
KeyboardAvoidingView,
|
||||||
|
Platform,
|
||||||
} from "react-native";
|
} from "react-native";
|
||||||
import { Dropdown } from "react-native-element-dropdown";
|
import { Dropdown } from "react-native-element-dropdown";
|
||||||
import { DateTimePickerAndroid } from "@react-native-community/datetimepicker";
|
import { DateTimePickerAndroid } from "@react-native-community/datetimepicker";
|
||||||
|
|
@ -85,7 +87,7 @@ export default function ServiceFormScreen(): JSX.Element {
|
||||||
DateTimePickerAndroid.open({
|
DateTimePickerAndroid.open({
|
||||||
value: now,
|
value: now,
|
||||||
mode: "date",
|
mode: "date",
|
||||||
is24Hour: true,
|
is24Hour: false,
|
||||||
display: "default",
|
display: "default",
|
||||||
onChange: (event, selectedDate) => {
|
onChange: (event, selectedDate) => {
|
||||||
if (event.type === "set" && selectedDate) {
|
if (event.type === "set" && selectedDate) {
|
||||||
|
|
@ -93,7 +95,7 @@ export default function ServiceFormScreen(): JSX.Element {
|
||||||
DateTimePickerAndroid.open({
|
DateTimePickerAndroid.open({
|
||||||
value: selectedDate,
|
value: selectedDate,
|
||||||
mode: "time",
|
mode: "time",
|
||||||
is24Hour: true,
|
is24Hour: false,
|
||||||
display: "default",
|
display: "default",
|
||||||
onChange: (timeEvent, selectedTime) => {
|
onChange: (timeEvent, selectedTime) => {
|
||||||
if (timeEvent.type === "set" && selectedTime) {
|
if (timeEvent.type === "set" && selectedTime) {
|
||||||
|
|
@ -115,8 +117,17 @@ export default function ServiceFormScreen(): JSX.Element {
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<KeyboardAvoidingView
|
||||||
<ScrollView style={styles.screen}>
|
style={styles.container}
|
||||||
|
behavior={Platform.OS === "ios" ? "padding" : "height"}
|
||||||
|
keyboardVerticalOffset={Platform.OS === "ios" ? 100 : 0}
|
||||||
|
>
|
||||||
|
<ScrollView
|
||||||
|
style={styles.screen}
|
||||||
|
contentContainerStyle={styles.scrollContent}
|
||||||
|
keyboardShouldPersistTaps="handled"
|
||||||
|
showsVerticalScrollIndicator={false}
|
||||||
|
>
|
||||||
<Formik
|
<Formik
|
||||||
initialValues={initialValues}
|
initialValues={initialValues}
|
||||||
validationSchema={validationSchema}
|
validationSchema={validationSchema}
|
||||||
|
|
@ -289,7 +300,7 @@ export default function ServiceFormScreen(): JSX.Element {
|
||||||
value={values.comments}
|
value={values.comments}
|
||||||
/>
|
/>
|
||||||
<Text style={styles.wordCount}>
|
<Text style={styles.wordCount}>
|
||||||
{values.comments.length}/100 words
|
{values.comments?.length || 0}/100 words
|
||||||
</Text>
|
</Text>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
|
|
@ -312,17 +323,20 @@ export default function ServiceFormScreen(): JSX.Element {
|
||||||
)}
|
)}
|
||||||
</Formik>
|
</Formik>
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
</>
|
</KeyboardAvoidingView>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// styles stay unchanged
|
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
|
container: {
|
||||||
|
flex: 1,
|
||||||
|
},
|
||||||
inputContainer: {},
|
inputContainer: {},
|
||||||
screen: {
|
screen: {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
backgroundColor: "#F3F5F8",
|
backgroundColor: "#F3F5F8",
|
||||||
|
},
|
||||||
|
scrollContent: {
|
||||||
paddingBottom: 116,
|
paddingBottom: 116,
|
||||||
},
|
},
|
||||||
topBar: {
|
topBar: {
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,8 @@ import { useSelector } from "react-redux";
|
||||||
import { RootState } from "@/store/rootReducer";
|
import { RootState } from "@/store/rootReducer";
|
||||||
import Header from "@/components/common/Header";
|
import Header from "@/components/common/Header";
|
||||||
import CheckCircle from "@/assets/icons/check_circle.svg";
|
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";
|
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
||||||
|
|
||||||
const PaymentConfirmationScreen = () => {
|
const PaymentConfirmationScreen = () => {
|
||||||
|
|
@ -15,6 +17,9 @@ const PaymentConfirmationScreen = () => {
|
||||||
|
|
||||||
const insets = useSafeAreaInsets();
|
const insets = useSafeAreaInsets();
|
||||||
|
|
||||||
|
// Get payment status - assuming it comes from paymentOrder.status
|
||||||
|
const paymentStatus = paymentOrder?.status || "confirmed";
|
||||||
|
|
||||||
// Format amount with currency
|
// Format amount with currency
|
||||||
const formatAmount = (amount: number | null) => {
|
const formatAmount = (amount: number | null) => {
|
||||||
if (!amount) return "₹0";
|
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: <CheckCircle />,
|
||||||
|
text: "Payment successful",
|
||||||
|
iconContainerStyle: styles.successIconContainer,
|
||||||
|
};
|
||||||
|
case "failure":
|
||||||
|
return {
|
||||||
|
icon: <Failed />,
|
||||||
|
text: "Payment failed",
|
||||||
|
iconContainerStyle: styles.failureIconContainer,
|
||||||
|
};
|
||||||
|
case "pending":
|
||||||
|
return {
|
||||||
|
icon: <Pending />,
|
||||||
|
text: "Payment pending",
|
||||||
|
iconContainerStyle: styles.pendingIconContainer,
|
||||||
|
};
|
||||||
|
default:
|
||||||
|
return {
|
||||||
|
icon: <CheckCircle />,
|
||||||
|
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 (
|
return (
|
||||||
<View style={styles.container}>
|
<View style={styles.container}>
|
||||||
<Header title="Payment Status" />
|
<Header title="Payment Status" />
|
||||||
|
|
@ -52,15 +94,15 @@ const PaymentConfirmationScreen = () => {
|
||||||
<View style={styles.contentFrame}>
|
<View style={styles.contentFrame}>
|
||||||
<View style={styles.qrFrame}>
|
<View style={styles.qrFrame}>
|
||||||
<View style={styles.paymentStatusContainer}>
|
<View style={styles.paymentStatusContainer}>
|
||||||
<View style={styles.successIconContainer}>
|
<View style={statusDisplay.iconContainerStyle}>
|
||||||
<CheckCircle />
|
{statusDisplay.icon}
|
||||||
</View>
|
</View>
|
||||||
<Text style={styles.amountText}>
|
<Text style={styles.amountText}>
|
||||||
{formatAmount(paymentOrder?.amount || due_amount)}
|
{formatAmount(paymentOrder?.amount || due_amount)}
|
||||||
</Text>
|
</Text>
|
||||||
|
|
||||||
<View style={styles.statusContainer}>
|
<View style={styles.statusContainer}>
|
||||||
<Text style={styles.statusText}>Payment successful</Text>
|
<Text style={styles.statusText}>{statusDisplay.text}</Text>
|
||||||
<Text style={styles.dateText}>
|
<Text style={styles.dateText}>
|
||||||
{formatDate(paymentOrder?.transaction_date)}
|
{formatDate(paymentOrder?.transaction_date)}
|
||||||
</Text>
|
</Text>
|
||||||
|
|
@ -75,42 +117,43 @@ const PaymentConfirmationScreen = () => {
|
||||||
<View style={styles.detailRow}>
|
<View style={styles.detailRow}>
|
||||||
<Text style={styles.detailLabel}>Payment mode</Text>
|
<Text style={styles.detailLabel}>Payment mode</Text>
|
||||||
<Text style={styles.detailValue}>
|
<Text style={styles.detailValue}>
|
||||||
{paymentOrder?.payment_mode?.[0] || "UPI"}
|
{displayValue(paymentOrder?.payment_mode?.[0])}
|
||||||
</Text>
|
</Text>
|
||||||
</View>
|
</View>
|
||||||
<View style={styles.detailRow}>
|
<View style={styles.detailRow}>
|
||||||
<Text style={styles.detailLabel}>Paid to</Text>
|
<Text style={styles.detailLabel}>Paid to</Text>
|
||||||
<Text style={styles.detailValue}>
|
<Text style={styles.detailValue}>
|
||||||
{paymentOrder?.upi_handle || "randomupiid@vecpay"}
|
{displayValue(paymentOrder?.upi_handle)}
|
||||||
</Text>
|
</Text>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
<View style={styles.detailRow}>
|
<View style={styles.detailRow}>
|
||||||
<Text style={styles.detailLabel}>Paid by</Text>
|
<Text style={styles.detailLabel}>Paid by</Text>
|
||||||
<Text style={styles.detailValue}>
|
<Text style={styles.detailValue}>
|
||||||
{paymentOrder?.paid_by_upi_handle || "amar.kesari@vecpay"}
|
{displayValue(paymentOrder?.paid_by_upi_handle)}
|
||||||
</Text>
|
</Text>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
<View style={styles.detailRow}>
|
<View style={styles.detailRow}>
|
||||||
<Text style={styles.detailLabel}>Order ID</Text>
|
<Text style={styles.detailLabel}>Order ID</Text>
|
||||||
<Text style={styles.detailValue}>
|
<Text style={styles.detailValue}>
|
||||||
{paymentOrder?.order_id || "1000516861984940"}
|
{displayValue(paymentOrder?.order_id)}
|
||||||
</Text>
|
</Text>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
<View style={styles.detailRow}>
|
<View style={styles.detailRow}>
|
||||||
<Text style={styles.detailLabel}>Transaction ID</Text>
|
<Text style={styles.detailLabel}>Transaction ID</Text>
|
||||||
<Text style={styles.detailValue}>
|
<Text style={styles.detailValue}>
|
||||||
{paymentOrder?.transaction_id ||
|
{displayValue(
|
||||||
paymentOrder?.transaction_order_id ||
|
paymentOrder?.transaction_id ||
|
||||||
"1000516861984940"}
|
paymentOrder?.transaction_order_id
|
||||||
|
)}
|
||||||
</Text>
|
</Text>
|
||||||
</View>
|
</View>
|
||||||
<View style={styles.detailRow}>
|
<View style={styles.detailRow}>
|
||||||
<Text style={styles.detailLabel}>RRN</Text>
|
<Text style={styles.detailLabel}>RRN</Text>
|
||||||
<Text style={styles.detailValue}>
|
<Text style={styles.detailValue}>
|
||||||
{paymentOrder?.payment_reference_id || "1000516861984940"}
|
{displayValue(paymentOrder?.payment_reference_id)}
|
||||||
</Text>
|
</Text>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
|
|
@ -153,6 +196,14 @@ const styles = StyleSheet.create({
|
||||||
marginBottom: 16,
|
marginBottom: 16,
|
||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
},
|
},
|
||||||
|
failureIconContainer: {
|
||||||
|
marginBottom: 16,
|
||||||
|
alignItems: "center",
|
||||||
|
},
|
||||||
|
pendingIconContainer: {
|
||||||
|
marginBottom: 16,
|
||||||
|
alignItems: "center",
|
||||||
|
},
|
||||||
successIcon: {
|
successIcon: {
|
||||||
// Icon styling handled by Ionicons
|
// Icon styling handled by Ionicons
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -143,26 +143,6 @@ const UpiPaymentScreen = () => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const sharePaymentDetails = async (): Promise<void> => {
|
|
||||||
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<void> => {
|
const shareQR = async (): Promise<void> => {
|
||||||
try {
|
try {
|
||||||
if (await Sharing.isAvailableAsync()) {
|
if (await Sharing.isAvailableAsync()) {
|
||||||
|
|
@ -207,6 +187,10 @@ const UpiPaymentScreen = () => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function handlePaymentDone() {
|
||||||
|
router.push("/(tabs)/payments");
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SafeAreaView style={styles.container}>
|
<SafeAreaView style={styles.container}>
|
||||||
<Header title="Pay EMI" showBackButton={false} />
|
<Header title="Pay EMI" showBackButton={false} />
|
||||||
|
|
@ -216,13 +200,13 @@ const UpiPaymentScreen = () => {
|
||||||
<View style={styles.amountSection}>
|
<View style={styles.amountSection}>
|
||||||
<Text style={styles.amountLabel}>Amount to be paid</Text>
|
<Text style={styles.amountLabel}>Amount to be paid</Text>
|
||||||
<Text style={styles.amount}>
|
<Text style={styles.amount}>
|
||||||
{formatAmount(paymentOrder.amount)}
|
{formatAmount(paymentOrder?.amount)}
|
||||||
</Text>
|
</Text>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
<View style={styles.qrCodeContainer}>
|
<View style={styles.qrCodeContainer}>
|
||||||
<Image
|
<Image
|
||||||
source={{ uri: paymentOrder.qr_code_url }}
|
source={{ uri: paymentOrder?.qr_code_url }}
|
||||||
style={styles.qrCode}
|
style={styles.qrCode}
|
||||||
contentFit="contain"
|
contentFit="contain"
|
||||||
/>
|
/>
|
||||||
|
|
@ -242,20 +226,53 @@ const UpiPaymentScreen = () => {
|
||||||
<Text style={styles.secondaryButtonText}>Download QR</Text>
|
<Text style={styles.secondaryButtonText}>Download QR</Text>
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
</View>
|
</View>
|
||||||
|
<TouchableOpacity
|
||||||
|
onPress={payUsingUpiApp}
|
||||||
|
style={[styles.primaryButton]}
|
||||||
|
>
|
||||||
|
<Text style={[styles.primaryButtonText]}>Pay using UPI app</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
<View style={[styles.confirm, { marginBottom: insets.bottom }]}>
|
||||||
|
<Text style={styles.confirmTitle}>
|
||||||
|
Confirm once your payment is completed.
|
||||||
|
</Text>
|
||||||
|
<TouchableOpacity
|
||||||
|
onPress={() => handlePaymentDone()}
|
||||||
|
style={styles.paymentDone}
|
||||||
|
>
|
||||||
|
<Text style={styles.doneText}>Payment Done</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
<TouchableOpacity
|
|
||||||
onPress={payUsingUpiApp}
|
|
||||||
style={[styles.primaryButton, { marginBottom: insets.bottom || 20 }]}
|
|
||||||
>
|
|
||||||
<Text style={[styles.primaryButtonText]}>Pay using UPI app</Text>
|
|
||||||
</TouchableOpacity>
|
|
||||||
</View>
|
</View>
|
||||||
</SafeAreaView>
|
</SafeAreaView>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
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: {
|
container: {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
backgroundColor: "#F3F5F8",
|
backgroundColor: "#F3F5F8",
|
||||||
|
|
@ -288,9 +305,9 @@ const styles = StyleSheet.create({
|
||||||
},
|
},
|
||||||
content: {
|
content: {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
justifyContent: "space-between",
|
|
||||||
paddingHorizontal: 16,
|
paddingHorizontal: 16,
|
||||||
paddingBottom: 16,
|
paddingBottom: 16,
|
||||||
|
justifyContent: "space-between",
|
||||||
},
|
},
|
||||||
qrFrame: {
|
qrFrame: {
|
||||||
backgroundColor: "#FCFCFC",
|
backgroundColor: "#FCFCFC",
|
||||||
|
|
@ -327,19 +344,18 @@ const styles = StyleSheet.create({
|
||||||
color: "#FFFFFF",
|
color: "#FFFFFF",
|
||||||
},
|
},
|
||||||
qrCodeContainer: {
|
qrCodeContainer: {
|
||||||
width: 200,
|
|
||||||
height: 200,
|
|
||||||
justifyContent: "center",
|
|
||||||
alignItems: "center",
|
|
||||||
marginBottom: 16,
|
marginBottom: 16,
|
||||||
borderWidth: 2,
|
borderWidth: 2,
|
||||||
borderColor: "#E5E9F0",
|
borderColor: "#E5E9F0",
|
||||||
padding: 12,
|
padding: 16,
|
||||||
borderRadius: 8,
|
borderRadius: 8,
|
||||||
|
width: "100%",
|
||||||
|
height: "auto",
|
||||||
},
|
},
|
||||||
qrCode: {
|
qrCode: {
|
||||||
width: "100%",
|
width: "100%",
|
||||||
height: "100%",
|
aspectRatio: 1,
|
||||||
|
alignSelf: "center",
|
||||||
},
|
},
|
||||||
upiIdSection: {
|
upiIdSection: {
|
||||||
flexDirection: "row",
|
flexDirection: "row",
|
||||||
|
|
@ -398,6 +414,8 @@ const styles = StyleSheet.create({
|
||||||
paddingVertical: 12,
|
paddingVertical: 12,
|
||||||
paddingHorizontal: 16,
|
paddingHorizontal: 16,
|
||||||
borderRadius: 4,
|
borderRadius: 4,
|
||||||
|
marginTop: 16,
|
||||||
|
width: "100%",
|
||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
},
|
},
|
||||||
primaryButtonText: {
|
primaryButtonText: {
|
||||||
|
|
|
||||||
|
|
@ -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<MyVehicleScreenProps> = ({ navigation }) => {
|
||||||
|
const dispatch = useDispatch<AppDispatch>();
|
||||||
|
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 (
|
||||||
|
<SafeAreaView style={styles.container}>
|
||||||
|
<StatusBar barStyle="dark-content" backgroundColor="#ffffff" />
|
||||||
|
<View style={styles.loadingContainer}>
|
||||||
|
<ActivityIndicator size="large" color="#25324B" />
|
||||||
|
<Text style={styles.loadingText}>Loading vehicle details...</Text>
|
||||||
|
</View>
|
||||||
|
</SafeAreaView>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
return (
|
||||||
|
<SafeAreaView style={styles.container}>
|
||||||
|
<StatusBar barStyle="dark-content" backgroundColor="#ffffff" />
|
||||||
|
<View style={styles.errorContainer}>
|
||||||
|
<Text style={styles.errorText}>Error: {error}</Text>
|
||||||
|
</View>
|
||||||
|
</SafeAreaView>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Header title="My Vehicle" showBackButton={true} />
|
||||||
|
<View style={styles.content}>
|
||||||
|
<View style={styles.itemContainer}>
|
||||||
|
{/* OEM - Model */}
|
||||||
|
<View style={styles.item}>
|
||||||
|
<Text style={styles.label}>OEM - Model</Text>
|
||||||
|
<Text style={styles.value}>
|
||||||
|
{vehicle?.model ? `Yatri - ${vehicle.model}` : "--"}
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<View style={styles.divider} />
|
||||||
|
|
||||||
|
{/* Chassis Number */}
|
||||||
|
<View style={styles.item}>
|
||||||
|
<Text style={styles.label}>Chassis Number</Text>
|
||||||
|
<Text style={styles.value}>{vehicle?.chasis_number || "--"}</Text>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<View style={styles.divider} />
|
||||||
|
|
||||||
|
{/* Vehicle ID */}
|
||||||
|
<View style={styles.item}>
|
||||||
|
<Text style={styles.label}>Vehicle ID</Text>
|
||||||
|
<Text style={styles.value}>
|
||||||
|
{vehicle?.vehicle_id ? vehicle.vehicle_id.toString() : "--"}
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
@ -12,7 +12,7 @@ export default function UserLayout() {
|
||||||
<StatusBar style="dark" />
|
<StatusBar style="dark" />
|
||||||
<Stack
|
<Stack
|
||||||
screenOptions={{
|
screenOptions={{
|
||||||
headerShown: true,
|
headerShown: false,
|
||||||
headerTitleStyle: {
|
headerTitleStyle: {
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
color: "#252A34",
|
color: "#252A34",
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ import { AWS, BASE_URL, USER_PROFILE } from "@/constants/config";
|
||||||
import { bytesToMB, updateUserProfile, uploadImage } from "@/utils/User";
|
import { bytesToMB, updateUserProfile, uploadImage } from "@/utils/User";
|
||||||
import { setUserData } from "@/store/userSlice";
|
import { setUserData } from "@/store/userSlice";
|
||||||
import { Overlay } from "@/components/common/Overlay";
|
import { Overlay } from "@/components/common/Overlay";
|
||||||
|
import Header from "@/components/common/Header";
|
||||||
|
|
||||||
export default function ProfileScreen() {
|
export default function ProfileScreen() {
|
||||||
const [isLangaugeModalVisible, setLanguageModalVisible] =
|
const [isLangaugeModalVisible, setLanguageModalVisible] =
|
||||||
|
|
@ -91,6 +92,7 @@ export default function ProfileScreen() {
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
<Header title="My Account" showBackButton={true} />
|
||||||
<ScrollView contentContainerStyle={styles.scrollContent}>
|
<ScrollView contentContainerStyle={styles.scrollContent}>
|
||||||
<View style={styles.avatarContainer}>
|
<View style={styles.avatarContainer}>
|
||||||
<Image
|
<Image
|
||||||
|
|
@ -134,7 +136,7 @@ export default function ProfileScreen() {
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
<View style={styles.card}>
|
<View style={styles.card}>
|
||||||
{menuItem("My Vehicle")}
|
{menuItem("My Vehicle", () => router.push("/user/MyVechicle"))}
|
||||||
<View style={styles.divider} />
|
<View style={styles.divider} />
|
||||||
{menuItem("Language", () => toggleLanguageModal())}
|
{menuItem("Language", () => toggleLanguageModal())}
|
||||||
</View>
|
</View>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue