Instruction file imported from iizquierdo/atletis.app (
.cursor/rules/sinapsis-list-pages.mdc). Copyright stays with the author.
Listas en Sinapsis (formato estándar)
Al crear o refactorizar una página de listado (tabla con búsqueda, ordenación y acciones), sigue este patrón para mantener coherencia con el listado de compañías y el resto del producto.
Referencia obligatoria
Reutiliza la misma composición que components/settings/CompaniesSettingsTable.tsx:
-
Bloque de contexto (encima de la tarjeta), no dentro del
Card:h2conclassName="text-3xl font-extrabold tracking-tight text-slate-900"(y variantedark:si aplica).- Párrafo descriptivo debajo:
mt-1 font-medium text-slate-500.
-
Contenedor de lista:
CardconclassName="overflow-hidden". -
Cabecera del card (
CardHeaderconmin-h-0 flex-col gap-4 py-4 sm:flex-row sm:items-center sm:justify-between):- Izquierda:
CardHeading→CardTitle(el componente ya aplica mayúsculas y tipografía de título de listado). - Derecha (
CardToolbarconw-full flex-wrap … sm:justify-end):- Búsqueda:
divrelative+ icono lucide-reactSearchposicionadoabsolute start-3 top-1/2 …+Inputtype="search"conclassName="ps-9"yplaceholdertraducido. - Acción principal a la derecha:
Buttonvariant="primary"(por ejemplo “+ Nuevo …” o “Actualizar” con iconoPlus/RefreshCw). No dejar la toolbar solo con búsqueda sin botón principal salvo que el PM lo pida explícitamente.
- Búsqueda:
- Izquierda:
-
Cuerpo de tabla:
CardTableconclassName="p-0"envolviendoDataGrid+div.overflow-x-auto+DataGridTable. -
Tabla de datos:
- TanStack Table (
useReactTable,getCoreRowModel,getSortedRowModel, estadosorting/onSortingChange). - Columnas ordenables: cabecera con
DataGridColumnHeaderymeta.headerTitlecoherente con el título mostrado. - Columna de acciones:
enableSorting: false, cabecera alineada a la derecha con el mismo patrón que en compañías (spanconuppercase tracking-wide text-table-header-foreground), celdasflex justify-end gap-1yButtonmode="icon"size="sm"variant="outline"className="size-8"con iconos lucide (Eye,Pencil,Trash2, etc.). - Clic en fila (
onRowClickenDataGrid) cuando tenga sentido (p. ej. ver detalle), además de botones de acción.
- TanStack Table (
-
DataGrid: pasartableLayoutalineado al listado de referencia, por ejemplo:rowBorder: true,headerBackground: true,headerBorder: true,width: 'auto'. -
Filas vacías / carga:
recordCount,emptyMessage(sin datos vs sin coincidencias de búsqueda) eisLoadingcuando los datos vengan de API. -
Búsqueda en listado: filtrado en cliente con
useMemosobre el array cargado (como en compañías), salvo que el volumen obligue a búsqueda server-side documentada. -
Imports:
Card,CardHeader,CardHeading,CardTitle,CardToolbar,CardTabledesde@/components/ui/card;DataGrid,DataGridTable,DataGridColumnHeaderdesde@/components/ui/data-grid*.
Atajo recomendado: components/shared/ListCard
Para no repetir el armado del card + toolbar + DataGrid, usá el wrapper
components/shared/ListCard.tsx, que ya encapsula el patrón completo. Vos solo definís
las columnas (TanStack) y el useReactTable, y le pasás table, recordCount,
emptyMessage, searchTerm/onSearchChange, primaryLabel/onPrimary y onRowClick.
Desde un módulo (modules/<x>/client) se importa por el alias @webapp:
import ListCard from '@webapp/components/shared/ListCard';
import { Button } from '@webapp/components/ui/button';
import { DataGridColumnHeader } from '@webapp/components/ui/data-grid-column-header';
import { cn } from '@webapp/lib/utils';
Referencias ya migradas a este patrón: modules/{disciplines,students,communities}/client/*Module.tsx.
Pantallas de detalle de entidad: components/shared/ProfileHeader
Para la vista de detalle de una entidad (alumno, comunidad, disciplina, etc.) usá
components/shared/ProfileHeader.tsx, que replica el estilo de "Mi Perfil"
(components/UserAccount): banner con degradado from-primary to-primary/75,
avatar/iniciales/icono superpuesto, fila de meta con iconos y tabs. Le pasás
title, initials/icon/imageUrl, meta (iconos lucide + texto), tabs,
activeTab, onTabChange, onBack y actions (p. ej. botón Editar). El contenido
de cada tab va debajo, envuelto en un card blanco
(rounded-2xl border border-slate-200 bg-white p-6 shadow-sm).
Evitar
- Tablas “planas” con
<table>manual sinDataGrid/DataGridColumnHeaderen nuevas pantallas de producto. - Barra de búsqueda sin icono ni sin el layout de toolbar del card.
- Sustituir el botón primary verde por
variant="secondary"como única acción principal del listado, salvo excepción acordada.