import React, { useState, useEffect } from 'react'; import { View, Text, StyleSheet, ScrollView, TouchableOpacity, Modal, Alert, Platform } from 'react-native'; import { useAuth } from '../hooks/useAuth'; import { transactionService } from '../services/transactionService'; import { categoryService } from '../services/categoryService'; import { Transaction, Category, TransactionType } from '../types'; import { TransactionCard } from '../components/TransactionCard'; import { InputText } from '../components/InputText'; import { Button } from '../components/Button'; export const TransactionScreen = ({ route, navigation }: any) => { const { user } = useAuth(); const [transactions, setTransactions] = useState([]); const [categories, setCategories] = useState([]); const [modalVisible, setModalVisible] = useState(false); const [loading, setLoading] = useState(false); // Form state const [type, setType] = useState(route?.params?.type || 'expense'); const [amount, setAmount] = useState(''); const [selectedCategory, setSelectedCategory] = useState(''); const [note, setNote] = useState(''); const [date, setDate] = useState(new Date()); useEffect(() => { if (!user) return; // Charger les catégories loadCategories(); // Écouter les transactions const unsubscribe = transactionService.subscribeToTransactions( user.uid, (newTransactions) => { setTransactions(newTransactions); } ); return () => unsubscribe(); }, [user]); // Ouvrir le modal automatiquement si on vient du Dashboard useEffect(() => { if (route?.params?.openModal) { setModalVisible(true); if (route.params.type) { setType(route.params.type); } // Réinitialiser le paramètre navigation.setParams({ openModal: false }); } }, [route?.params]); const loadCategories = async () => { if (!user) return; try { let userCategories = await categoryService.getCategories(user.uid); // Si l'utilisateur n'a pas de catégories, initialiser les catégories par défaut if (userCategories.length === 0) { await categoryService.initializeDefaultCategories(user.uid); userCategories = await categoryService.getCategories(user.uid); } setCategories(userCategories); // Sélectionner la première catégorie du type approprié const defaultCategory = userCategories.find((c) => c.type === type); if (defaultCategory) { setSelectedCategory(defaultCategory.name); } } catch (error) { console.error('Erreur lors du chargement des catégories:', error); } }; const handleAddTransaction = async () => { if (!user) return; if (!amount || parseFloat(amount) <= 0) { Alert.alert('Erreur', 'Veuillez entrer un montant valide'); return; } if (!selectedCategory) { Alert.alert('Erreur', 'Veuillez sélectionner une catégorie'); return; } setLoading(true); try { await transactionService.addTransaction( user.uid, type, parseFloat(amount), selectedCategory, date, note ); // Réinitialiser le formulaire setAmount(''); setSelectedCategory(''); setNote(''); setDate(new Date()); setLoading(false); setModalVisible(false); Alert.alert('Succès', 'Transaction ajoutée avec succès'); } catch (error: any) { setLoading(false); Alert.alert('Erreur', error.message); } }; const filteredCategories = categories.filter((c) => c.type === type); const getCategoryInfo = (categoryName: string) => { const category = categories.find((c) => c.name === categoryName); return category || { icon: '📦', color: '#95A5A6' }; }; return ( Transactions setModalVisible(true)} > + Ajouter {transactions.length === 0 ? ( 💸 Aucune transaction Ajoutez votre première transaction pour commencer ) : ( transactions.map((transaction) => { const categoryInfo = getCategoryInfo(transaction.category); return ( ); }) )} setModalVisible(false)} > Nouvelle transaction setModalVisible(false)}> { setType('expense'); const defaultCategory = filteredCategories.find((c) => c.type === 'expense'); if (defaultCategory) setSelectedCategory(defaultCategory.name); }} > Dépense { setType('income'); const defaultCategory = filteredCategories.find((c) => c.type === 'income'); if (defaultCategory) setSelectedCategory(defaultCategory.name); }} > Revenu { // Permettre uniquement les chiffres et un point décimal const cleaned = text.replace(/[^0-9.]/g, ''); // Empêcher plusieurs points const parts = cleaned.split('.'); if (parts.length > 2) return; // Limiter à 2 décimales if (parts[1] && parts[1].length > 2) return; setAmount(cleaned); }} keyboardType="decimal-pad" /> Catégorie {filteredCategories.map((category) => ( setSelectedCategory(category.name)} > {category.icon} {category.name} ))}