import { Loader2 } from "lucide-react"; import { useState } from "react"; import { formatHeaders } from "@/lib/api"; import { useBase64Store } from "@/stores/base64-store"; import { useFileStore } from "@/stores/file-store"; const OUTPUT_FORMATS = [ { value: "original", label: "Keep Original" }, { value: "jpeg", label: "JPEG" }, { value: "png", label: "PNG" }, { value: "webp", label: "WebP" }, ] as const; export function ImageToBase64Settings() { const { files } = useFileStore(); const { processing, setProcessing, setResults, reset } = useBase64Store(); const [outputFormat, setOutputFormat] = useState("original"); const [quality, setQuality] = useState(80); const [maxWidth, setMaxWidth] = useState(0); const [maxHeight, setMaxHeight] = useState(0); const [error, setError] = useState(null); const handleProcess = async () => { if (files.length === 0) return; setProcessing(true); setError(null); reset(); try { const formData = new FormData(); for (const file of files) { formData.append("files", file); } formData.append("settings", JSON.stringify({ outputFormat, quality, maxWidth, maxHeight })); const res = await fetch("/api/v1/tools/image-to-base64", { method: "POST", headers: formatHeaders(), body: formData, }); if (!res.ok) { const body = await res.json().catch(() => ({})); throw new Error(body.error || `Failed: ${res.status}`); } const data = await res.json(); setResults(data.results, data.errors); } catch (err) { setError(err instanceof Error ? err.message : "Failed to convert"); } finally { setProcessing(false); } }; const hasFiles = files.length > 0; const showQuality = outputFormat === "jpeg" || outputFormat === "webp"; return (
{/* Output Format */}

Convert before encoding to control MIME type and size

{OUTPUT_FORMATS.map((fmt) => ( ))}
{/* Quality slider */} {showQuality && (
{quality}%
setQuality(Number(e.target.value))} className="w-full mt-1 accent-primary" />

Lower quality = smaller base64 string

)} {/* Max Width */}
setMaxWidth(Math.max(0, Number(e.target.value)))} placeholder="0 = no limit" className="mt-1 w-full rounded bg-muted px-3 py-1.5 text-xs text-foreground placeholder:text-muted-foreground/50 outline-none" />
{/* Max Height */}
setMaxHeight(Math.max(0, Number(e.target.value)))} placeholder="0 = no limit" className="mt-1 w-full rounded bg-muted px-3 py-1.5 text-xs text-foreground placeholder:text-muted-foreground/50 outline-none" />

Resize before encoding. Aspect ratio is preserved. 0 = no limit.

{/* Process button */} {error &&

{error}

}
); }