CoolFace
Apppublic

fmatituy/selectospromanager

sourceHugging Faceupdated 6mo agoView on Hugging Face
0likes
solicitud_permiso.py86 linesDownload Raw Back to personal
1from nicegui import ui2from services.auth import require_auth, get_current_user3from modules.layout import SelectosLayout4from datetime import datetime5 6@ui.page('/personal/solicitud-permiso')7@require_auth8def solicitud_permiso_asistente_page():9    user = get_current_user()10    11    TIPO_PERMISOS = [12        "Permiso por Cita Médica",13        "Calamidad Doméstica",14        "Trámite Administrativo",15        "Licencia por Luto",16        "Licencia de Paternidad/Maternidad",17        "Vacaciones",18        "Otro"19    ]20 21    with SelectosLayout('Solicitud de Permisos'):22        # CONTENEDOR PRINCIPAL MOBILE-FIRST (Estilo Formulario de Avances)23        with ui.column().classes('w-full max-w-xl mx-auto p-4 gap-6 pb-32'):24            25            # Cabecera de la Herramienta26            with ui.row().classes('w-full items-center gap-4 mb-4'):27                with ui.element('div').classes('w-12 h-12 bg-indigo-700 rounded-[1.5rem] flex items-center justify-center shadow-lg shadow-indigo-200'):28                    ui.icon('assignment_ind', color='white', size='24px')29                with ui.column().classes('gap-0'):30                    ui.label('Permisos y Citas').classes('text-2xl font-black text-slate-800 tracking-tight')31                    ui.label('Gestiona tus ausencias y solicitudes legales.').classes('text-xs text-slate-400 font-bold')32 33            # --- FORMULARIO ---34            35            # 1. Motivo del Permiso36            with ui.column().classes('w-full gap-2'):37                ui.label('¿CUÁL ES EL MOTIVO DE TU AUSENCIA?').classes('text-[10px] font-black text-slate-400 tracking-[0.2em] ml-2')38                tipo = ui.select(TIPO_PERMISOS, label='Seleccionar Motivo *').props('outlined rounded-[2rem] h-14 behavior=menu').classes('w-full bg-white shadow-sm')39 40            # 2. Fechas41            with ui.column().classes('w-full bg-slate-50 p-6 rounded-[2.5rem] border border-slate-100 gap-4'):42                ui.label('FECHAS PROGRAMADAS').classes('text-[10px] font-black text-slate-500 tracking-[0.2em] ml-2')43                with ui.row().classes('w-full grid grid-cols-1 sm:grid-cols-2 gap-4'):44                    f_ini = ui.input('Desde (Fecha)', value=datetime.now().strftime('%Y-%m-%d')).props('type=date outlined rounded-2xl bg-white').classes('w-full')45                    f_fin = ui.input('Hasta (Fecha)', value=datetime.now().strftime('%Y-%m-%d')).props('type=date outlined rounded-2xl bg-white').classes('w-full')46 47            # 3. Justificación48            with ui.column().classes('w-full gap-2'):49                ui.label('DETALLES / JUSTIFICACIÓN').classes('text-[10px] font-black text-slate-400 tracking-[0.2em] ml-2')50                detalles = ui.textarea('Describe brevemente la razón de tu solicitud...').props('outlined rounded-[2rem]').classes('w-full bg-white h-32 shadow-sm')51 52            # 4. Soporte53            with ui.column().classes('w-full gap-2'):54                ui.label('SOPORTE O CERTIFICADO (OPCIONAL)').classes('text-[10px] font-black text-slate-400 tracking-[0.2em] ml-2')55                with ui.column().classes('w-full p-6 border-2 border-dashed border-slate-200 rounded-[2rem] items-center gap-2 bg-slate-50/50'):56                    ui.icon('cloud_upload', color='slate-400', size='md')57                    ui.label('Adjuntar archivo o foto del certificado').classes('text-[10px] font-bold text-slate-400 uppercase tracking-widest')58                    ui.button('SUBIR SOPORTE', icon='attach_file').props('flat rounded-xl color=indigo-700').classes('font-black text-xs')59 60            # BOTÓN FIJO EN LA PARTE INFERIOR (Action Bar Mobile Style)61            with ui.row().classes('fixed bottom-0 left-0 right-0 p-6 bg-white/80 backdrop-blur-xl border-t border-slate-100 z-50'):62                def enviar_solicitud():63                    if not tipo.value:64                        return ui.notify('Seleccione el motivo del permiso', type='warning', icon='warning')65                    66                    try:67                        from modules.sst.services_sst_ext import reportar_ausentismo68                        data = {69                            'trabajador_id': user.get('id'),70                            'tipo_permiso': tipo.value,71                            'fecha_inicio': f_ini.value,72                            'fecha_fin': f_fin.value,73                            'detalles': detalles.value,74                            'soporte_path': None, # Por implementar subida real si se requiere75                            'estado': 'Pendiente'76                        }77                        reportar_ausentismo(data)78                        ui.notify('SOLICITUD RADICADA EXITOSAMENTE Y EVALUADA POR SST', type='positive', icon='check_circle')79                        ui.timer(1.2, lambda: ui.navigate.to('/'), once=True)80                    except Exception as e:81                        print(f"Error reportando ausentismo: {e}")82                        ui.notify('Error al radicar solicitud. Contacte a soporte.', type='negative')83 84                ui.button('CANCELAR', on_click=lambda: ui.navigate.to('/')).props('flat rounded-full color=slate-400').classes('flex-1 font-black text-xs h-14')85                ui.button('RADICAR SOLICITUD', icon='send', on_click=enviar_solicitud).props('unelevated color=indigo-900 rounded-[2rem]').classes('flex-[2] font-black h-14 shadow-2xl shadow-indigo-400/20')86