All files / src/hooks useInvoices.ts

100% Statements 36/36
100% Branches 12/12
100% Functions 5/5
100% Lines 33/33

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 }
}