Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | 18x 18x 18x 18x 18x 18x 18x 7x 7x 7x 7x 7x 7x 1x 1x 1x 1x 1x 6x 6x 2x 1x 1x 4x 3x 1x 2x 6x 4x 7x 7x 2x 18x | import { useState, useEffect } from 'react' import type { Invoice, InvoiceApiResponse, InvoiceFilters } from '../types/invoices' import { getInvoices } from '../services/billingService' import { useAuthStore } from '../stores/useAuthStore' export function useInvoices(filters: InvoiceFilters, lang: string) { const token = useAuthStore(s => s.authToken) const [invoices, setInvoices] = useState<Invoice[]>([]) const [total, setTotal] = useState(0) const [loading, setLoading] = useState(false) const [error, setError] = useState<Error | null>(null) const [validationErrors, setValidationErrors] = useState<any>(null) useEffect(() => { let cancelled = false const fetchInvoices = async () => { // On réinitialise les états d’erreur avant la requête setLoading(true) setError(null) setValidationErrors(null) if (!token) { // Pas de token = pas authentifié setError(new Error('User not authenticated')) setInvoices([]) setTotal(0) setLoading(false) return } try { // Si tu veux passer lang comme header Accept-Language, tu peux surcharger getInvoices const resp: InvoiceApiResponse = await getInvoices(filters, token) if (cancelled) return // resp.data est InvoiceResponse // InvoiceResponse.data est Invoice[] setInvoices(resp.data.data) setTotal(resp.data.meta.total) } catch (err: any) { if (cancelled) return // Si c'est une erreur de validation 422 if (err.response?.status === 422) { setValidationErrors(err.response.data.errors) } else { setError(err instanceof Error ? err : new Error('Unknown error')) } } finally { if (!cancelled) { setLoading(false) } } } fetchInvoices() return () => { // À la destruction ou avant un nouveau fetch, on marque annulé cancelled = true } // Dépendances : // - JSON.stringify(filters) si tu veux comparer le contenu. // Attention : ça peut déclencher souvent si l'ordre des clés change ou si filters est reconstruit à chaque render. // Si filters vient d'un state/setState et que tu changes uniquement par setFilters, // tu peux directement utiliser [filters, token, lang]. }, [JSON.stringify(filters), token, lang]) return { invoices, total, loading, error, validationErrors } } |