From 0e884f20c5a47ae5904e51ccefc5b9680efd2cf4 Mon Sep 17 00:00:00 2001 From: "Roberto.silva" Date: Fri, 7 Nov 2025 07:23:02 -0600 Subject: [PATCH] Se agrega funcionalidad de historico de cambios --- .../historico/HistorialCambiosModal.tsx | 92 +++++++++++++++++++ src/components/planes/academic-sections.tsx | 79 ++++++++++------ 2 files changed, 142 insertions(+), 29 deletions(-) create mode 100644 src/components/historico/HistorialCambiosModal.tsx diff --git a/src/components/historico/HistorialCambiosModal.tsx b/src/components/historico/HistorialCambiosModal.tsx new file mode 100644 index 0000000..225e432 --- /dev/null +++ b/src/components/historico/HistorialCambiosModal.tsx @@ -0,0 +1,92 @@ +import { useQuery } from "@tanstack/react-query" +import { Dialog, DialogContent, DialogHeader, DialogTitle } from "@/components/ui/dialog" +import { Button } from "@/components/ui/button" +import { supabase } from "@/auth/supabase" +import ReactMarkdown from "react-markdown" +import { useSupabaseAuth } from "@/auth/supabase" + +export function HistorialCambiosModal({ + open, + onClose, + planId, + onRestore, // 🔥 recibiremos una función del padre para restaurar +}: { + open: boolean + onClose: () => void + planId: string + onRestore: (key: string, value: string) => void +}) { + const auth = useSupabaseAuth() + + const { data, isLoading, error } = useQuery({ + queryKey: ["historico_cambios", planId, auth.user?.id], + queryFn: async () => { + const { data, error } = await supabase + .from("historico_cambios") + .select("id, json_cambios, user_id, created_at") + .eq("id_plan_estudios", planId) + .eq("user_id", auth.user?.id) // ✅ filtro por usuario actual + .order("created_at", { ascending: false }) + + if (error) throw error + return data + }, + enabled: !!auth.user?.id, // ✅ solo corre si hay usuario autenticado + }) + + return ( + + + + Histórico de cambios + + + {isLoading &&

Cargando historial...

} + {error &&

Error al cargar: {String(error)}

} + {!isLoading && !error && (!data || data.length === 0) && ( +

No hay cambios registrados.

+ )} + +
+ {data?.map((item) => { + const diff = item.json_cambios?.[0] + const key = diff?.path?.replace("/", "") + return ( +
+
+ Usuario: {item.user_id || "Desconocido"} + {new Date(item.created_at).toLocaleString()} +
+ +
+

Campo: {key}

+

Antes: {diff?.from || "—"}

+

Después: {diff?.value || "—"}

+
+ + +
+ ) + })} +
+ +
+ +
+
+
+ ) + +} diff --git a/src/components/planes/academic-sections.tsx b/src/components/planes/academic-sections.tsx index da3baa4..170031f 100644 --- a/src/components/planes/academic-sections.tsx +++ b/src/components/planes/academic-sections.tsx @@ -7,6 +7,7 @@ import { Textarea } from "@/components/ui/textarea" import { supabase,useSupabaseAuth } from "@/auth/supabase" import { toast } from "sonner" import ReactMarkdown from 'react-markdown' +import { HistorialCambiosModal } from "../historico/HistorialCambiosModal" /* ===================================================== @@ -27,6 +28,7 @@ export type PlanTextFields = { indicadores_desempeno?: string | string[] | null pertinencia?: string | string[] | null prompt?: string | null + historico?: string | null } async function fetchPlanText(planId: string): Promise { @@ -112,6 +114,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() + const [openHistorial, setOpenHistorial] = useState(false) if(!planId) return
Cargando…
const { data: plan } = useSuspenseQuery(planTextOptions(planId)) @@ -155,6 +158,7 @@ export function AcademicSections({ planId, color }: { planId: string; color?: st { id: "sec-ind", title: "Indicadores de desempeño", icon: Icons.LineChart, key: "indicadores_desempeno" as const, mono: false }, { id: "sec-per", title: "Pertinencia", icon: Icons.Lightbulb, key: "pertinencia" as const, mono: false }, { id: "sec-prm", title: "Prompt (origen)", icon: Icons.Code2, key: "prompt" as const, mono: true }, + { id: "sec-hist", title: "Histórico de cambios", icon: Icons.History, key: "historico" as const, mono: false } ], [] ) @@ -163,38 +167,48 @@ export function AcademicSections({ planId, color }: { planId: string; color?: st <>
{sections.map((s) => { - const text = plan[s.key] ?? null - return ( - - -
- - {s.key !== "prompt" && - ( + ) : ( + <> + +
+ )} -
- - ) - })} + Copiar + + {s.key !== "prompt" && ( + + )} +
+ + )} +
+ ) + })} +
{/* Diálogo de edición */} @@ -257,7 +271,14 @@ export function AcademicSections({ planId, color }: { planId: string; color?: st - + setOpenHistorial(false)} + planId={planId} + onRestore={async (key, value) => { + updateField.mutate({ key, value }) + }} + /> ) }