import { Download, Loader2 } from "lucide-react"; import { useState } from "react"; import { useFileStore } from "@/stores/file-store"; function getToken(): string { return localStorage.getItem("stirling-token") || ""; } type Layout = "2x2" | "3x3" | "1x3" | "2x1" | "3x1" | "1x2"; const LAYOUTS: { value: Layout; label: string }[] = [ { value: "2x2", label: "2 x 2" }, { value: "3x3", label: "3 x 3" }, { value: "1x3", label: "1 x 3" }, { value: "3x1", label: "3 x 1" }, { value: "2x1", label: "2 x 1" }, { value: "1x2", label: "1 x 2" }, ]; export function CollageSettings() { const { files, processing, error, setProcessing, setError, setProcessedUrl, setSizes, setJobId } = useFileStore(); const [layout, setLayout] = useState("2x2"); const [gap, setGap] = useState(4); const [backgroundColor, setBackgroundColor] = useState("#FFFFFF"); const [downloadUrl, setDownloadUrl] = useState(null); const [originalSize, setOriginalSize] = useState(null); const [processedSize, setProcessedSize] = useState(null); const handleProcess = async () => { if (files.length === 0) return; setProcessing(true); setError(null); setDownloadUrl(null); try { const formData = new FormData(); for (const file of files) { formData.append("file", file); } formData.append("settings", JSON.stringify({ layout, gap, backgroundColor })); const res = await fetch("/api/v1/tools/collage", { method: "POST", headers: { Authorization: `Bearer ${getToken()}` }, body: formData, }); if (!res.ok) { const body = await res.json().catch(() => ({})); throw new Error(body.error || `Failed: ${res.status}`); } const result = await res.json(); setJobId(result.jobId); setProcessedUrl(result.downloadUrl); setDownloadUrl(result.downloadUrl); setOriginalSize(result.originalSize); setProcessedSize(result.processedSize); setSizes(result.originalSize, result.processedSize); } catch (err) { setError(err instanceof Error ? err.message : "Collage failed"); } finally { setProcessing(false); } }; const hasFiles = files.length > 0; return (

Layout

{LAYOUTS.map((l) => ( ))}
{gap}px
setGap(Number(e.target.value))} className="w-full mt-1" />
setBackgroundColor(e.target.value)} className="w-full mt-0.5 h-8 rounded border border-border" />
{error &&

{error}

} {originalSize != null && processedSize != null && (

Input total: {(originalSize / 1024).toFixed(1)} KB

Collage: {(processedSize / 1024).toFixed(1)} KB

)} {downloadUrl && ( Download Collage )}
); }