diff --git a/src/admin/pages/InvoiceDetail.tsx b/src/admin/pages/InvoiceDetail.tsx index ff62eb6..e0779d7 100644 --- a/src/admin/pages/InvoiceDetail.tsx +++ b/src/admin/pages/InvoiceDetail.tsx @@ -975,18 +975,21 @@ export default function InvoiceDetail() { // ─── Edit mode: PDF export ─── const handleViewPdf = async (_lang = "cs") => { + const newWindow = window.open("", "_blank"); setPdfLoading(true); try { const response = await apiFetch(`${API_BASE}/invoices/${id}/file`); if (!response.ok) { + newWindow?.close(); alert.error("PDF soubor nenalezen — uložte fakturu pro vygenerování"); return; } const blob = await response.blob(); const url = URL.createObjectURL(blob); - window.open(url, "_blank"); + if (newWindow) newWindow.location.href = url; setTimeout(() => URL.revokeObjectURL(url), 60000); } catch { + newWindow?.close(); alert.error("Chyba připojení"); } finally { setPdfLoading(false); diff --git a/src/admin/pages/OfferDetail.tsx b/src/admin/pages/OfferDetail.tsx index a48eb6a..a0163d4 100644 --- a/src/admin/pages/OfferDetail.tsx +++ b/src/admin/pages/OfferDetail.tsx @@ -768,19 +768,25 @@ export default function OfferDetail() { const handlePdf = async () => { if (!isEdit || pdfLoading) return; + const newWindow = window.open("", "_blank"); setPdfLoading(true); try { const response = await apiFetch(`${API_BASE}/offers/${id}/file`); - if (response.status === 401) return; + if (response.status === 401) { + newWindow?.close(); + return; + } if (!response.ok) { + newWindow?.close(); alert.error("PDF soubor nenalezen — uložte nabídku pro vygenerování"); return; } const blob = await response.blob(); const url = URL.createObjectURL(blob); - window.open(url, "_blank"); + if (newWindow) newWindow.location.href = url; setTimeout(() => URL.revokeObjectURL(url), 60000); } catch { + newWindow?.close(); alert.error("Chyba při generování PDF"); } finally { setPdfLoading(false); diff --git a/src/admin/pages/Offers.tsx b/src/admin/pages/Offers.tsx index 119be91..3624320 100644 --- a/src/admin/pages/Offers.tsx +++ b/src/admin/pages/Offers.tsx @@ -221,21 +221,27 @@ export default function Offers() { const handlePdf = async (quotation: Quotation) => { if (pdfLoading) return; + const newWindow = window.open("", "_blank"); setPdfLoading(quotation.id); try { const response = await apiFetch( `${API_BASE}/offers/${quotation.id}/file`, ); - if (response.status === 401) return; + if (response.status === 401) { + newWindow?.close(); + return; + } if (!response.ok) { + newWindow?.close(); alert.error("PDF soubor nenalezen — otevřete nabídku a uložte ji"); return; } const blob = await response.blob(); const url = URL.createObjectURL(blob); - window.open(url, "_blank"); + if (newWindow) newWindow.location.href = url; setTimeout(() => URL.revokeObjectURL(url), 60000); } catch { + newWindow?.close(); alert.error("Chyba připojení"); } finally { setPdfLoading(null); diff --git a/src/admin/pages/ReceivedInvoices.tsx b/src/admin/pages/ReceivedInvoices.tsx index c22f3fb..c165a3c 100644 --- a/src/admin/pages/ReceivedInvoices.tsx +++ b/src/admin/pages/ReceivedInvoices.tsx @@ -503,19 +503,22 @@ export default function ReceivedInvoices({ }; const openFile = async (inv: ReceivedInvoice) => { + const newWindow = window.open("", "_blank"); try { const response = await apiFetch( `${API_BASE}/received-invoices/${inv.id}/file`, ); if (!response.ok) { + newWindow?.close(); alert.error("Nepodařilo se načíst soubor"); return; } const blob = await response.blob(); const url = URL.createObjectURL(blob); - window.open(url, "_blank"); + if (newWindow) newWindow.location.href = url; setTimeout(() => URL.revokeObjectURL(url), 60000); } catch { + newWindow?.close(); alert.error("Chyba připojení"); } };