Add Transaction Details screen

feature/app-setup
vinay kumar 2025-08-15 13:29:42 +05:30
parent 75a3eb87e1
commit 9dd62f9377
3 changed files with 97 additions and 104 deletions

View File

@ -460,6 +460,7 @@ export default function PaymentsTabScreen() {
: paymentHistory.slice(0, 3) : paymentHistory.slice(0, 3)
).map((payment) => ( ).map((payment) => (
<PaymentHistoryCard <PaymentHistoryCard
id={payment.id}
key={payment.id} key={payment.id}
date={formatPaymentDate(payment.payment_date)} date={formatPaymentDate(payment.payment_date)}
amount={formatCurrency(parseFloat(payment.amount))} amount={formatCurrency(parseFloat(payment.amount))}

View File

@ -17,6 +17,7 @@ import { SafeAreaView } from "react-native-safe-area-context";
import SuccessIcon from "@/assets/icons/check_circle.svg"; import SuccessIcon from "@/assets/icons/check_circle.svg";
import FailureIcon from "@/assets/icons/cancel.svg"; import FailureIcon from "@/assets/icons/cancel.svg";
import PendingIcon from "@/assets/icons/pending.svg"; import PendingIcon from "@/assets/icons/pending.svg";
import Header from "@/components/common/Header";
interface TransactionDetailData { interface TransactionDetailData {
id: number; id: number;
@ -56,28 +57,6 @@ export default function TransactionDetailScreen() {
useState<TransactionDetailData | null>(null); useState<TransactionDetailData | null>(null);
const [isLoading, setIsLoading] = useState(true); const [isLoading, setIsLoading] = useState(true);
useLayoutEffect(() => {
navigation.setOptions({
headerStyle: {
backgroundColor: "#F3F5F8",
},
headerTitle: "Transaction Detail",
headerTitleStyle: {
fontSize: 18,
fontWeight: "600",
color: "#111827",
},
headerLeft: () => (
<TouchableOpacity
onPress={() => router.back()}
style={styles.backButton}
>
<Text style={styles.backText}></Text>
</TouchableOpacity>
),
});
}, [navigation, router]);
useEffect(() => { useEffect(() => {
fetchTransactionDetail(); fetchTransactionDetail();
}, [paymentId]); }, [paymentId]);
@ -86,7 +65,7 @@ export default function TransactionDetailScreen() {
try { try {
setIsLoading(true); setIsLoading(true);
const response = await api.get( const response = await api.get(
`${BASE_URL}/api/v1/payment-history?id=${paymentId}` `${BASE_URL}/api/v1/payment-history?page_number=1&page_size=10&id=${paymentId}`
); );
const result: TransactionResponse = response.data; const result: TransactionResponse = response.data;
@ -140,12 +119,9 @@ export default function TransactionDetailScreen() {
const getStatusText = (status: string) => { const getStatusText = (status: string) => {
switch (status.toLowerCase()) { switch (status.toLowerCase()) {
case "success":
case "completed":
case "confirmed": case "confirmed":
return "Payment successful"; return "Payment successful";
case "failure": case "failure":
case "failed":
return "Payment failed"; return "Payment failed";
case "pending": case "pending":
return "Payment pending"; return "Payment pending";
@ -154,86 +130,73 @@ export default function TransactionDetailScreen() {
} }
}; };
if (isLoading) { return (
return ( <>
<SafeAreaView style={styles.container}> <Header title="Transaction Details" showBackButton={true} />
{isLoading ? (
<View style={styles.loadingContainer}> <View style={styles.loadingContainer}>
<ActivityIndicator size="large" color="#00BE88" /> <ActivityIndicator size="large" color="#00BE88" />
</View> </View>
</SafeAreaView> ) : !transactionData ? (
);
}
if (!transactionData) {
return (
<SafeAreaView style={styles.container}>
<View style={styles.errorContainer}> <View style={styles.errorContainer}>
<Text style={styles.errorText}>Transaction not found</Text> <Text style={styles.errorText}>Transaction not found</Text>
</View> </View>
</SafeAreaView> ) : (
); <View style={styles.container}>
} <View style={styles.content}>
<View style={styles.iconContainer}>
{getStatusIcon(transactionData.status)}
</View>
<Text style={styles.amount}>
{formatCurrency(transactionData.amount)}
</Text>
return ( <Text style={styles.statusText}>
<SafeAreaView style={styles.container}> {getStatusText(transactionData.status)}
<View style={styles.content}> </Text>
{/* Status Icon */} <Text style={styles.dateTime}>
<View style={styles.iconContainer}> {formatDateTime(transactionData.transaction_date)}
{getStatusIcon(transactionData.status)} </Text>
<View style={styles.divider} />
<View style={styles.detailsCard}>
<Text style={styles.detailsTitle}>Transaction Details</Text>
<DetailRow
label="Payment mode"
value={transactionData.payment_mode.join(", ") || "--"}
/>
<DetailRow
label="Paid to"
value={transactionData.upi_handle || "--"}
/>
<DetailRow
label="Paid by"
value={transactionData.paid_by_upi_handle || "--"}
/>
<DetailRow
label="Order ID"
value={transactionData.order_id || "--"}
/>
<DetailRow
label="Transaction ID"
value={transactionData.transaction_order_id || "--"}
/>
<DetailRow
label="RRN"
value={transactionData.payment_reference_id || "--"}
isLast={true}
/>
</View>
</View>
</View> </View>
)}
{/* Amount */} </>
<Text style={styles.amount}>
{formatCurrency(transactionData.amount)}
</Text>
{/* Status Text */}
<Text style={styles.statusText}>
{getStatusText(transactionData.status)}
</Text>
{/* Date Time */}
<Text style={styles.dateTime}>
{formatDateTime(transactionData.transaction_date)}
</Text>
{/* Transaction Details Card */}
<View style={styles.detailsCard}>
<Text style={styles.detailsTitle}>Transaction Details</Text>
<DetailRow
label="Payment mode"
value={transactionData.payment_mode.join(", ") || "--"}
/>
<DetailRow
label="Paid to"
value={transactionData.upi_handle || "--"}
/>
<DetailRow
label="Paid by"
value={transactionData.paid_by_upi_handle || "--"}
/>
<DetailRow
label="Order ID"
value={transactionData.order_id || "--"}
/>
<DetailRow
label="Transaction ID"
value={transactionData.transaction_order_id || "--"}
/>
<DetailRow
label="RRN"
value={transactionData.payment_reference_id || "--"}
isLast={true}
/>
</View>
</View>
</SafeAreaView>
); );
} }
@ -253,9 +216,15 @@ const DetailRow = ({
); );
const styles = StyleSheet.create({ const styles = StyleSheet.create({
divider: {
height: 1,
width: "100%",
backgroundColor: "#E5E9F0",
},
container: { container: {
flex: 1, flex: 1,
backgroundColor: "#F3F5F8", backgroundColor: "#F3F5F8",
paddingHorizontal: 16,
}, },
loadingContainer: { loadingContainer: {
flex: 1, flex: 1,
@ -272,9 +241,9 @@ const styles = StyleSheet.create({
color: "#6B7280", color: "#6B7280",
}, },
content: { content: {
flex: 1,
padding: 16, padding: 16,
alignItems: "center", alignItems: "center",
backgroundColor: "#FCFCFC",
}, },
backButton: { backButton: {
paddingLeft: 16, paddingLeft: 16,
@ -351,7 +320,6 @@ const styles = StyleSheet.create({
justifyContent: "space-between", justifyContent: "space-between",
alignItems: "flex-start", alignItems: "flex-start",
paddingVertical: 8, paddingVertical: 8,
borderBottomWidth: 1,
borderBottomColor: "#E5E9F0", borderBottomColor: "#E5E9F0",
}, },
detailRowLast: { detailRowLast: {
@ -367,6 +335,6 @@ const styles = StyleSheet.create({
fontWeight: "600", fontWeight: "600",
color: "#252A34", color: "#252A34",
flex: 1, flex: 1,
textAlign: "right", textAlign: "left",
}, },
}); });

View File

@ -1,4 +1,5 @@
import { Text, View } from "react-native"; import { useRouter } from "expo-router";
import { Text, TouchableOpacity, View } from "react-native";
interface PaymentHistoryCardProps { interface PaymentHistoryCardProps {
date: string; date: string;
@ -6,9 +7,11 @@ interface PaymentHistoryCardProps {
time: string; time: string;
method: string; method: string;
status: string; status: string;
id: number;
} }
export default ({ export default ({
id,
date, date,
amount, amount,
time, time,
@ -16,6 +19,16 @@ export default ({
status, status,
}: PaymentHistoryCardProps) => { }: PaymentHistoryCardProps) => {
//failure, confirmed, pending //failure, confirmed, pending
const router = useRouter();
const handlePress = () => {
router.push({
pathname: "/payments/TransactionDetails",
params: { paymentId: id },
});
};
console.log(status, "payment Status"); console.log(status, "payment Status");
const getStatusStyle = (status: string) => { const getStatusStyle = (status: string) => {
switch (status.toLowerCase()) { switch (status.toLowerCase()) {
@ -45,7 +58,8 @@ export default ({
const statusStyle = getStatusStyle(status); const statusStyle = getStatusStyle(status);
return ( return (
<View style={styles.paymentCard}> // <TouchableOpacity style={styles.paymentCard} onPress={handlePress}>
<TouchableOpacity style={styles.paymentCard} onPress={handlePress}>
<View style={styles.paymentCardTop}> <View style={styles.paymentCardTop}>
<Text style={styles.paymentDate}>{date}</Text> <Text style={styles.paymentDate}>{date}</Text>
<Text style={styles.paymentAmount}>{amount}</Text> <Text style={styles.paymentAmount}>{amount}</Text>
@ -67,7 +81,8 @@ export default ({
</View> </View>
)} )}
</View> </View>
</View> </TouchableOpacity>
// </TouchableOpacity>
); );
}; };
@ -83,6 +98,15 @@ const styles = StyleSheet.create({
paddingHorizontal: 12, paddingHorizontal: 12,
flexDirection: "column", flexDirection: "column",
gap: "12", gap: "12",
shadowColor: "#000",
shadowOffset: {
width: 0,
height: 1,
},
shadowOpacity: 0.05,
shadowRadius: 2,
elevation: 1,
}, },
paymentCardTop: { paymentCardTop: {
height: 20, height: 20,