import { createFileRoute, useRouter, Link } from "@tanstack/react-router" import { useMemo, useState } from "react" import { supabase, useSupabaseAuth } from "@/auth/supabase" import { Input } from "@/components/ui/input" import { Button } from "@/components/ui/button" import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card" import { Badge } from "@/components/ui/badge" import * as Icons from "lucide-react" import { Plus, RefreshCcw, Building2, ScrollText, BookOpen } from "lucide-react" export type PlanDeEstudios = { id: string; nombre: string; nivel: string | null; duracion: string | null; total_creditos: number | null; estado: string | null; fecha_creacion: string | null; carrera_id: string | null } type PlanRow = PlanDeEstudios & { carreras: { id: string; nombre: string; facultades?: { id: string; nombre: string; color?: string | null; icon?: string | null } | null } | null } export const Route = createFileRoute("/_authenticated/planes")({ component: RouteComponent, loader: async () => { const { data, error } = await supabase .from("plan_estudios") .select(` *, carreras ( id, nombre, facultades:facultades ( id, nombre, color, icon ) ) `) .order("fecha_creacion", { ascending: false }) .limit(100) if (error) throw new Error(error.message) return (data ?? []) as PlanRow[] }, }) /* ---------- helpers de estilo suave ---------- */ function hexToRgb(hex?: string | null): [number, number, number] { if (!hex) return [37, 99, 235] // azul por defecto const h = hex.replace('#', '') const v = h.length === 3 ? h.split('').map(c => c + c).join('') : h const n = parseInt(v, 16) return [(n >> 16) & 255, (n >> 8) & 255, n & 255] } function softCardStyles(color?: string | null) { const [r, g, b] = hexToRgb(color) return { // borde + velo muy sutil del color de la facultad borderColor: `rgba(${r},${g},${b},.28)`, background: `linear-gradient(180deg, rgba(${r},${g},${b},.15), rgba(${r},${g},${b},.02))`, } as React.CSSProperties } function RouteComponent() { const auth = useSupabaseAuth() const [q, setQ] = useState("") const data = Route.useLoaderData() as PlanRow[] const router = useRouter() const showFacultad = auth.claims?.role === "lci" || auth.claims?.role === "vicerrectoria" const showCarrera = showFacultad || auth.claims?.role === "secretario_academico" const filtered = useMemo(() => { const term = q.trim().toLowerCase() if (!term || !data) return data return data.filter((p) => [p.nombre, p.nivel, p.estado, p.carreras?.nombre, p.carreras?.facultades?.nombre] .filter(Boolean) .some((v) => String(v).toLowerCase().includes(term)) ) }, [q, data]) return (