import { Download, Loader2 } from "lucide-react"; import { useState } from "react"; import { useFileStore } from "@/stores/file-store"; function getToken(): string { return localStorage.getItem("stirling-token") || ""; } export function BulkRenameSettings() { const { files, processing, error, setProcessing, setError } = useFileStore(); const [pattern, setPattern] = useState("image-{{index}}"); const [startIndex, setStartIndex] = useState(1); const [downloadReady, setDownloadReady] = useState(false); const handleProcess = async () => { if (files.length === 0) return; setProcessing(true); setError(null); setDownloadReady(false); try { const formData = new FormData(); for (const file of files) { formData.append("file", file); } formData.append("settings", JSON.stringify({ pattern, startIndex })); const res = await fetch("/api/v1/tools/bulk-rename", { method: "POST", headers: { Authorization: `Bearer ${getToken()}` }, body: formData, }); if (!res.ok) { const text = await res.text(); throw new Error(text || `Failed: ${res.status}`); } const blob = await res.blob(); const url = URL.createObjectURL(blob); const a = document.createElement("a"); a.href = url; a.download = "renamed.zip"; a.click(); URL.revokeObjectURL(url); setDownloadReady(true); } catch (err) { setError(err instanceof Error ? err.message : "Rename failed"); } finally { setProcessing(false); } }; const hasFiles = files.length > 0; // Preview names const previewNames = hasFiles ? files.slice(0, 5).map((f, i) => { const ext = f.name.includes(".") ? f.name.slice(f.name.lastIndexOf(".")) : ""; const idx = startIndex + i; const padded = String(idx).padStart(String(files.length + startIndex).length, "0"); return ( pattern .replace(/\{\{index\}\}/g, String(idx)) .replace(/\{\{padded\}\}/g, padded) .replace(/\{\{original\}\}/g, f.name.replace(ext, "")) + ext ); }) : []; return (
setPattern(e.target.value)} className="w-full mt-0.5 px-2 py-1.5 rounded border border-border bg-background text-sm text-foreground" />

Variables: {"{{index}}"}, {"{{padded}}"}, {"{{original}}"}

setStartIndex(Number(e.target.value))} min={0} className="w-full mt-0.5 px-2 py-1.5 rounded border border-border bg-background text-sm text-foreground" />
{previewNames.length > 0 && (

Preview

{previewNames.map((name) => (
{name}
))} {files.length > 5 && (

... and {files.length - 5} more

)}
)} {error &&

{error}

} {downloadReady && (

ZIP downloaded successfully

)}
); }