import React, { useCallback, useEffect, useMemo, useState } from "react"; import { View, Text, StyleSheet, FlatList, RefreshControl, TouchableOpacity, SafeAreaView, } from "react-native"; import { apiCall } from "../../utils/ApiHelper"; import { TRANSACTION } from "../../utils/ApiUrls"; import colors from "../../components/colors"; import AppView from "../../components/AppView"; import Header from "../../components/common/Header"; type Transaction = { id: string; fundGroupId: string; fundGroupName: string; amount: number; status: string; payerMobile?: string; transactionDate: number[]; }; type ApiResponse = { message: string; status: string; statusCode: number; data: Transaction[]; }; // Helper: convert the array-style date into a JS Date const parseTransactionDate = (arr: number[] | undefined): Date | null => { if (!arr || arr.length < 6) return null; const [year, month, day, hour = 0, minute = 0, second = 0, sub = 0] = arr; let milli = 0; if (sub > 999999999) { milli = Math.floor(sub / 1e6); } else if (sub > 1000) { milli = Math.floor(sub / 1e6); } else { milli = sub; } return new Date(year, month - 1, day, hour, minute, second, milli); }; const formatINR = (amount: number) => { try { return new Intl.NumberFormat("en-IN", { style: "currency", currency: "INR" }).format(amount); } catch (e) { return `₹${amount.toFixed(2)}`; } }; const StatusBadge: React.FC<{ status?: string }> = ({ status }) => { const text = status ?? "UNKNOWN"; const color = text === "SUCCESS" ? styles.statusSuccess : text === "PENDING" ? styles.statusPending : styles.statusFailed; return ( {text} ); }; const TransactionItem: React.FC<{ item: Transaction }> = ({ item }) => { const date = useMemo(() => parseTransactionDate(item.transactionDate), [item.transactionDate]); const dateStr = date ? date.toLocaleString("en-IN") : "-"; return ( {item.fundGroupName} Payer: {item.payerMobile ?? "-"} {dateStr} {formatINR(item.amount)} ); }; const TransactionsList: React.FC = () => { const [refreshing, setRefreshing] = useState(false); const [transactions, setTransactions] = useState([]); const [message, setMessage] = useState(""); const handleTransactionList = async () => { try { const res = (await apiCall(TRANSACTION, "GET")) as ApiResponse; console.log("transaction list response : ", res); if (res.statusCode === 200) { setTransactions(res.data); setMessage(res.message); } } catch (error) { console.error("Error fetching transactions:", error); } }; useEffect(() => { handleTransactionList(); }, []); const handleRefresh = useCallback(async () => { try { setRefreshing(true); await handleTransactionList(); } catch (e) { console.warn("Refresh failed", e); } finally { setRefreshing(false); } }, []); const renderEmpty = () => ( No transactions Transactions will appear here when available. ); return (
{message} item.id} renderItem={({ item }) => } ListEmptyComponent={renderEmpty} contentContainerStyle={transactions.length === 0 ? { flex: 1 } : undefined} refreshControl={} /> ); }; export default TransactionsList; const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: "#f7f7fb" }, headerTitle: { fontSize: 18, fontWeight: "500", color: colors.primary }, headerSubtitle: { marginTop: 4, color: "#6b7280" }, card: { flexDirection: "row", justifyContent: "space-between", padding: 16, // marginHorizontal: 12, marginVertical: 8, backgroundColor: "#fff", borderRadius: 12, shadowColor: "#000", shadowOpacity: 0.03, shadowRadius: 8, elevation: 2, }, cardLeft: { flex: 1 }, fundName: { fontSize: 16, fontWeight: "600" }, payer: { marginTop: 6, color: "#6b7280" }, date: { marginTop: 6, color: "#9ca3af" }, cardRight: { alignItems: "flex-end", justifyContent: "space-between" }, amount: { fontSize: 16, fontWeight: "700" }, statusBadge: { marginTop: 8, paddingHorizontal: 8, paddingVertical: 4, borderRadius: 999, }, statusText: { fontSize: 12, fontWeight: "600", color: "#fff" }, statusSuccess: { backgroundColor: "#10b981" }, statusPending: { backgroundColor: "#f59e0b" }, statusFailed: { backgroundColor: "#ef4444" }, emptyContainer: { alignItems: "center", justifyContent: "center", }, emptyTitle: { fontSize: 18, fontWeight: "600", color: "#374151" }, emptySubtitle: { marginTop: 8, color: "#6b7280" }, });