From 3e12f4f15a09fae6952ad758500dec338f680d00 Mon Sep 17 00:00:00 2001 From: Alejandro Rosales Date: Thu, 21 Aug 2025 15:57:12 -0600 Subject: [PATCH] refactor: clean up code formatting and improve layout in usuarios and procedencia-combobox components --- src/components/users/procedencia-combobox.tsx | 6 +- src/routes/_authenticated/usuarios.tsx | 151 ++++++++++++------ 2 files changed, 103 insertions(+), 54 deletions(-) diff --git a/src/components/users/procedencia-combobox.tsx b/src/components/users/procedencia-combobox.tsx index 2209231..f57e7c4 100644 --- a/src/components/users/procedencia-combobox.tsx +++ b/src/components/users/procedencia-combobox.tsx @@ -6,11 +6,11 @@ import { Check, ChevronsUpDown, Building2, GraduationCap } from "lucide-react" import { supabase } from "@/auth/supabase" /* Util simple */ -const cls = (...a: (string|false|undefined)[]) => a.filter(Boolean).join(" ") +const cls = (...a: (string | false | undefined)[]) => a.filter(Boolean).join(" ") /* --------- COMBOBOX BASE --------- */ function ComboBase({ - placeholder, value, onChange, options, icon:Icon, + placeholder, value, onChange, options, icon: Icon, }: { placeholder: string value?: string | null @@ -28,7 +28,7 @@ function ComboBase({ type="button" variant="outline" role="combobox" - className="w-full sm:w-[420px] justify-between truncate" + className="w-full justify-between truncate" title={current?.label ?? placeholder} > diff --git a/src/routes/_authenticated/usuarios.tsx b/src/routes/_authenticated/usuarios.tsx index 26b7cf8..1b0744d 100644 --- a/src/routes/_authenticated/usuarios.tsx +++ b/src/routes/_authenticated/usuarios.tsx @@ -18,7 +18,6 @@ import { import { SupabaseClient } from "@supabase/supabase-js" import { CarreraCombobox, FacultadCombobox } from "@/components/users/procedencia-combobox" -/* ---------- Tipos ---------- */ type AdminUser = { id: string email: string | null @@ -31,7 +30,6 @@ type AdminUser = { const ROLES = ["lci", "vicerrectoria", "secretario_academico", "jefe_carrera", "planeacion"] as const export type Role = typeof ROLES[number] -/* ---------- Meta bonita de roles (codificado internamente) ---------- */ const ROLE_META: Record> @@ -69,13 +67,16 @@ function RolePill({ role }: { role: Role }) { if (!meta) return null const { Icon, className, label } = meta return ( - - {label} + + + {label} ) } -/* ---------- Página ---------- */ export const Route = createFileRoute("/_authenticated/usuarios")({ component: RouteComponent, loader: async () => { @@ -163,15 +164,21 @@ function RouteComponent() { return (
- + Usuarios
- setQ(e.target.value)} className="w-72" /> + setQ(e.target.value)} + className="w-full" + />
+
{filtered.map(u => { @@ -179,50 +186,96 @@ function RouteComponent() { const a = u.app_metadata || {} const roleCode: Role | undefined = a.role return ( -
- -
-
-
- {m.nombre ? `${m.nombre} ${m.apellidos ?? ""}` : (u.email ?? "—")} +
+
+ + +
+ {/* Fila superior: nombre + chips + botón (desktop) */} +
+
+
+ {m.title ? `${m.title} ` : ""} + {m.nombre ? `${m.nombre} ${m.apellidos ?? ""}` : (u.email ?? "—")} +
+ +
+ {roleCode && } {/* usa el pill responsivo */} + {a.claims_admin ? ( + + Administrador + + ) : ( + + Usuario + + )} +
+
+ + {/* Desktop: botón con texto */} + +
+ + {/* Fila inferior: metadatos (wrapping) */} +
+ + {u.email ?? "—"} + + + Creado: {new Date(u.created_at).toLocaleDateString()} + + + Último acceso: {u.last_sign_in_at ? new Date(u.last_sign_in_at).toLocaleDateString() : "—"} + + {m.email_verified ? ( + + Verificado + + ) : ( + + No verificado + + )}
- {roleCode && } - {a.claims_admin ? ( - Administrador - ) : ( - Usuario - )}
-
- {u.email ?? "—"} - Creado: {new Date(u.created_at).toLocaleDateString()} - Último acceso: {u.last_sign_in_at ? new Date(u.last_sign_in_at).toLocaleDateString() : "—"} - {m.email_verified ? ( - Verificado - ) : ( - No verificado - )} -
-
-
-
+ ) })} - {!filtered.length &&
Sin usuarios
} + {!filtered.length && ( +
Sin usuarios
+ )}
{/* Dialog de edición */} { if (!o) setEditing(null) }}> - + Editar usuario
@@ -265,36 +318,31 @@ function RouteComponent() { }} > {/* Hace que el popper herede ancho del trigger y no se salga */} - + {ROLES.map(code => { const meta = ROLE_META[code]; const Icon = meta.Icon return ( - + - - {meta.label} + {meta.label} ) })} +
{/* Solo SECRETARIO: facultad */} - {/* SECRETARIO: solo facultad */} {form.role === "secretario_academico" && (
@@ -308,7 +356,7 @@ function RouteComponent() { {/* JEFE DE CARRERA: ambos */} {form.role === "jefe_carrera" && ( - <> + < div className="grid gap-4 sm:grid-cols-2"> {/* 👈 asegura wrap en XS */}
- +
+ )} @@ -346,6 +395,6 @@ function RouteComponent() {
-
+
) }