Files
CBS-Mobile-App/src/modules/agent/screens/CollectionHistoryScreen.tsx
T

116 lines
4.1 KiB
TypeScript

import React, { useEffect } from 'react';
import { View, StyleSheet, FlatList, RefreshControl, Text } from 'react-native';
import { NativeStackScreenProps } from '@react-navigation/native-stack';
import Animated, { FadeInUp } from 'react-native-reanimated';
import { ScreenShell } from '../../../components';
import { useTheme, fontFamily } from '../../../theme';
import { useAppDispatch, useAppSelector } from '../../../app/hooks';
import type { AgentCollectionsStackParamList } from '../navigation/agentNavigationTypes';
import { useGetCollectionHistoryQuery } from '../services/agentApi';
import { agentActions } from '../store/agentSlice';
import { selectCollectionHistory } from '../store/agentSelectors';
import { CollectionEntryCard } from '../components/CollectionEntryCard';
import { AgentSkeletonLoader } from '../components/AgentSkeletonLoader';
import { AgentEmptyState } from '../components/AgentEmptyState';
import { formatAgentCurrency, formatDate } from '../utils/agentFormatters';
type Props = NativeStackScreenProps<AgentCollectionsStackParamList, 'CollectionHistory'>;
export default function CollectionHistoryScreen({ navigation }: Props) {
const theme = useTheme();
const dispatch = useAppDispatch();
const history = useAppSelector(selectCollectionHistory);
const { data, isLoading, refetch, isFetching } = useGetCollectionHistoryQuery({});
useEffect(() => {
if (data) {
dispatch(agentActions.setCollectionHistory(data));
}
}, [data, dispatch]);
const totalCollected = history.reduce((sum, item) => sum + item.collectedAmount, 0);
return (
<ScreenShell title="Collection History" scrollable={false}>
{/* Summary Header */}
<View style={[styles.summaryHeader, { backgroundColor: theme.colors.surface, borderBottomColor: theme.colors.cardBorder }]}>
<View style={styles.summaryItem}>
<Text style={[styles.summaryLabel, { color: theme.colors.textMuted }]}>Total Entries</Text>
<Text style={[styles.summaryValue, { color: theme.colors.textPrimary }]}>{history.length}</Text>
</View>
<View style={[styles.vDivider, { backgroundColor: theme.colors.cardBorder }]} />
<View style={styles.summaryItem}>
<Text style={[styles.summaryLabel, { color: theme.colors.textMuted }]}>Amount Collected</Text>
<Text style={[styles.summaryValue, { color: theme.colors.primary }]}>{formatAgentCurrency(totalCollected)}</Text>
</View>
</View>
<View style={styles.listArea}>
{isLoading && history.length === 0 ? (
<AgentSkeletonLoader type="list" />
) : (
<FlatList
data={history}
keyExtractor={item => item.id}
contentContainerStyle={styles.listContent}
showsVerticalScrollIndicator={false}
refreshControl={
<RefreshControl refreshing={isFetching} onRefresh={refetch} colors={[theme.colors.primary]} />
}
ListEmptyComponent={() => (
<AgentEmptyState
title="No history found"
description="There are no past collection records."
/>
)}
renderItem={({ item, index }) => (
<Animated.View entering={FadeInUp.delay(index * 50)}>
<CollectionEntryCard
entry={item}
onPress={() => item.status !== 'pending' && item.receiptId ? navigation.navigate('CollectionReceipt', { entryId: item.receiptId }) : null}
/>
</Animated.View>
)}
/>
)}
</View>
</ScreenShell>
);
}
const styles = StyleSheet.create({
summaryHeader: {
flexDirection: 'row',
padding: 16,
borderBottomWidth: 1,
},
summaryItem: {
flex: 1,
},
summaryLabel: {
fontSize: 12,
fontFamily: fontFamily.medium,
marginBottom: 4,
},
summaryValue: {
fontSize: 20,
fontFamily: fontFamily.bold,
},
vDivider: {
width: 1,
height: '100%',
marginHorizontal: 16,
},
listArea: {
flex: 1,
},
listContent: {
padding: 16,
paddingBottom: 40,
},
});