fmatituy/selectospromanager
0
1from nicegui import ui
2from services.auth import require_auth, get_current_user
3from modules.layout import SelectosLayout
4from services.navigation import MANAGER_ROLES
5
6def render_console_card(title, description, icon, url, color="blue", status="Activo", role_allowed=["Todos"]):
7 # Paleta de Colores Institucional
8 CORP_BLUE = '#1F3A5F' # Azul Corporativo
9 CORP_GRAY = '#2C3E50' # Gris Texto Principal
10 CORP_BG = '#F4F7F9' # Fondo Institucional
11
12 user = get_current_user()
13 if not ("Todos" in role_allowed or user.get('rol') in role_allowed):
14 return
15
16 # Mapeo de colores a la paleta institucional
17 color_map = {
18 "blue": "#1F3A5F",
19 "indigo": "#3F51B5",
20 "violet": "#673AB7",
21 "amber": "#F57C00",
22 "rose": "#B71C1C",
23 "emerald": "#2E7D32",
24 "slate": "#455A64"
25 }
26 hex_color = color_map.get(color, color)
27
28 def handle_click():
29 if url.startswith('javascript:'):
30 ui.run_javascript(url[11:])
31 else:
32 ui.navigate.to(url)
33
34 with ui.card().classes('group relative transition-all duration-300 hover:shadow-md border border-slate-200 bg-white rounded-lg p-6 cursor-pointer h-full flex flex-col shadow-sm').on('click', handle_click):
35 with ui.row().classes('w-full justify-between items-start mb-4'):
36 with ui.element('div').classes('p-3 rounded-lg').style(f'background-color: {hex_color}10; color: {hex_color}'):
37 ui.icon(icon, size='1.8rem')
38
39 with ui.row().classes('items-center gap-1.5'):
40 ui.element('div').classes('w-1.5 h-1.5 rounded-full').style(f'background-color: {hex_color}')
41 ui.label(status).classes('text-[9px] font-bold tracking-widest text-slate-400 uppercase')
42
43 with ui.column().classes('gap-1.5 flex-1'):
44 ui.label(title).classes(f'text-lg font-bold text-[{CORP_GRAY}] tracking-tight leading-tight group-hover:text-[{CORP_BLUE}] transition-colors')
45 ui.label(description).classes('text-xs text-slate-500 font-medium leading-relaxed')
46
47 with ui.row().classes('w-full justify-between items-center mt-6 pt-4 border-t border-slate-50'):
48 ui.label('INGRESAR AL MÓDULO').classes(f'text-[9px] font-black tracking-[0.2em] text-slate-400 group-hover:text-[{CORP_BLUE}]')
49 ui.icon('chevron_right', size='1rem').classes('text-slate-300 group-hover:translate-x-1 transition-transform')
50
51def render_hub_header(title, subtitle, icon="shield"):
52 CORP_BLUE = '#1F3A5F'
53 CORP_GRAY = '#2C3E50'
54
55 with ui.row().classes('w-full justify-between items-center bg-white p-8 rounded-xl shadow-sm border-b-4 mb-8').style(f'border-color: {CORP_BLUE}'):
56 with ui.column().classes('gap-1 z-10'):
57 with ui.row().classes('items-center gap-2 mb-1'):
58 ui.icon(icon, color='slate-400', size='14px')
59 ui.label('SST CORPORATE SYSTEM').classes('text-[9px] font-black tracking-[0.4em] text-slate-400 uppercase')
60 ui.label(title).classes(f'text-3xl font-bold text-[{CORP_GRAY}] tracking-tight leading-none')
61 ui.label(subtitle).classes('text-sm text-slate-400 font-medium mt-1 uppercase tracking-wider')
62
63 ui.icon(icon, size='4rem', color='slate-50').classes('opacity-50')
64
65@ui.page('/sst/operacion')
66@require_auth
67def sst_operacion_hub():
68 CORP_BG = '#F4F7F9'
69 with SelectosLayout('Crear Permiso de Trabajo'):
70 ui.query('body').style(f'background-color: {CORP_BG}')
71 with ui.column().classes('w-full max-w-6xl mx-auto p-4 md:p-8'):
72 render_hub_header('Crear Permiso de Trabajo', 'GESTIÓN DE CAMPO Y EJECUCIÓN TÉCNICA', icon='engineering')
73
74 with ui.row().classes('w-full grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6'):
75 render_console_card('Centro de Formatos Inteligentes', 'Biblioteca de plantillas, rellenado automático y control de versiones.', 'architecture', '/sst/constructor', color='rose', role_allowed=MANAGER_ROLES)
76 render_console_card('Permisos de Trabajo Crítico', 'Gestión de alturas, caliente, confinados y energías críticas.', 'vpn_key', '/sst/constructor', color='amber')
77 render_console_card('Scan Designer Pro', 'Extrae formatos dinámicos a partir de un escaneo físico (IA).', 'document_scanner', '/sst/scan-designer', color='emerald', status="IA Pro", role_allowed=MANAGER_ROLES)
78 render_console_card('Sara IA: Borradores', 'Gestión de documentos preliminares y registros generados por IA.', 'auto_awesome', '/sst/borradores', color='blue', status="IA Activa")
79
80@ui.page('/sst/cumplimiento')
81@require_auth
82def sst_cumplimiento_hub():
83 CORP_BG = '#F4F7F9'
84 with SelectosLayout('Cumplimiento y Control'):
85 ui.query('body').style(f'background-color: {CORP_BG}')
86 with ui.column().classes('w-full max-w-6xl mx-auto p-4 md:p-8'):
87 render_hub_header('Cumplimiento y Control', 'CUMPLIMIENTO NORMATIVO Y VALIDACIÓN TÉCNICA', icon='verified_user')
88
89 with ui.row().classes('w-full grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6'):
90 render_console_card('Aval SHE', 'Validación y autorización técnica para inicio de actividades.', 'verified', '/sst/permisos/aval-she', color='emerald', role_allowed=MANAGER_ROLES)
91 render_console_card('Auditoría y Trazabilidad', 'Trazabilidad normativa y registro oficial de eventos críticos.', 'history_edu', '/sst/auditoria', color='slate', role_allowed=MANAGER_ROLES)
92 render_console_card('Expediente Digital', 'Repositorio centralizado de soportes y registros generados.', 'inventory', '/sst', color='indigo')
93 render_console_card('Alertas de Vencimiento', 'Control de vigencia legal para personal operativo y equipos.', 'notification_important', '/sst/alertas', color='rose', status="Validación Activa")
94 