loan order working
This commit is contained in:
145
src/screens/Loan/LoanOrdersScreen.js
Normal file
145
src/screens/Loan/LoanOrdersScreen.js
Normal file
@@ -0,0 +1,145 @@
|
||||
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 passportLine = `Pasport: ${item.passport_serie} ${item.passport_id}`;
|
||||
const amountLine = `Karz mukdary:`;
|
||||
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}>{passportLine}</Text>
|
||||
<Text style={styles.accountLabel}>{amountLine}</Text>
|
||||
<Text style={styles.accountValue}>{item.loan_amount || '-'}</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 },
|
||||
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;
|
||||
Reference in New Issue
Block a user