import { useState, useEffect, useCallback, useRef } from "react"; import { useNavigate } from "react-router-dom"; import api from "../../api/client"; const STATUS_STYLES = { draft: { bg: "var(--bg-card-hover)", color: "var(--text-secondary)" }, sent: { bg: "var(--badge-blue-bg)", color: "var(--badge-blue-text)" }, accepted: { bg: "var(--success-bg)", color: "var(--success-text)" }, rejected: { bg: "var(--danger-bg)", color: "var(--danger-text)" }, }; function fmt(n) { const f = parseFloat(n) || 0; return f.toLocaleString("el-GR", { minimumFractionDigits: 2, maximumFractionDigits: 2 }) + " €"; } function fmtDate(iso) { if (!iso) return "—"; return iso.slice(0, 10); } // ── PDF thumbnail via PDF.js ────────────────────────────────────────────────── function loadPdfJs() { return new Promise((res, rej) => { if (window.pdfjsLib) { res(); return; } if (document.getElementById("__pdfjs2__")) { // Script already injected — wait for it const check = setInterval(() => { if (window.pdfjsLib) { clearInterval(check); res(); } }, 50); return; } const s = document.createElement("script"); s.id = "__pdfjs2__"; s.src = "https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.11.174/pdf.min.js"; s.onload = () => { window.pdfjsLib.GlobalWorkerOptions.workerSrc = "https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.11.174/pdf.worker.min.js"; res(); }; s.onerror = rej; document.head.appendChild(s); }); } function PdfThumbnail({ quotationId, onClick }) { const canvasRef = useRef(null); const [failed, setFailed] = useState(false); useEffect(() => { let cancelled = false; (async () => { try { await loadPdfJs(); const token = localStorage.getItem("access_token"); const url = `/api/crm/quotations/${quotationId}/pdf`; const loadingTask = window.pdfjsLib.getDocument({ url, httpHeaders: token ? { Authorization: `Bearer ${token}` } : {}, }); const pdf = await loadingTask.promise; if (cancelled) return; const page = await pdf.getPage(1); if (cancelled) return; const canvas = canvasRef.current; if (!canvas) return; const viewport = page.getViewport({ scale: 1 }); const scale = Math.min(72 / viewport.width, 96 / viewport.height); const scaled = page.getViewport({ scale }); canvas.width = scaled.width; canvas.height = scaled.height; await page.render({ canvasContext: canvas.getContext("2d"), viewport: scaled }).promise; } catch { if (!cancelled) setFailed(true); } })(); return () => { cancelled = true; }; }, [quotationId]); const style = { width: 72, height: 96, borderRadius: 4, overflow: "hidden", flexShrink: 0, cursor: "pointer", border: "1px solid var(--border-primary)", display: "flex", alignItems: "center", justifyContent: "center", backgroundColor: "var(--bg-primary)", }; if (failed) { return (