Se crea funcionalidad de exportar pdf desde front y generar historial de version de cambios se agrego una libreri jspdf

This commit is contained in:
2025-11-05 15:19:38 -06:00
parent daac6f3f6d
commit 9462e25a20
8 changed files with 6622 additions and 91 deletions

View File

@@ -4,7 +4,7 @@ import { useSuspenseQuery, useMutation, useQueryClient, queryOptions } from "@ta
import { Button } from "@/components/ui/button"
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter } from "@/components/ui/dialog"
import { Textarea } from "@/components/ui/textarea"
import { supabase } from "@/auth/supabase"
import { supabase,useSupabaseAuth } from "@/auth/supabase"
import { toast } from "sonner"
import ReactMarkdown from 'react-markdown'
@@ -111,6 +111,7 @@ function SectionPanel({ title, icon: Icon, color, children, id }: { title: strin
===================================================== */
export function AcademicSections({ planId, color }: { planId: string; color?: string | null }) {
const qc = useQueryClient()
const auth = useSupabaseAuth()
if(!planId) return <div>Cargando</div>
const { data: plan } = useSuspenseQuery(planTextOptions(planId))
@@ -196,28 +197,67 @@ export function AcademicSections({ planId, color }: { planId: string; color?: st
})}
</div>
{/* Diálogo de edición */}
<Dialog open={!!editing} onOpenChange={(o) => { if (!o) setEditing(null) }}>
<DialogContent className="max-w-2xl">
<DialogHeader>
<DialogTitle className="font-mono" >{editing ? `Editar: ${sections.find((x) => x.key === editing.key)?.title}` : ""}</DialogTitle>
</DialogHeader>
<Textarea value={draft} onChange={(e) => setDraft(e.target.value)} className={`min-h-[260px] ${editing?.key === "prompt" ? "font-mono" : ""}`} placeholder="Escribe aquí…" />
<DialogFooter>
<Button variant="outline" onClick={() => setEditing(null)}>Cancelar</Button>
<Button
onClick={() => {
if (!editing) return
updateField.mutate({ key: editing.key, value: draft })
setEditing(null)
}}
disabled={updateField.isPending}
>
{updateField.isPending ? "Guardando…" : "Guardar"}
</Button>
</DialogFooter>
</DialogContent>
</Dialog>
{/* Diálogo de edición */}
<Dialog open={!!editing} onOpenChange={(o) => { if (!o) setEditing(null) }}>
<DialogContent className="max-w-2xl">
<DialogHeader>
<DialogTitle className="font-mono">
{editing ? `Editar: ${sections.find((x) => x.key === editing.key)?.title}` : ""}
</DialogTitle>
</DialogHeader>
<Textarea
value={draft}
onChange={(e) => setDraft(e.target.value)}
className={`min-h-[260px] ${editing?.key === "prompt" ? "font-mono" : ""}`}
placeholder="Escribe aquí…"
/>
<DialogFooter>
<Button variant="outline" onClick={() => setEditing(null)}>Cancelar</Button>
<Button
onClick={async () => {
if (!editing) return
// 1⃣ Obtener el valor anterior (por ejemplo, desde 'plan' o 'section')
const oldValue = (plan as any)[editing.key]
// 2⃣ Crear un diff tipo JSON Patch
const diff = [{
op: "replace",
path: `/${editing.key}`,
from: oldValue,
value: draft
}]
// 3⃣ Guardar respaldo antes de actualizar
const { error: backupError } = await supabase.from("historico_cambios").insert({
id_plan_estudios: planId, // asegúrate de tener `plan.id` disponible en este contexto
json_cambios: diff,
user_id:auth.user?.id,
created_at: new Date().toISOString()
})
if (backupError) {
console.error("Error al guardar respaldo:", backupError)
alert("No se pudo guardar el respaldo de los cambios")
return
}
// 4⃣ Ejecutar la mutación original
updateField.mutate({ key: editing.key, value: draft })
// 5⃣ Cerrar el diálogo
setEditing(null)
}}
disabled={updateField.isPending}
>
{updateField.isPending ? "Guardando…" : "Guardar"}
</Button>
</DialogFooter>
</DialogContent>
</Dialog>
</>
)
}