import React, { useState, useEffect } from 'react'; import { useSearchParams } from 'react-router-dom'; import { Brand } from '../types'; import { brandApi } from '../services/api'; import AddBrandModal from './AddBrandModal'; import ConfirmDeleteModal from './ConfirmDeleteModal'; const BrandList: React.FC = () => { const [searchParams, setSearchParams] = useSearchParams(); const [brands, setBrands] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(''); const [isModalOpen, setIsModalOpen] = useState(false); const [editingBrand, setEditingBrand] = useState(null); const [deletingBrand, setDeletingBrand] = useState(null); const [deleteLoading, setDeleteLoading] = useState(false); const [sortField, setSortField] = useState('name'); const [sortDirection, setSortDirection] = useState<'asc' | 'desc'>('asc'); useEffect(() => { fetchBrands(); // Check if we should auto-open the modal if (searchParams.get('add') === 'true') { setIsModalOpen(true); // Remove the parameter from URL setSearchParams({}); } }, [searchParams, setSearchParams]); const fetchBrands = async () => { try { setLoading(true); const response = await brandApi.getAll(); setBrands(response.data); } catch (err) { setError('Failed to fetch brands'); console.error('Error fetching brands:', err); } finally { setLoading(false); } }; const handleBrandAdded = () => { fetchBrands(); // Refresh the brands list }; const handleEditBrand = (brand: Brand) => { setEditingBrand(brand); setIsModalOpen(true); }; const handleDeleteBrand = (brand: Brand) => { setDeletingBrand(brand); }; const confirmDelete = async () => { if (!deletingBrand) return; try { setDeleteLoading(true); await brandApi.delete(deletingBrand.id); setDeletingBrand(null); fetchBrands(); // Refresh the brands list } catch (err: any) { console.error('Error deleting brand:', err); // Handle specific error message from backend if (err.response?.status === 400) { setError('Cannot delete brand: products are still associated with this brand'); } else { setError('Failed to delete brand. Please try again.'); } } finally { setDeleteLoading(false); } }; const handleCloseModal = () => { setIsModalOpen(false); setEditingBrand(null); }; const handleCloseDeleteModal = () => { setDeletingBrand(null); }; const handleSort = (field: keyof Brand) => { if (field === sortField) { setSortDirection(sortDirection === 'asc' ? 'desc' : 'asc'); } else { setSortField(field); setSortDirection('asc'); } }; const sortedBrands = [...brands].sort((a, b) => { let aValue = a[sortField]; let bValue = b[sortField]; // Handle null/undefined values if (aValue === null || aValue === undefined) aValue = ''; if (bValue === null || bValue === undefined) bValue = ''; // Convert to string for comparison const aStr = String(aValue).toLowerCase(); const bStr = String(bValue).toLowerCase(); if (sortDirection === 'asc') { return aStr.localeCompare(bStr); } else { return bStr.localeCompare(aStr); } }); const getSortIcon = (field: keyof Brand) => { if (sortField !== field) { return ( ); } if (sortDirection === 'asc') { return ( ); } else { return ( ); } }; if (loading) { return (
); } return (

Brands

{error && (
{error}
)}
{brands.length === 0 ? (

No brands

Get started by adding your first brand.

) : ( {sortedBrands.map((brand) => ( ))}
handleSort('name')} >
Name {getSortIcon('name')}
handleSort('created_at')} >
Created {getSortIcon('created_at')}
handleSort('updated_at')} >
Updated {getSortIcon('updated_at')}
Actions
{brand.name}
{new Date(brand.created_at).toLocaleDateString()} {brand.updated_at ? new Date(brand.updated_at).toLocaleDateString() : '-'}
)}
); }; export default BrandList;