"use client"; import { Images, Loader2 } from "lucide-react"; import { useEffect, useState } from "react"; import Modal from "@/components/Modal"; import { apiMyMedia, type MediaAttachment } from "@/lib/api"; import { mediaURLFitsSlot, type BrandSlot } from "@/lib/brand"; const SLOT_LABEL: Record = { logo_light: "浅色 Logo", logo_dark: "暗色 Logo", favicon: "Favicon", }; export default function BrandMediaPicker({ open, slot, onClose, onPick, }: { open: boolean; slot: BrandSlot; onClose: () => void; onPick: (item: MediaAttachment) => void; }) { const [items, setItems] = useState([]); const [loading, setLoading] = useState(false); const [error, setError] = useState(""); useEffect(() => { if (!open) return; let cancelled = false; setLoading(true); setError(""); void apiMyMedia() .then((res) => { if (cancelled) return; if (res.error) { setError(res.error); setItems([]); return; } const all = res.attachments || []; setItems(all.filter((item) => mediaURLFitsSlot(slot, item.url))); }) .catch(() => { if (!cancelled) setError("加载媒体库失败"); }) .finally(() => { if (!cancelled) setLoading(false); }); return () => { cancelled = true; }; }, [open, slot]); return ( {loading ? (

加载中

) : error ? (

{error}

) : items.length === 0 ? (

没有可用图片。Logo 需要 PNG / WebP / SVG,Favicon 还可选 ICO。

) : (
{items.map((item) => ( ))}
)}
); }