Refactor transaction display in HomeScreen by integrating TransactionList component and removing redundant code for rendering transactions.

This commit is contained in:
2025-09-10 20:49:24 +05:00
parent 4efaf2543e
commit 4630b195b9
2 changed files with 134 additions and 110 deletions

View File

@@ -0,0 +1,132 @@
import React from 'react';
import { View, Text, FlatList, StyleSheet } from 'react-native';
import { Ionicons } from '@expo/vector-icons';
import { COLORS } from '../constants/colors';
const TransactionList = ({ transactions }) => {
if (!transactions || transactions.length === 0) {
return (
<View style={styles.container}>
<Text style={styles.emptyText}>No transactions yet.</Text>
</View>
);
}
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 }) => (
<View style={styles.transactionItem}>
<View style={styles.transactionIcon}>
<Ionicons
name={item.type === 'credit' ? 'arrow-down' : 'arrow-up'}
size={20}
color={item.type === 'credit' ? COLORS.success : COLORS.danger}
/>
</View>
<View style={styles.transactionDetails}>
<Text style={styles.transactionTitle}>{item.description}</Text>
<Text style={styles.transactionDate}>{new Date(item.date).toLocaleTimeString()}</Text>
</View>
<Text
style={[
styles.transactionAmount,
{ color: item.type === 'credit' ? COLORS.success : COLORS.textPrimary },
]}
>
{item.type === 'credit' ? '+' : '-'}
{item.amount} {item.currency}
</Text>
</View>
);
const renderTransactionSection = ({ item: date }) => (
<View>
<Text style={styles.transactionDateHeader}>{date}</Text>
<FlatList
data={groupedTransactions[date]}
renderItem={renderTransactionItem}
keyExtractor={(item) => item.id.toString()}
scrollEnabled={false}
ItemSeparatorComponent={() => <View style={styles.separator} />}
/>
</View>
);
return (
<FlatList
data={Object.keys(groupedTransactions)}
renderItem={renderTransactionSection}
keyExtractor={(date) => date}
scrollEnabled={false}
ItemSeparatorComponent={() => <View style={styles.separator} />}
/>
);
};
const styles = StyleSheet.create({
container: {
padding: 16,
},
emptyText: {
textAlign: 'center',
color: COLORS.textSecondary,
},
transactionItem: {
flexDirection: 'row',
alignItems: 'center',
paddingVertical: 12,
},
transactionIcon: {
width: 44,
height: 44,
borderRadius: 22,
backgroundColor: COLORS.background,
alignItems: 'center',
justifyContent: 'center',
marginRight: 16,
},
transactionDetails: {
flex: 1,
},
transactionTitle: {
fontSize: 16,
fontWeight: '600',
color: COLORS.textPrimary,
marginBottom: 2,
},
transactionDate: {
fontSize: 13,
color: COLORS.textSecondary,
},
transactionAmount: {
fontSize: 16,
fontWeight: '700',
},
transactionDateHeader: {
fontSize: 14,
fontWeight: '600',
color: COLORS.textSecondary,
backgroundColor: COLORS.white,
paddingTop: 16,
paddingBottom: 8,
paddingHorizontal: 4,
},
separator: {
height: 1,
backgroundColor: COLORS.gray[200],
marginLeft: 60,
},
});
export default TransactionList;

View File

@@ -16,6 +16,7 @@ import { useAuth } from '../../contexts/AuthContext';
import { COLORS } from '../../constants/colors';
import MetricCard from '../../components/MetricCard';
import apiService from '../../services/apiService';
import TransactionList from '../../components/TransactionList';
const STATIC_TRANSACTIONS = [
{
@@ -212,57 +213,6 @@ 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 }) => (
<View style={styles.transactionItem}>
<View style={styles.transactionIcon}>
<Ionicons
name={item.type === 'credit' ? 'arrow-down' : 'arrow-up'}
size={20}
color={item.type === 'credit' ? COLORS.success : COLORS.danger}
/>
</View>
<View style={styles.transactionDetails}>
<Text style={styles.transactionTitle}>{item.description}</Text>
<Text style={styles.transactionDate}>{new Date(item.date).toLocaleTimeString()}</Text>
</View>
<Text
style={[
styles.transactionAmount,
{ color: item.type === 'credit' ? COLORS.success : COLORS.textPrimary },
]}
>
{item.type === 'credit' ? '+' : '-'}
{item.amount} {item.currency}
</Text>
</View>
);
const renderTransactionSection = ({ item: date }) => (
<View>
<Text style={styles.transactionDateHeader}>{date}</Text>
<FlatList
data={groupedTransactions[date]}
renderItem={renderTransactionItem}
keyExtractor={(item) => item.id.toString()}
scrollEnabled={false}
ItemSeparatorComponent={() => <View style={styles.separator} />}
/>
</View>
);
return (
<SafeAreaView style={styles.container}>
<StatusBar style="dark" />
@@ -330,17 +280,7 @@ const HomeScreen = () => {
<Text style={styles.seeAllText}>See All</Text>
</TouchableOpacity>
</View>
{transactions.length > 0 ? (
<FlatList
data={Object.keys(groupedTransactions)}
renderItem={renderTransactionSection}
keyExtractor={(date) => date}
scrollEnabled={false}
ItemSeparatorComponent={() => <View style={styles.separator} />}
/>
) : (
<Text style={{ textAlign: 'center', color: COLORS.textSecondary }}>No transactions yet.</Text>
)}
<TransactionList transactions={transactions} />
</View>
)}
</ScrollView>
@@ -472,54 +412,6 @@ const styles = StyleSheet.create({
color: COLORS.textSecondary,
textAlign: 'center',
},
transactionsList: {
marginTop: 16,
},
transactionItem: {
flexDirection: 'row',
alignItems: 'center',
paddingVertical: 12,
},
transactionIcon: {
width: 44,
height: 44,
borderRadius: 22,
backgroundColor: COLORS.background,
alignItems: 'center',
justifyContent: 'center',
marginRight: 16,
},
transactionDetails: {
flex: 1,
},
transactionTitle: {
fontSize: 16,
fontWeight: '600',
color: COLORS.textPrimary,
marginBottom: 2,
},
transactionDate: {
fontSize: 13,
color: COLORS.textSecondary,
},
transactionAmount: {
fontSize: 16,
fontWeight: '700',
},
transactionDateHeader: {
fontSize: 14,
fontWeight: '600',
color: COLORS.textSecondary,
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',
justifyContent: 'space-between',