"use client"; import { useState, useTransition } from "react"; import Link from "next/link"; import { Ruler, Loader2, AlertTriangle, ExternalLink } from "lucide-react"; import { scanUndersizedCovers, type UndersizedCover } from "@/app/actions/maintenance"; import { thumbUrl } from "@/lib/assetUrls"; import { useSettingsPanel } from "./SettingsPanelProvider"; type State = | { kind: "idle" } | { kind: "scanning" } | { kind: "result"; rows: UndersizedCover[] }; function fmtBytes(n: number): string { if (n < 1024) return `${n} B`; if (n < 1024 * 1024) return `${(n / 1024).toFixed(1)} KB`; return `${(n / 1024 / 1024).toFixed(2)} MB`; } export function UndersizedCoversButton() { const [state, setState] = useState({ kind: "idle" }); const [pending, start] = useTransition(); const { close: closeSettings } = useSettingsPanel(); const scan = () => { setState({ kind: "scanning" }); start(async () => { const rows = await scanUndersizedCovers(); setState({ kind: "result", rows }); }); }; return (
Find Undersized Covers
Scan top-level covers smaller than standard JAV size (default floor is 750×500; real covers are usually 800×538). Catches thumbnails or web previews accidentally imported as covers.
{state.kind === "result" && state.rows.length === 0 && (
No undersized covers — all top-level covers meet the size threshold.
)} {state.kind === "result" && state.rows.length > 0 && (
{state.rows.length} undersized cover{state.rows.length === 1 ? "" : "s"} found.
)}
{state.kind === "idle" && ( )} {state.kind === "scanning" && ( Scanning… )} {state.kind === "result" && ( <> )}
{state.kind === "result" && state.rows.length > 0 && (
{state.rows.map((r) => ( {/* eslint-disable-next-line @next/next/no-img-element */}
{r.code ? ( {r.code} ) : ( no code )} {r.width}×{r.height} {fmtBytes(r.bytes)}
{r.filename}
))}
)}
); }