From 4efaf2543e29d7b659ceaf4bbf2c482542129fca Mon Sep 17 00:00:00 2001 From: Nurmuhammet Allanov Date: Wed, 10 Sep 2025 20:34:38 +0500 Subject: [PATCH] Add transaction display feature to HomeScreen --- src/screens/Main/HomeScreen.js | 218 ++++++++++++++++++++++++++++----- 1 file changed, 188 insertions(+), 30 deletions(-) diff --git a/src/screens/Main/HomeScreen.js b/src/screens/Main/HomeScreen.js index 3cc0dd8..8d28ef0 100644 --- a/src/screens/Main/HomeScreen.js +++ b/src/screens/Main/HomeScreen.js @@ -8,6 +8,7 @@ import { TouchableOpacity, ActivityIndicator, RefreshControl, + FlatList, } from 'react-native'; import { StatusBar } from 'expo-status-bar'; import { Ionicons } from '@expo/vector-icons'; @@ -16,6 +17,89 @@ import { COLORS } from '../../constants/colors'; import MetricCard from '../../components/MetricCard'; import apiService from '../../services/apiService'; +const STATIC_TRANSACTIONS = [ + { + id: 1, + type: 'debit', + description: 'Canva Design and Publishing', + date: '2025-09-07T10:30:00Z', + amount: 10.0, + currency: 'EUR', + }, + { + id: 2, + type: 'debit', + description: 'Google', + date: '2025-09-07T11:00:00Z', + amount: 12.99, + currency: 'SAR', + }, + { + id: 3, + type: 'debit', + description: 'Canva Design and Publishing', + date: '2025-09-05T14:15:00Z', + amount: 10.0, + currency: 'EUR', + }, + { + id: 4, + type: 'credit', + description: 'Töleg alyňýan hasap', + date: '2025-09-03T09:00:00Z', + amount: 20.0, + currency: 'USD', + }, + { + id: 5, + type: 'debit', + description: 'Комиссия за оплату', + date: '2025-09-03T09:01:00Z', + amount: 0.12, + currency: 'USD', + }, + { + id: 6, + type: 'credit', + description: 'Hasaby doldurmak', + date: '2025-09-02T18:45:00Z', + amount: 10.0, + currency: 'USD', + }, + { + id: 7, + type: 'debit', + description: 'Canva Design and Publishing', + date: '2025-09-01T12:00:00Z', + amount: 10.0, + currency: 'EUR', + }, + { + id: 8, + type: 'debit', + description: 'Netflix', + date: '2025-08-28T16:00:00Z', + amount: 9.99, + currency: 'USD', + }, + { + id: 9, + type: 'credit', + description: 'Bank Transfer', + date: '2025-08-25T08:20:00Z', + amount: 500.0, + currency: 'TMT', + }, + { + id: 10, + type: 'debit', + description: 'Amazon', + date: '2025-08-23T19:55:00Z', + amount: 45.5, + currency: 'USD', + }, +]; + const HomeScreen = () => { const { user, logout } = useAuth(); const [metrics, setMetrics] = useState(null); @@ -25,6 +109,7 @@ const HomeScreen = () => { const [cardBalanceError, setCardBalanceError] = useState(null); const [isBalanceVisible, setIsBalanceVisible] = useState(true); const [refreshing, setRefreshing] = useState(false); + const [transactions, setTransactions] = useState(STATIC_TRANSACTIONS); const showBalanceCard = !loadingCardBalance && cardBalanceError === null && cardBalance !== null; @@ -50,16 +135,18 @@ const HomeScreen = () => { }, []); useEffect(() => { - const fetchCardBalance = async () => { + const fetchCardData = async () => { // Ensure user has filled all required card & passport fields if (!user?.passport_serie || !user?.passport_id || !user?.card_number || !user?.card_month || !user?.card_year) { setLoadingCardBalance(false); return; } + + setLoadingCardBalance(true); + try { const res = await apiService.getCardBalanceQuickCheck(); if (res.success) { - // Try common balance keys else fallback to raw const raw = res.data; let balanceValue = null; if (raw && typeof raw === 'object') { @@ -73,12 +160,13 @@ const HomeScreen = () => { } } catch (e) { console.warn('Error fetching card balance:', e); + setCardBalanceError('Error fetching balance'); } finally { setLoadingCardBalance(false); } }; - fetchCardBalance(); + fetchCardData(); }, [user]); const handleRefresh = async () => { @@ -124,6 +212,57 @@ const HomeScreen = () => { setRefreshing(false); }; + const groupedTransactions = transactions.reduce((acc, transaction) => { + const date = new Date(transaction.date).toLocaleDateString('en-US', { + year: 'numeric', + month: 'long', + day: 'numeric', + }); + if (!acc[date]) { + acc[date] = []; + } + acc[date].push(transaction); + return acc; + }, {}); + + const renderTransactionItem = ({ item }) => ( + + + + + + {item.description} + {new Date(item.date).toLocaleTimeString()} + + + {item.type === 'credit' ? '+' : '-'} + {item.amount} {item.currency} + + + ); + + const renderTransactionSection = ({ item: date }) => ( + + {date} + item.id.toString()} + scrollEnabled={false} + ItemSeparatorComponent={() => } + /> + + ); + return ( @@ -149,7 +288,7 @@ const HomeScreen = () => { {/* Metrics */} - Metrics + Görkezijiler {loadingMetrics ? ( ) : ( @@ -181,6 +320,29 @@ const HomeScreen = () => { )} + + {/* Card Transactions */} + {showBalanceCard && ( + + + Transactions + + See All + + + {transactions.length > 0 ? ( + date} + scrollEnabled={false} + ItemSeparatorComponent={() => } + /> + ) : ( + No transactions yet. + )} + + )} ); @@ -311,20 +473,21 @@ const styles = StyleSheet.create({ textAlign: 'center', }, transactionsList: { - gap: 16, + marginTop: 16, }, transactionItem: { flexDirection: 'row', alignItems: 'center', + paddingVertical: 12, }, transactionIcon: { - width: 40, - height: 40, - borderRadius: 20, - backgroundColor: COLORS.backgroundSecondary, + width: 44, + height: 44, + borderRadius: 22, + backgroundColor: COLORS.background, alignItems: 'center', justifyContent: 'center', - marginRight: 12, + marginRight: 16, }, transactionDetails: { flex: 1, @@ -333,34 +496,29 @@ const styles = StyleSheet.create({ fontSize: 16, fontWeight: '600', color: COLORS.textPrimary, + marginBottom: 2, }, transactionDate: { - fontSize: 14, + fontSize: 13, color: COLORS.textSecondary, }, transactionAmount: { fontSize: 16, - fontWeight: 'bold', - color: COLORS.success, + fontWeight: '700', }, - servicesGrid: { - flexDirection: 'row', - flexWrap: 'wrap', - justifyContent: 'space-between', - }, - serviceItem: { - width: '48%', - padding: 16, - backgroundColor: COLORS.backgroundSecondary, - borderRadius: 12, - alignItems: 'center', - marginBottom: 12, - }, - serviceText: { - fontSize: 12, + transactionDateHeader: { + fontSize: 14, + fontWeight: '600', color: COLORS.textSecondary, - textAlign: 'center', - marginTop: 8, + backgroundColor: COLORS.white, + paddingTop: 16, + paddingBottom: 8, + paddingHorizontal: 4, + }, + separator: { + height: 1, + backgroundColor: COLORS.gray[200], + marginLeft: 60, // Align with transaction details, skipping the icon }, metricsGrid: { flexDirection: 'row',