CoolFace
Apppublic

fmatituy/selectospromanager

sourceHugging Faceupdated 6mo agoView on Hugging Face
0likes
dashboard_shared.py100 linesDownload Raw Back to modules
1from nicegui import ui
2from services.auth import get_current_user
3
4def render_view_selector(current_view='gerencial'):
5    """Renders the top switcher between Management and Operational views."""
6    user = get_current_user()
7    rol = user.get('rol', '')
8    
9    with ui.row().classes('w-full justify-center mb-6'):
10        with ui.row().classes('bg-slate-200 p-1.5 rounded-2xl gap-1 shadow-inner'):
11            # Gerencial Button - Only for Gerencia
12            if 'Gerente' in rol or 'Gerencia' in rol:
13                ui.button('VISTA GERENCIAL', 
14                          on_click=lambda: ui.navigate.to('/dashboard/gerencial'),
15                          icon='insights').props(
16                    f'unelevated rounded-xl size=sm {"color=primary" if current_view == "gerencial" else "flat color=slate-500"}'
17                ).classes('px-6 font-black tracking-widest')
18            
19            # Operativo Button
20            ui.button('VISTA OPERATIVA', 
21                      on_click=lambda: ui.navigate.to('/dashboard/operativo'),
22                      icon='engineering').props(
23                f'unelevated rounded-xl size=sm {"color=primary" if current_view == "operativo" else "flat color=slate-500"}'
24            ).classes('px-6 font-black tracking-widest')
25
26def render_kpi_card_industrial(title, val, icon, color='blue-600', trend=None, subtitle=None, on_click_info=None, spark_data=None):
27    """Modern industrial KPI card - COMPACT VERSION."""
28    color_map = {'blue-600': '#2563eb', 'emerald-600': '#059669', 'indigo-600': '#4f46e5', 'orange-600': '#ea580c', 'rose-600': '#e11d48'}
29    hex_color = color_map.get(color, '#2563eb')
30    
31    with ui.card().classes('h-full p-4 rounded-xl border border-slate-100 shadow-sm hover:shadow-md transition-all relative overflow-hidden bg-white group'):
32        # Glow strip
33        ui.element('div').classes(f'absolute top-0 left-0 w-full h-1 bg-{color} opacity-60 group-hover:opacity-100 transition-opacity')
34        
35        with ui.row().classes('justify-between items-center w-full mb-1'):
36            ui.label(title).classes('text-[9px] font-black text-slate-400 uppercase tracking-[0.15em]')
37            ui.icon(icon, size='14px').classes(f'text-{color} opacity-40')
38            
39        with ui.row().classes('items-baseline gap-2'):
40            ui.label(val).classes('text-2xl font-black text-slate-800 tracking-tighter')
41            if trend:
42                is_up = '↑' in trend
43                tc = 'emerald-500' if is_up else 'rose-500'
44                ui.label(trend).classes(f'text-[8px] font-black text-{tc} bg-{tc}/10 px-1.5 py-0.5 rounded')
45        
46        if spark_data:
47            ui.echart({
48                'grid': {'left': 0, 'right': 0, 'top': 2, 'bottom': 2},
49                'xAxis': {'show': False, 'type': 'category'},
50                'yAxis': {'show': False, 'type': 'value'},
51                'series': [{
52                    'data': spark_data,
53                    'type': 'line',
54                    'smooth': True,
55                    'symbol': 'none',
56                    'lineStyle': {'width': 1.5, 'color': hex_color},
57                    'areaStyle': {'opacity': 0.1, 'color': hex_color}
58                }]
59            }).classes('h-8 w-full mt-1')
60        elif subtitle:
61            ui.label(subtitle).classes('text-[8px] font-bold text-slate-400 mt-1 uppercase tracking-tight')
62
63def render_smart_project_card(p):
64    """Deep-info project card for AEC industrial control - COMPACT VERSION."""
65    risk_colors = {'Bajo': 'emerald', 'Medio': 'amber', 'Crítico': 'rose'}
66    rc = risk_colors.get(p.get('nivel_riesgo', 'Bajo'), 'emerald')
67    
68    with ui.card().classes('p-0 rounded-xl border border-slate-100 shadow-sm bg-white overflow-hidden hover:shadow-md transition-all group'):
69        # Status Sidebar (Semaphore)
70        with ui.row().classes('w-full h-1.5').classes(f'bg-{rc}-500'): pass
71        
72        with ui.column().classes('p-3.5 w-full gap-2.5'):
73            # Header
74            with ui.row().classes('w-full justify-between items-start no-wrap'):
75                with ui.column().classes('gap-0 flex-1'):
76                    ui.label(p['nombre']).classes('text-[13px] font-black text-slate-800 line-clamp-1 group-hover:text-primary transition-colors')
77                    ui.label(f"Resp: {p['responsable'] or 'Global'}").classes('text-[8px] font-bold text-slate-400 uppercase tracking-tighter')
78                ui.badge(p['nivel_riesgo'], color=f'{rc}-100').classes(f'text-{rc}-700 text-[8px] font-black px-1.5 rounded py-0.5 h-fit')
79
80            # Progress & KPI
81            with ui.column().classes('w-full gap-1.5'):
82                with ui.row().classes('w-full justify-between items-end text-[9px] font-black text-slate-400'):
83                    ui.label('AVANCE')
84                    ui.label(f"{p['avance']}%")
85                ui.linear_progress(p['avance']/100).classes('w-full h-1 rounded-full bg-slate-50 text-transparent').props(f'color={rc}-600')
86                
87            # SST & Permissions Metadata
88            with ui.row().classes('w-full justify-between items-center mt-1 pt-2 border-t border-slate-50'):
89                with ui.row().classes('gap-2'):
90                    # Permits
91                    with ui.row().classes('items-center gap-1'):
92                        ui.icon('description', size='10px', color='slate-300')
93                        ui.label(str(p.get('permisos_pendientes', 0))).classes('text-[9px] font-black text-slate-600')
94                    # SST Status
95                    with ui.row().classes('items-center gap-1'):
96                        ui.icon('verified_user' if p['estado_sst'] == 'Aprobado' else 'warning', size='10px', color='emerald-400' if p['estado_sst'] == 'Aprobado' else 'amber-500')
97                        ui.label(p['estado_sst']).classes('text-[8px] font-black text-slate-500 uppercase')
98                
99                ui.button(icon='open_in_new').props('flat round size=xs color=slate-300').classes('hover:bg-slate-50 scale-75')
100