import { useEffect, useState } from 'react' import { Plus } from 'lucide-react' import { useToast } from '../context/ToastContext' import { BrandModal } from '../components/BrandModal' import { BrandRow } from '../components/BrandRow' import { Breadcrumbs } from '../components/Breadcrumbs' import { PageTitle } from '../components/PageTitle' import { ConfirmDeleteModal } from '../components/ConfirmDeleteModal' import type { Brand, BrandFormData } from '../types/brand' import { ApiError } from '../lib/api' import { resolveDataUrlToMediaId } from '../services/mediaService' import { createBrand, deleteBrand, listAllBrands, mapBrandApiToUi, toBrandFormPayload, updateBrand, } from '../services/brandService' import { useT } from '../i18n/useT' import pageStyles from '../components/PageContent.module.css' import styles from './BrandsPage.module.css' export function BrandsPage() { const t = useT() const { showToast } = useToast() const [brands, setBrands] = useState([]) const [modalOpen, setModalOpen] = useState(false) const [modalTitle, setModalTitle] = useState(() => t('brands.add')) const [editingBrand, setEditingBrand] = useState(null) const [isLoading, setIsLoading] = useState(true) const [isSubmitting, setIsSubmitting] = useState(false) const [error, setError] = useState('') const [deleteTarget, setDeleteTarget] = useState(null) useEffect(() => { const controller = new AbortController() void loadBrands(controller.signal) return () => controller.abort() }, []) async function loadBrands(signal?: AbortSignal) { setIsLoading(true) setError('') try { const items = await listAllBrands(signal) setBrands(items.map(mapBrandApiToUi)) } catch (err) { if (err instanceof DOMException && err.name === 'AbortError') return if (err instanceof ApiError) { setError(err.message) } else { setError(t('brands.errorLoad')) } } finally { setIsLoading(false) } } function openCreateModal() { setEditingBrand(null) setModalTitle(t('brands.add')) setModalOpen(true) } function openEditModal(brand: Brand) { setEditingBrand(brand) setModalTitle(t('brands.edit')) setModalOpen(true) } async function handleSubmit(data: BrandFormData) { setIsSubmitting(true) setError('') try { const resolvedImageMediaId = await resolveDataUrlToMediaId( data.image, 'brand-logo.png', data.imageMediaId, ) if (editingBrand) { const result = await updateBrand(editingBrand.id, { ...toBrandFormPayload(data), imageMediaId: resolvedImageMediaId, }) setBrands((prev) => prev.map((brand) => brand.id === editingBrand.id ? mapBrandApiToUi(result.brand) : brand, ), ) showToast(t('brands.toast.updated'), 'success') } else { const result = await createBrand(toBrandFormPayload(data, resolvedImageMediaId)) setBrands((prev) => [...prev, mapBrandApiToUi(result.brand)]) showToast(t('brands.toast.created'), 'success') } setModalOpen(false) setEditingBrand(null) } catch (err) { if (err instanceof ApiError) { setError(err.message) } else { setError(t('brands.errorSave')) } } finally { setIsSubmitting(false) } } async function confirmDelete() { if (!deleteTarget) return setIsSubmitting(true) setError('') try { await deleteBrand(deleteTarget.id) setBrands((prev) => prev.filter((brand) => brand.id !== deleteTarget.id)) setDeleteTarget(null) showToast(t('brands.toast.deleted'), 'success') } catch (err) { if (err instanceof ApiError) { setError(err.message) } else { setError(t('brands.errorDelete')) } } finally { setIsSubmitting(false) } } return (
{t('title.brands')}

{t('brands.page.subtitle')}

{error && (
{error}
)}
{isLoading ? (

{t('brands.loading')}

) : brands.length === 0 ? (

{t('brands.empty')}

) : ( brands.map((brand) => ( { const item = brands.find((entry) => entry.id === id) if (item) openEditModal(item) }} onRemove={(id) => { const item = brands.find((entry) => entry.id === id) if (item) setDeleteTarget(item) }} /> )) )}
{ if (!isSubmitting) { setModalOpen(false) setEditingBrand(null) } }} onSubmit={handleSubmit} editingBrand={editingBrand} title={modalTitle} isSubmitting={isSubmitting} /> !isSubmitting && setDeleteTarget(null)} />
) }