feat: index SAM con tableros por modulo (SamShell Academico + sidebar de funciones API)

This commit is contained in:
Nurfog committed 2026-09-08 16:05:33 -03:00
1 parent 6d30e1c274
commit d30374729c
8 files changed
+719 -86

No files matched your search

+169
View File
@@ -0,0 +1,169 @@
// ============================================================
// SAM - Tipos, manifiesto de funciones API y helpers de UI
// Las funciones por módulo reflejan los controllers del
// backend compartido (SAM.API). El routing de ASP.NET Core
// es case-insensitive, por eso los paths van en minúsculas.
// ============================================================
export interface LastDeploy {
sha: string;
time: string;
ok: boolean;
log: string;
}
export interface ModuleState {
name: string;
repoUrl: string;
branch: string;
subdomain: string;
port: number;
active: boolean;
lastDeploy?: LastDeploy;
container?: string | null;
}
export interface ApiResponse {
backend: {
repoUrl: string;
branch: string;
container: string | null;
lastDeploy: LastDeploy | null;
};
modules: ModuleState[];
}
export interface ApiFunction {
label: string;
icon: string;
path: string;
desc: string;
}
export interface MenuItem {
label: string;
icon: string;
href: string;
}
const A = (
label: string,
icon: string,
path: string,
desc: string
): ApiFunction => ({ label, icon, path, desc });
// --- Conjuntos de funciones por familia de módulo ---
const CORE: ApiFunction[] = [
A("Alumnos", "bx-group", "api/alumnos", "Ficha, matrícula y sesiones de alumnos"),
A("Cursos", "bx-book", "api/cursos", "Catálogo, apertura y horarios de cursos"),
A("Profesores", "bx-pencil", "api/profesores", "Ficha y periodos de profesores"),
A("Empresas", "bx-buildings", "api/empresas/extra", "Empresas en convenio y propuestas"),
A("Pagos", "bx-money", "api/pagos", "Caja, cotizaciones y vouchers"),
A("Contratos", "bx-file", "api/contratos", "Contratos firmados y por firmar"),
A("Informes", "bx-bar-chart-alt-2", "api/informes", "Reportes académicos y de gestión"),
];
const FUNCTION_SETS: Record<string, ApiFunction[]> = {
academico: [
A("Cursos", "bx-book", "api/cursos", "Catálogo, apertura y horarios"),
A("Alumnos", "bx-group", "api/alumnos/extra", "Ficha, matrícula y sesiones"),
A("Apoderados", "bx-user", "api/apoderados", "Apoderados y contactos"),
A("Horarios", "bx-time", "api/horarios", "Bloques horarios y salas"),
A("Jornadas", "bx-sun", "api/jornadas", "Jornadas diurno / vespertino"),
A("Feriados", "bx-calendar", "api/feriados", "Calendario de feriados"),
A("Placement Test", "bx-edit", "api/placement-test", "Pruebas de nivel"),
A("Plan Anual", "bx-calendar-alt", "api/plan-anual", "Planificación anual"),
],
profesores: [
A("Profesores", "bx-pencil", "api/profesores", "Ficha y periodos"),
A("Funciones Extra", "bx-plus-circle", "api/profesores/extra", "Operaciones extendidas"),
A("Horarios", "bx-time", "api/horarios", "Bloques horarios y salas"),
A("Jornadas", "bx-sun", "api/jornadas", "Jornadas diurno / vespertino"),
],
empresas: [
A("Propuestas", "bx-briefcase", "api/propuestas-empresa", "Propuestas a empresas"),
A("Empresas", "bx-buildings", "api/empresas/extra", "Empresas en convenio"),
A("Comercial", "bx-trending-up", "api/comercial/extra", "Gestión comercial"),
A("Contratos", "bx-file", "api/contratos/extra", "Contratos con empresas"),
],
ventas: [
A("Comercial", "bx-trending-up", "api/comercial/extra", "Gestión comercial"),
A("Leads", "bx-target-lock", "api/leads/extra", "Prospectos y seguimiento"),
A("Ventas", "bx-cart", "api/ventas", "Ventas y cotizaciones"),
A("Cotizaciones", "bx-receipt", "api/cotizaciones", "Cotizaciones emitidas"),
A("Ejecutivos", "bx-user-voice", "api/ejecutivos", "Ejecutivos de venta"),
],
pagos: [
A("Portal Pagos", "bx-credit-card", "api/portal-pagos", "Pagos en línea"),
A("Pagos", "bx-money", "api/pagos", "Caja y vouchers"),
A("WebPay", "bx-card", "api/webpay", "Transacciones Transbank"),
A("Boletas", "bx-receipt", "api/boletas", "Boletas y facturación"),
A("Arqueo", "bx-calculator", "api/arqueocaja", "Arqueo de caja"),
],
contabilidad: [
A("Contabilidad", "bx-detail", "api/contabilidad", "Movimientos contables"),
A("Libros", "bx-book-open", "api/libros", "Libros de compra / venta"),
A("DTE", "bx-file-blank", "api/dte", "Documentos tributarios"),
A("Documentos", "bx-folder", "api/documentos", "Repositorio documental"),
],
};
const MODULE_FAMILY: Record<string, string> = {
academico: "academico",
"academico-empresas": "empresas",
portal: "empresas",
empresas: "empresas",
ventas: "ventas",
comercial: "ventas",
pagos: "pagos",
contabilidad: "contabilidad",
profesores: "profesores",
};
export function getModuleFunctions(name: string): ApiFunction[] {
const key = name.toLowerCase();
const family =
MODULE_FAMILY[key] ??
Object.keys(FUNCTION_SETS).find((f) => key.includes(f));
if (family && FUNCTION_SETS[family]) return FUNCTION_SETS[family];
return CORE;
}
// --- Meta visual por módulo (iconos boxicons + fondo) ---
const iconMap: Record<string, { icon: string; bg: string }> = {
sam: { icon: "bx-layer", bg: "bg-primary" },
ventas: { icon: "bx-money", bg: "bg-success" },
comercial: { icon: "bx-money", bg: "bg-success" },
finanzas: { icon: "bx-detail", bg: "bg-danger" },
contabilidad: { icon: "bx-detail", bg: "bg-danger" },
academico: { icon: "bx-user", bg: "bg-primary" },
"academico-empresas": { icon: "bx-briefcase", bg: "bg-primary" },
profesor: { icon: "bx-pencil", bg: "bg-warning text-dark" },
profesores: { icon: "bx-pencil", bg: "bg-warning text-dark" },
empresas: { icon: "bx-building", bg: "bg-info" },
portal: { icon: "bx-building", bg: "bg-info" },
pagos: { icon: "bx-credit-card", bg: "bg-success" },
default: { icon: "bx-cube", bg: "bg-secondary" },
};
export function getModuleMeta(name: string) {
return iconMap[name.toLowerCase()] || iconMap.default;
}
export function getStatusInfo(m: ModuleState) {
if (!m.container) return { label: "Detenido", cls: "status-unhealthy" };
if (m.container.includes("healthy"))
return { label: "Activo", cls: "status-healthy" };
if (m.container.includes("starting"))
return { label: "Iniciando", cls: "status-starting" };
return { label: "Activo", cls: "status-healthy" };
}
export function displayName(name: string) {
return name.charAt(0).toUpperCase() + name.slice(1).replace(/-/g, " ");
}
export function moduleUrl(m: ModuleState) {
return `https://${m.subdomain}.devops.norteamericano.cl`;
}