|
1 | | -import { View, Text, StyleSheet } from 'react-native'; |
| 1 | +import { useEffect, useState, useCallback } from 'react'; |
| 2 | +import { |
| 3 | + View, Text, FlatList, StyleSheet, |
| 4 | + ActivityIndicator, Modal, TouchableOpacity, Alert, |
| 5 | +} from 'react-native'; |
| 6 | +import AsyncStorage from '@react-native-async-storage/async-storage'; |
| 7 | +import axios from 'axios'; |
| 8 | +import { BASE_URL, EMPRESTIMOS } from '@constants/endpoints'; |
| 9 | +import { useAuth } from '@hooks/useAuth'; |
| 10 | +import { Emprestimo } from 'emprestimo'; |
| 11 | +import { EmprestimoListItem } from '@components/emprestimos/EmprestimoListItem'; |
| 12 | +import { EmprestimoCard } from '@components/emprestimos/EmprestimoCard'; |
| 13 | + |
| 14 | +const TOKEN_KEY = '@pagaai:token'; |
| 15 | + |
| 16 | +async function req(method: 'get' | 'patch' | 'delete', path: string) { |
| 17 | + const token = await AsyncStorage.getItem(TOKEN_KEY); |
| 18 | + return axios({ method, url: `${BASE_URL}${path}`, headers: { Authorization: `Bearer ${token}` } }); |
| 19 | +} |
2 | 20 |
|
3 | 21 | export default function EmprestimosScreen() { |
| 22 | + const { user } = useAuth(); |
| 23 | + const cobrador = user?.nome ?? ''; |
| 24 | + |
| 25 | + const [lista, setLista] = useState<Emprestimo[]>([]); |
| 26 | + const [carregando, setCarregando] = useState(true); |
| 27 | + const [selecionado, setSelecionado] = useState<Emprestimo | null>(null); |
| 28 | + |
| 29 | + const carregar = useCallback(async () => { |
| 30 | + if (!cobrador) return; |
| 31 | + setCarregando(true); |
| 32 | + try { |
| 33 | + const url = `${EMPRESTIMOS}/carteira/${encodeURIComponent(cobrador)}`; |
| 34 | + console.log('[Emprestimos] chamando:', url); |
| 35 | + const res = await req('get', url); |
| 36 | + console.log('[Emprestimos] total:', res.data?.length); |
| 37 | + setLista(Array.isArray(res.data) ? res.data : []); |
| 38 | + } catch (e: any) { |
| 39 | + console.error('[Emprestimos] erro:', e?.response?.status, e?.response?.data ?? e?.message); |
| 40 | + } finally { |
| 41 | + setCarregando(false); |
| 42 | + } |
| 43 | + }, [cobrador]); |
| 44 | + |
| 45 | + useEffect(() => { carregar(); }, [carregar]); |
| 46 | + |
| 47 | + async function marcarPago(id: number) { |
| 48 | + Alert.alert('Confirmar', 'Marcar como recebido?', [ |
| 49 | + { text: 'Cancelar', style: 'cancel' }, |
| 50 | + { |
| 51 | + text: 'Confirmar', onPress: async () => { |
| 52 | + try { |
| 53 | + await req('patch', `${EMPRESTIMOS}/${id}/pagar/${encodeURIComponent(cobrador)}`); |
| 54 | + setSelecionado(null); |
| 55 | + carregar(); |
| 56 | + } catch { Alert.alert('Erro', 'Não foi possível marcar como pago.'); } |
| 57 | + }, |
| 58 | + }, |
| 59 | + ]); |
| 60 | + } |
| 61 | + |
| 62 | + async function deletar(id: number) { |
| 63 | + Alert.alert('Excluir', 'Deseja excluir este empréstimo?', [ |
| 64 | + { text: 'Cancelar', style: 'cancel' }, |
| 65 | + { |
| 66 | + text: 'Excluir', style: 'destructive', onPress: async () => { |
| 67 | + try { |
| 68 | + await req('delete', `${EMPRESTIMOS}/${id}/${encodeURIComponent(cobrador)}`); |
| 69 | + setSelecionado(null); |
| 70 | + carregar(); |
| 71 | + } catch { Alert.alert('Erro', 'Não foi possível excluir.'); } |
| 72 | + }, |
| 73 | + }, |
| 74 | + ]); |
| 75 | + } |
| 76 | + |
| 77 | + if (carregando) { |
| 78 | + return <View style={s.center}><ActivityIndicator size="large" color="#7C3AED" /></View>; |
| 79 | + } |
| 80 | + |
4 | 81 | return ( |
5 | | - <View style={s.container}> |
6 | | - <Text style={s.icon}>💳</Text> |
7 | | - <Text style={s.titulo}>Empréstimos</Text> |
8 | | - <Text style={s.sub}>Tela em desenvolvimento</Text> |
| 82 | + <View style={s.page}> |
| 83 | + <View style={s.header}> |
| 84 | + <Text style={s.titulo}>Empréstimos</Text> |
| 85 | + <Text style={s.sub}>{lista.length} registro{lista.length !== 1 ? 's' : ''}</Text> |
| 86 | + </View> |
| 87 | + |
| 88 | + {lista.length === 0 ? ( |
| 89 | + <View style={s.center}> |
| 90 | + <Text style={s.vazio}>Nenhum empréstimo encontrado.</Text> |
| 91 | + </View> |
| 92 | + ) : ( |
| 93 | + <FlatList |
| 94 | + data={lista} |
| 95 | + keyExtractor={(e) => String(e.id)} |
| 96 | + renderItem={({ item }) => ( |
| 97 | + <EmprestimoListItem |
| 98 | + emprestimo={item} |
| 99 | + onPress={(id) => setSelecionado(lista.find((e) => e.id === id) ?? null)} |
| 100 | + /> |
| 101 | + )} |
| 102 | + contentContainerStyle={{ paddingBottom: 32 }} |
| 103 | + /> |
| 104 | + )} |
| 105 | + |
| 106 | + <Modal visible={!!selecionado} animationType="slide" onRequestClose={() => setSelecionado(null)}> |
| 107 | + <View style={s.modalPage}> |
| 108 | + <TouchableOpacity style={s.fechar} onPress={() => setSelecionado(null)}> |
| 109 | + <Text style={s.fecharText}>← Voltar</Text> |
| 110 | + </TouchableOpacity> |
| 111 | + {selecionado && ( |
| 112 | + <EmprestimoCard |
| 113 | + emprestimo={selecionado} |
| 114 | + onPagar={marcarPago} |
| 115 | + onDeletar={deletar} |
| 116 | + /> |
| 117 | + )} |
| 118 | + </View> |
| 119 | + </Modal> |
9 | 120 | </View> |
10 | 121 | ); |
11 | 122 | } |
12 | 123 |
|
13 | 124 | const s = StyleSheet.create({ |
14 | | - container: { flex: 1, alignItems: 'center', justifyContent: 'center', backgroundColor: '#F5F3FF' }, |
15 | | - icon: { fontSize: 48, marginBottom: 12 }, |
16 | | - titulo: { fontSize: 22, fontWeight: '700', color: '#1F2937' }, |
17 | | - sub: { fontSize: 14, color: '#6B7280', marginTop: 6 }, |
| 125 | + page: { flex: 1, backgroundColor: '#F5F3FF' }, |
| 126 | + center: { flex: 1, alignItems: 'center', justifyContent: 'center' }, |
| 127 | + header: { padding: 20, paddingBottom: 12 }, |
| 128 | + titulo: { fontSize: 28, fontWeight: '700', color: '#1F2937' }, |
| 129 | + sub: { fontSize: 13, color: '#6B7280', marginTop: 2 }, |
| 130 | + vazio: { fontSize: 15, color: '#9CA3AF' }, |
| 131 | + modalPage: { flex: 1, backgroundColor: '#F5F3FF', padding: 16 }, |
| 132 | + fechar: { paddingVertical: 12, marginBottom: 8 }, |
| 133 | + fecharText: { fontSize: 15, color: '#7C3AED', fontWeight: '600' }, |
18 | 134 | }); |
0 commit comments