import { useEffect, useMemo, useState } from "react"; import { api, ApiError } from "../api"; import type { Brand } from "../types"; import { Tag, Pencil, Plus, Trash2, GitMerge, Search } from "lucide-react"; type EditState = { id: string; name: string }; type MergeState = { source: Brand; targetId: string }; export default function BrandsPage() { const [rows, setRows] = useState([]); const [error, setError] = useState(""); const [query, setQuery] = useState(""); const [creating, setCreating] = useState(false); const [newName, setNewName] = useState(""); const [edit, setEdit] = useState(null); const [merge, setMerge] = useState(null); const [busy, setBusy] = useState(false); async function load() { setError(""); try { const res = await api.listBrands(); setRows(res.items); } catch (e) { setError(e instanceof ApiError ? e.message : "加载失败"); } } useEffect(() => { load(); }, []); const filtered = useMemo(() => { const q = query.trim().toLowerCase(); if (!q) return rows; return rows.filter((b) => b.name.toLowerCase().includes(q)); }, [rows, query]); function fail(e: unknown, fallback: string) { setError(e instanceof ApiError ? e.message : fallback); } async function create() { if (!newName.trim()) return; setBusy(true); setError(""); try { await api.createBrand(newName.trim()); setNewName(""); setCreating(false); await load(); } catch (e) { fail(e, "新建失败"); } finally { setBusy(false); } } async function saveEdit() { if (!edit || !edit.name.trim()) return; setBusy(true); setError(""); try { await api.updateBrand(edit.id, edit.name.trim()); setEdit(null); await load(); } catch (e) { fail(e, "保存失败"); } finally { setBusy(false); } } async function remove(b: Brand) { if (!confirm(`确认删除品牌「${b.name}」?`)) return; setError(""); try { await api.deleteBrand(b.id); await load(); } catch (e) { fail(e, "删除失败"); } } async function doMerge() { if (!merge || !merge.targetId) return; const target = rows.find((b) => b.id === merge.targetId); if ( !confirm( `将「${merge.source.name}」的 ${merge.source.product_count} 个商品并入「${target?.name}」,并删除「${merge.source.name}」?`, ) ) return; setBusy(true); setError(""); try { await api.mergeBrands(merge.source.id, merge.targetId); setMerge(null); await load(); } catch (e) { fail(e, "合并失败"); } finally { setBusy(false); } } return (

品牌管理

维护品牌名录。可重命名、删除未被引用的品牌,或将重复品牌合并到一起。

{error && (
{error}
)}
setQuery(e.target.value)} placeholder="筛选品牌名" className="w-full rounded border border-gray-300 py-2 pl-8 pr-3 text-sm focus:border-emerald-500 focus:outline-none" />
{creating && (

新建品牌

)} {merge && (

合并品牌

把「{merge.source.name}」({merge.source.product_count} 个商品)合并到下面选择的品牌,源品牌将被删除。

)}
{filtered.length === 0 ? ( ) : ( filtered.map((b) => ( )) )}
品牌 商品数
{rows.length === 0 ? "暂无品牌" : "无匹配品牌"}
{edit && edit.id === b.id ? ( setEdit({ ...edit, name: e.target.value })} onKeyDown={(e) => { if (e.key === "Enter") saveEdit(); if (e.key === "Escape") setEdit(null); }} /> ) : ( {b.name} )} {b.product_count} {edit && edit.id === b.id ? ( <> ) : ( <> )}
); }