import { BASE_CONFIG, CONVERSION_PRESET_BY_ID } from "@snapotter/shared"; import { Download } from "lucide-react"; import { useState } from "react"; import { useParams } from "react-router-dom"; import { ProgressCard } from "@/components/common/progress-card"; import { useTranslation } from "@/contexts/i18n-context"; import { useToolProcessor } from "@/hooks/use-tool-processor"; import { format } from "@/lib/format"; import { useFileStore } from "@/stores/file-store"; /** Target formats that honor a quality knob (lossy raster encodings). */ const LOSSY = new Set(["jpg", "jpeg", "webp", "avif"]); /** * One settings panel shared by every conversion preset. Reads the active tool * id from the route (the /:section/:toolId param), looks up the preset and its * base settingsKind from shared metadata, and renders the matching controls: * a quality slider for lossy raster/svg targets, a quality select for * convert-video, page size + orientation for image-to-pdf, nothing otherwise. */ export function ConversionPresetSettings() { const { t } = useTranslation(); const params = useParams<{ toolId: string }>(); const toolId = params.toolId ?? ""; const preset = CONVERSION_PRESET_BY_ID[toolId]; const kind = preset ? BASE_CONFIG[preset.base].settingsKind : "none"; const { files } = useFileStore(); const { processFiles, processAllFiles, processing, error, downloadUrl, progress } = useToolProcessor(toolId); const [quality, setQuality] = useState(85); const [videoQuality, setVideoQuality] = useState<"high" | "balanced" | "small">("balanced"); const [pageSize, setPageSize] = useState<"A4" | "Letter" | "A3" | "A5">("A4"); const [orientation, setOrientation] = useState<"portrait" | "landscape">("portrait"); const hasFile = files.length > 0; const targetIsLossy = preset ? LOSSY.has(String(preset.locked.format ?? "")) : false; const buildSettings = (): Record => { if (kind === "quality" && targetIsLossy) return { quality }; if (kind === "video") return { quality: videoQuality }; if (kind === "pdf") return { pageSize, orientation }; return {}; }; const handleProcess = () => { const settings = buildSettings(); if (files.length > 1) processAllFiles(files, settings); else processFiles(files, settings); }; const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); if (hasFile && !processing) handleProcess(); }; return (
{kind === "quality" && targetIsLossy && (
{quality}
setQuality(Number(e.target.value))} className="w-full mt-1" />
)} {kind === "video" && (
)} {kind === "pdf" && (
)} {error &&

{error}

} {processing ? ( ) : ( )} {downloadUrl && ( {t.common.download} )} ); }