Files
tbbank-react-native-mobile/src/screens/Loan/LoanOrdersScreen.js

147 lines
4.7 KiB
JavaScript

import React, { useState, useCallback } from 'react';
import { View, Text, StyleSheet, FlatList, ActivityIndicator, TouchableOpacity, RefreshControl, SafeAreaView } from 'react-native';
import { Ionicons } from '@expo/vector-icons';
import { useNavigation, useFocusEffect } from '@react-navigation/native';
import apiService from '../../services/apiService';
import { COLORS } from '../../constants/colors';
import { StatusBar } from 'expo-status-bar';
const CARD_BG = '#F1F9F1';
const CIRCLE_BG = '#A2E4A4';
const LoanOrdersScreen = () => {
const navigation = useNavigation();
const [orders, setOrders] = useState([]);
const [loading, setLoading] = useState(true);
const [refreshing, setRefreshing] = useState(false);
const fetchOrders = async () => {
try {
const res = await apiService.getLoanOrders();
if (res.success) {
setOrders(Array.isArray(res.data) ? res.data : []);
} else {
console.warn(res.error);
}
} catch (e) {
console.warn(e.message);
} finally {
setLoading(false);
setRefreshing(false);
}
};
useFocusEffect(
useCallback(() => {
fetchOrders();
}, [])
);
const onRefresh = () => {
setRefreshing(true);
fetchOrders();
};
const renderItem = ({ item }) => {
const amountLine = `Karz mukdary: `;
const amount = (item.loan_amount + ' TMT') || '-';
const created = item.created_at ? new Date(item.created_at).toLocaleDateString() : '';
return (
<TouchableOpacity style={styles.card} onPress={() => navigation.navigate('LoanOrderDetails', { orderId: item.id })}>
<View style={styles.circle}>
<Text style={styles.circleText}>{item.id}</Text>
</View>
<View style={styles.cardContent}>
<Text style={styles.passportText}>{item.loan_type}</Text>
<Text style={styles.accountLabel}>{amountLine}
<Text style={{ color: COLORS.textPrimary }}>{amount}</Text>
</Text>
<Text style={styles.dateText}>{created}</Text>
</View>
</TouchableOpacity>
);
};
if (loading) {
return (
<View style={styles.centered}>
<ActivityIndicator size="large" color={COLORS.primary} />
</View>
);
}
return (
<SafeAreaView style={styles.container}>
<StatusBar style="dark" />
{/* Header */}
<View style={styles.header}>
<TouchableOpacity onPress={() => navigation.goBack()} style={{ paddingRight: 12 }}>
<Ionicons name="arrow-back" size={24} color={COLORS.textPrimary} />
</TouchableOpacity>
<Text style={styles.headerTitle}>Karz sargytlar</Text>
</View>
<FlatList
data={orders}
keyExtractor={(it) => it.id?.toString()}
renderItem={renderItem}
contentContainerStyle={orders.length === 0 && styles.emptyContainer}
refreshControl={<RefreshControl refreshing={refreshing} onRefresh={onRefresh} />}
ListEmptyComponent={<Text style={styles.emptyText}>No orders yet</Text>}
/>
<TouchableOpacity style={styles.fab} onPress={() => navigation.navigate('CreateLoanOrder')}>
<Ionicons name="add" size={28} color={COLORS.white} />
</TouchableOpacity>
</SafeAreaView>
);
};
const styles = StyleSheet.create({
container: { flex: 1, backgroundColor: COLORS.backgroundSecondary },
centered: { flex: 1, alignItems: 'center', justifyContent: 'center' },
header: { flexDirection: 'row', alignItems: 'center', padding: 16 },
headerTitle: { fontSize: 18, fontWeight: 'bold', color: COLORS.textPrimary, marginLeft: 12 },
card: {
flexDirection: 'row',
backgroundColor: CARD_BG,
marginHorizontal: 24,
marginTop: 16,
borderRadius: 12,
padding: 16,
alignItems: 'center',
},
circle: {
width: 40,
height: 40,
borderRadius: 20,
backgroundColor: CIRCLE_BG,
alignItems: 'center',
justifyContent: 'center',
marginRight: 16,
},
circleText: { color: COLORS.white, fontWeight: '600' },
cardContent: { flex: 1 },
passportText: { fontWeight: '700', color: COLORS.textPrimary, marginBottom: 4 },
accountLabel: { color: COLORS.textSecondary, fontSize: 14 },
accountValue: { color: COLORS.textPrimary, marginBottom: 4 },
dateText: { color: COLORS.textSecondary, fontSize: 12, textAlign: 'right' },
emptyContainer: { flex: 1, justifyContent: 'center', alignItems: 'center' },
emptyText: { fontSize: 16, color: COLORS.textSecondary },
fab: {
position: 'absolute',
right: 24,
bottom: 40,
width: 56,
height: 56,
borderRadius: 28,
backgroundColor: COLORS.primary,
alignItems: 'center',
justifyContent: 'center',
elevation: 4,
},
});
export default LoanOrdersScreen;