diff --git a/package-lock.json b/package-lock.json index 6d48975..29ce438 100644 --- a/package-lock.json +++ b/package-lock.json @@ -30,6 +30,7 @@ "@tanstack/router-plugin": "^1.121.2", "@types/canvas-confetti": "^1.9.0", "canvas-confetti": "^1.9.3", + "carbone-sdk-js": "^1.2.2", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "cmdk": "^1.1.1", @@ -2819,6 +2820,12 @@ "node": ">=10.0.0" } }, + "node_modules/carbone-sdk-js": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/carbone-sdk-js/-/carbone-sdk-js-1.2.2.tgz", + "integrity": "sha512-3bc4F04DizC8ULB6j6JsOq8G0sW/pwdwvfbbZ8exBZbcOCV4WE8KHsY6GiED/3tmH++Z1I5XMppjkBhjg60zjA==", + "license": "Apache-2.0" + }, "node_modules/ccount": { "version": "2.0.1", "license": "MIT", @@ -3372,6 +3379,20 @@ "node": ">=8" } }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, "node_modules/gensync": { "version": "1.0.0-beta.2", "license": "MIT", @@ -5514,7 +5535,9 @@ } }, "node_modules/vite": { - "version": "6.3.5", + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.4.1.tgz", + "integrity": "sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g==", "license": "MIT", "peer": true, "dependencies": { diff --git a/package.json b/package.json index 7b7c8d6..dad4635 100644 --- a/package.json +++ b/package.json @@ -34,6 +34,7 @@ "@tanstack/router-plugin": "^1.121.2", "@types/canvas-confetti": "^1.9.0", "canvas-confetti": "^1.9.3", + "carbone-sdk-js": "^1.2.2", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "cmdk": "^1.1.1", diff --git a/src/components/planes/DownloadPlanPDF.tsx b/src/components/planes/DownloadPlanPDF.tsx index 09fbab4..476a4cc 100644 --- a/src/components/planes/DownloadPlanPDF.tsx +++ b/src/components/planes/DownloadPlanPDF.tsx @@ -1,49 +1,132 @@ -import { Button } from "../ui/button" -import { Download } from "lucide-react" +import { supabase } from "@/auth/supabase"; +import { Button } from "../ui/button"; +import { Download } from "lucide-react"; -export type PlanLike = Record +export type PlanLike = Record< + string, + string | number | object | null | undefined +>; -export function DownloadPlanPDF({ plan }: { plan: PlanLike }) { +export function DownloadPlanPDF({ plan }: { plan: Record }) { async function fetchPDF() { + const planObj = { + ...plan, + nivel_y_nombre_del_plan_de_estudios: `${plan["nivel"]} en ${plan["nombre"]}`, + nivel: undefined, + nombre: undefined, + }; + const fileName = `Plan_${planObj.nivel_y_nombre_del_plan_de_estudios || "Desconocido"}.pdf`; + // const jsonData = JSON.stringify(planObj); + + const triggerDownload = (blob: Blob, name: string) => { + const url = URL.createObjectURL(blob); + const a = document.createElement("a"); + a.href = url; + a.setAttribute("download", name); + document.body.appendChild(a); + a.click(); + a.remove(); + URL.revokeObjectURL(url); + }; + + const fetchBinaryFallback = async () => { + // Intenta construir la URL del runtime de Functions + const anyClient = supabase as any; + const baseUrl = + anyClient?.functions?.url || + `${(anyClient?.supabaseUrl || "").replace(/\/$/, "")}/functions/v1`; + const { data: sess } = await supabase.auth.getSession(); + const token = sess?.session?.access_token; + + console.log(JSON.stringify(planObj, null, 2)); + console.log(planObj); + + + + const resp = await fetch(`${baseUrl}/carbone-io-api`, { + method: "POST", + headers: { + "Content-Type": "application/json", + Accept: "application/pdf", + ...(token ? { Authorization: `Bearer ${token}` } : {}), + }, + body: JSON.stringify({ + action: "downloadReport", + templateId: "1302213091201757023", + fileName, + convertTo: "pdf", + data: planObj, + }), + }); + + if (!resp.ok) throw new Error(`HTTP ${resp.status}`); + const blob = await resp.blob(); + triggerDownload(blob, fileName); + }; + try { - const response = await fetch( - "https://reportes-template.nicesand-99c6cbb8.westus2.azurecontainerapps.io/api/report", - { - method: "POST", - headers: { - "Content-Type": "application/json", - Accept: "application/pdf", - }, - body: JSON.stringify({ - template: { name: "plan-estudios" }, - data: { - nombre_autorizado_de_la_institucion: "Probando pdf", - // (plan["nombre"] ? String(plan["nombre"]) : "Plan de estudios"), - }, - }), - } - ) + // const { data, error } = await supabase.functions.invoke( + // "carbone-io-api", + // { + // method: "POST", + // headers: { Accept: "application/octet-stream" }, // preferir binario + // body: { + // action: "downloadReport", + // templateId: "1302213091201757023", + // fileName, + // convertTo: "pdf", + // data: planObj, + // }, + // } + // ); - if (!response.ok) { - const text = await response.text().catch(() => "") - console.error("Error HTTP al obtener PDF:", response.status, text) - throw new Error(`HTTP ${response.status}`) - } + // if (error) throw error; - const ct = response.headers.get("Content-Type") || "" - if (!ct.includes("application/pdf")) { - const text = await response.text().catch(() => "") - console.error("Respuesta no-PDF recibida:", text) - } + // // Si ya viene binario, descargar directo + // if (typeof Blob !== "undefined" && data instanceof Blob) { + // triggerDownload(data, fileName); + // return; + // } + // if (data instanceof ArrayBuffer) { + // triggerDownload( + // new Blob([data], { type: "application/pdf" }), + // fileName + // ); + // return; + // } - const blob = await response.blob() - const pdfUrl = URL.createObjectURL(blob) - window.open(pdfUrl, "_blank") + // // Si vino como string (ej. empieza con %PDF), usa el fallback binario + // if (typeof data === "string") { + // await fetchBinaryFallback(); + // return; + // } - // Limpia el objeto URL después de un tiempo - setTimeout(() => URL.revokeObjectURL(pdfUrl), 60_000) + // // Si vino JSON con base64, decodificar y descargar + // if (data && typeof data === "object") { + // const b64 = + // (data as any).file || (data as any).buffer || (data as any).base64; + // if (typeof b64 === "string") { + // const clean = b64.replace(/^data:.*;base64,/, ""); + // const binary = atob(clean); + // const bytes = new Uint8Array(binary.length); + // for (let i = 0; i < binary.length; i++) + // bytes[i] = binary.charCodeAt(i); + // triggerDownload( + // new Blob([bytes], { type: "application/pdf" }), + // fileName + // ); + // return; + // } + // } + + // console.warn("Respuesta no reconocida para descarga de PDF.", { + // type: typeof data, + // }); + + await fetchBinaryFallback(); + return; } catch (error) { - console.error("Error al obtener PDF:", error) + console.error("Error al obtener PDF:", error); } } @@ -56,7 +139,7 @@ export function DownloadPlanPDF({ plan }: { plan: PlanLike }) { Descargar PDF - ) + ); } -export default DownloadPlanPDF \ No newline at end of file +export default DownloadPlanPDF;