92 lines
3.1 KiB
TypeScript
92 lines
3.1 KiB
TypeScript
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 { 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 (
|
|
<Dialog open={open} onOpenChange={onClose}>
|
|
<DialogContent className="max-w-3xl">
|
|
<DialogHeader>
|
|
<DialogTitle>Histórico de cambios</DialogTitle>
|
|
</DialogHeader>
|
|
|
|
{isLoading && <p className="text-sm text-gray-500">Cargando historial...</p>}
|
|
{error && <p className="text-red-500 text-sm">Error al cargar: {String(error)}</p>}
|
|
{!isLoading && !error && (!data || data.length === 0) && (
|
|
<p className="text-gray-500 text-sm">No hay cambios registrados.</p>
|
|
)}
|
|
|
|
<div className="space-y-4 max-h-[60vh] overflow-y-auto">
|
|
{data?.map((item) => {
|
|
const diff = item.json_cambios?.[0]
|
|
const key = diff?.path?.replace("/", "")
|
|
return (
|
|
<div
|
|
key={item.id}
|
|
className="rounded-lg border p-3 bg-white/70 dark:bg-neutral-900/50"
|
|
>
|
|
<div className="flex justify-between text-xs text-neutral-500 mb-2">
|
|
<span>Usuario: {item.user_id || "Desconocido"}</span>
|
|
<span>{new Date(item.created_at).toLocaleString()}</span>
|
|
</div>
|
|
|
|
<div className="text-xs text-gray-700 font-mono whitespace-pre-wrap">
|
|
<p><strong>Campo:</strong> {key}</p>
|
|
<p><strong>Antes:</strong> {diff?.from || "—"}</p>
|
|
<p><strong>Después:</strong> {diff?.value || "—"}</p>
|
|
</div>
|
|
|
|
<Button
|
|
size="sm"
|
|
variant="outline"
|
|
className="mt-2"
|
|
onClick={() => onRestore(key, diff.from)}
|
|
>
|
|
Restaurar
|
|
</Button>
|
|
</div>
|
|
)
|
|
})}
|
|
</div>
|
|
|
|
<div className="mt-4 text-right">
|
|
<Button variant="outline" onClick={onClose}>
|
|
Cerrar
|
|
</Button>
|
|
</div>
|
|
</DialogContent>
|
|
</Dialog>
|
|
)
|
|
|
|
}
|