"use client"; import { useState, useEffect, useCallback } from "react"; import { useRouter } from "next/navigation"; import { ArrowLeft, Trash2, Copy, Check, Image as ImageIcon } from "lucide-react"; const HUGO_SITE = "https://usj.cc"; interface ImageFile { name: string; path: string; folder: string; size: number; url: string; localUrl: string; } export default function ImagesPage() { const router = useRouter(); const [images, setImages] = useState([]); const [loading, setLoading] = useState(true); const [copied, setCopied] = useState(null); const [message, setMessage] = useState<{ type: "success" | "error"; text: string } | null>(null); const fetchImages = useCallback(async () => { setLoading(true); try { const res = await fetch("/api/images"); setImages((await res.json()).images || []); } catch {} finally { setLoading(false); } }, []); useEffect(() => { fetchImages(); }, [fetchImages]); const copyMarkdown = (img: ImageFile) => { const md = `![](./${img.name})`; navigator.clipboard.writeText(md).then(() => { setCopied(img.name); setTimeout(() => setCopied(null), 2000); }).catch(() => {}); }; const handleDelete = async (img: ImageFile) => { if (!confirm(`确定删除「${img.name}」?此操作不可撤销。`)) return; try { const res = await fetch(`/api/images?path=${encodeURIComponent(img.path)}`, { method: "DELETE" }); if (!res.ok) throw new Error("删除失败"); setImages((prev) => prev.filter((x) => x.path !== img.path)); } catch (err: unknown) { setMessage({ type: "error", text: err instanceof Error ? err.message : "删除失败" }); } }; const formatSize = (bytes: number) => { if (bytes < 1024) return `${bytes}B`; if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)}KB`; return `${(bytes / (1024 * 1024)).toFixed(1)}MB`; }; return (

图片管理

{images.length} 张
{message && (
{message.text}
)} {loading ? (
加载中...
) : images.length === 0 ? (

暂无图片

) : (
{images.map((img) => (
{img.name} { (e.target as HTMLImageElement).style.display = "none"; }} />
{img.name}
{formatSize(img.size)} {img.folder || "根目录"}
))}
)}
); }