All files / src/hooks useProducts.ts

100% Statements 27/27
100% Branches 16/16
100% Functions 5/5
100% Lines 27/27

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 73 74 75 76                                    29x 29x 29x 29x 29x   29x 10x 10x 10x     10x           10x   10x                       10x   4x 4x     5x 4x 4x 1x 1x   3x 2x 2x 2x     2x   9x     29x    
import { useState, useEffect } from 'react';
import axios from 'axios';
import type { Product } from '../types/products';
import { API_BASE_URL } from '../config';
 
export interface Filters {
  name: string;
  category: string;
  location: string;
  date: string;
  places: number;
  sortBy: 'name' | 'price' | 'date';
  order: 'asc' | 'desc';
  perPage: number;
  page: number;
}
 
export function useProducts(filters: Filters, lang: string) {
  const [products, setProducts] = useState<Product[]>([]);
  const [total, setTotal] = useState(0);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string|null>(null);
  const [validationErrors, setValidationErrors] = useState<Record<string,string[]> | null>(null);
 
  useEffect(() => {
    setLoading(true);
    setError(null);
    setValidationErrors(null);
 
    // Mapping interne entre notre enum "sortBy" et la clé API
    const sortMap: Record<Filters['sortBy'], string> = {
      name:  'name',
      price: 'price',
      date:  'product_details->date',
    };
 
    const apiSort = sortMap[filters.sortBy];
 
    const params: Record<string, any> = {
      per_page: Math.max(1, filters.perPage),
      page: filters.page,
      sort_by: apiSort,
      order: filters.order,
      ...(filters.name     && { name:     filters.name     }),
      ...(filters.category && { category: filters.category }),
      ...(filters.location && { location: filters.location }),
      ...(filters.date     && { date:     filters.date     }),
      ...(filters.places > 0 && { places: filters.places }),
    };
 
    axios.get(`${API_BASE_URL}/api/products`, { params, headers: { 'Accept-Language': lang } })
      .then(res => {
        setProducts(res.data.data);
        setTotal(res.data.pagination.total);
      })
      .catch(err => {
        if (axios.isAxiosError(err)) {
          const status = err.response?.status;
          if (status === 422) {
          setValidationErrors(err.response!.data.errors as Record<string,string[]>);
          return;
        }
        if (status === 404) {
          setProducts([]);
          setTotal(0);
          return;
        }
      }
      setError(err.code);
    })
    .finally(() => setLoading(false));
  }, [filters, lang]);
 
  return { products, total, loading, error, validationErrors };
}