genración del pdf de plan de estudios ya funciona
This commit is contained in:
25
package-lock.json
generated
25
package-lock.json
generated
@@ -30,6 +30,7 @@
|
|||||||
"@tanstack/router-plugin": "^1.121.2",
|
"@tanstack/router-plugin": "^1.121.2",
|
||||||
"@types/canvas-confetti": "^1.9.0",
|
"@types/canvas-confetti": "^1.9.0",
|
||||||
"canvas-confetti": "^1.9.3",
|
"canvas-confetti": "^1.9.3",
|
||||||
|
"carbone-sdk-js": "^1.2.2",
|
||||||
"class-variance-authority": "^0.7.1",
|
"class-variance-authority": "^0.7.1",
|
||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
"cmdk": "^1.1.1",
|
"cmdk": "^1.1.1",
|
||||||
@@ -2819,6 +2820,12 @@
|
|||||||
"node": ">=10.0.0"
|
"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": {
|
"node_modules/ccount": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@@ -3372,6 +3379,20 @@
|
|||||||
"node": ">=8"
|
"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": {
|
"node_modules/gensync": {
|
||||||
"version": "1.0.0-beta.2",
|
"version": "1.0.0-beta.2",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@@ -5514,7 +5535,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/vite": {
|
"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",
|
"license": "MIT",
|
||||||
"peer": true,
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|||||||
@@ -34,6 +34,7 @@
|
|||||||
"@tanstack/router-plugin": "^1.121.2",
|
"@tanstack/router-plugin": "^1.121.2",
|
||||||
"@types/canvas-confetti": "^1.9.0",
|
"@types/canvas-confetti": "^1.9.0",
|
||||||
"canvas-confetti": "^1.9.3",
|
"canvas-confetti": "^1.9.3",
|
||||||
|
"carbone-sdk-js": "^1.2.2",
|
||||||
"class-variance-authority": "^0.7.1",
|
"class-variance-authority": "^0.7.1",
|
||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
"cmdk": "^1.1.1",
|
"cmdk": "^1.1.1",
|
||||||
|
|||||||
@@ -1,49 +1,132 @@
|
|||||||
import { Button } from "../ui/button"
|
import { supabase } from "@/auth/supabase";
|
||||||
import { Download } from "lucide-react"
|
import { Button } from "../ui/button";
|
||||||
|
import { Download } from "lucide-react";
|
||||||
|
|
||||||
export type PlanLike = Record<string, string | number | object | null | undefined>
|
export type PlanLike = Record<
|
||||||
|
string,
|
||||||
|
string | number | object | null | undefined
|
||||||
|
>;
|
||||||
|
|
||||||
export function DownloadPlanPDF({ plan }: { plan: PlanLike }) {
|
export function DownloadPlanPDF({ plan }: { plan: Record<string, any> }) {
|
||||||
async function fetchPDF() {
|
async function fetchPDF() {
|
||||||
try {
|
const planObj = {
|
||||||
const response = await fetch(
|
...plan,
|
||||||
"https://reportes-template.nicesand-99c6cbb8.westus2.azurecontainerapps.io/api/report",
|
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",
|
method: "POST",
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
Accept: "application/pdf",
|
Accept: "application/pdf",
|
||||||
|
...(token ? { Authorization: `Bearer ${token}` } : {}),
|
||||||
},
|
},
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
template: { name: "plan-estudios" },
|
action: "downloadReport",
|
||||||
data: {
|
templateId: "1302213091201757023",
|
||||||
nombre_autorizado_de_la_institucion: "Probando pdf",
|
fileName,
|
||||||
// (plan["nombre"] ? String(plan["nombre"]) : "Plan de estudios"),
|
convertTo: "pdf",
|
||||||
},
|
data: planObj,
|
||||||
}),
|
}),
|
||||||
}
|
});
|
||||||
)
|
|
||||||
|
|
||||||
if (!response.ok) {
|
if (!resp.ok) throw new Error(`HTTP ${resp.status}`);
|
||||||
const text = await response.text().catch(() => "")
|
const blob = await resp.blob();
|
||||||
console.error("Error HTTP al obtener PDF:", response.status, text)
|
triggerDownload(blob, fileName);
|
||||||
throw new Error(`HTTP ${response.status}`)
|
};
|
||||||
}
|
|
||||||
|
|
||||||
const ct = response.headers.get("Content-Type") || ""
|
try {
|
||||||
if (!ct.includes("application/pdf")) {
|
// const { data, error } = await supabase.functions.invoke(
|
||||||
const text = await response.text().catch(() => "")
|
// "carbone-io-api",
|
||||||
console.error("Respuesta no-PDF recibida:", text)
|
// {
|
||||||
}
|
// method: "POST",
|
||||||
|
// headers: { Accept: "application/octet-stream" }, // preferir binario
|
||||||
|
// body: {
|
||||||
|
// action: "downloadReport",
|
||||||
|
// templateId: "1302213091201757023",
|
||||||
|
// fileName,
|
||||||
|
// convertTo: "pdf",
|
||||||
|
// data: planObj,
|
||||||
|
// },
|
||||||
|
// }
|
||||||
|
// );
|
||||||
|
|
||||||
const blob = await response.blob()
|
// if (error) throw error;
|
||||||
const pdfUrl = URL.createObjectURL(blob)
|
|
||||||
window.open(pdfUrl, "_blank")
|
|
||||||
|
|
||||||
// Limpia el objeto URL después de un tiempo
|
// // Si ya viene binario, descargar directo
|
||||||
setTimeout(() => URL.revokeObjectURL(pdfUrl), 60_000)
|
// if (typeof Blob !== "undefined" && data instanceof Blob) {
|
||||||
|
// triggerDownload(data, fileName);
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// if (data instanceof ArrayBuffer) {
|
||||||
|
// triggerDownload(
|
||||||
|
// new Blob([data], { type: "application/pdf" }),
|
||||||
|
// fileName
|
||||||
|
// );
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Si vino como string (ej. empieza con %PDF), usa el fallback binario
|
||||||
|
// if (typeof data === "string") {
|
||||||
|
// await fetchBinaryFallback();
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // 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) {
|
} 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
|
Descargar PDF
|
||||||
<Download className="w-4 h-4" />
|
<Download className="w-4 h-4" />
|
||||||
</Button>
|
</Button>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default DownloadPlanPDF
|
export default DownloadPlanPDF;
|
||||||
|
|||||||
Reference in New Issue
Block a user