fmatituy/selectospromanager
0
1from nicegui import ui, app
2
3class OnboardingTutorial:
4 """
5 Sistema de Onboarding para presentar las funcionalidades del ERP.
6 """
7
8 def __init__(self):
9 self.steps = [
10 {
11 'title': 'PROMANAGER 2026',
12 'subtitle': 'EL FUTURO DE LA INGENIERÍA',
13 'icon': 'rocket_launch',
14 'color': '#1e40af',
15 'text': 'Has ingresado al ecosistema digital más potente para el control de proyectos y SST. Diseñado para la eficiencia total.'
16 },
17 {
18 'title': 'SARA IA',
19 'subtitle': 'TU ASISTENTE INTELIGENTE',
20 'icon': 'psychology',
21 'color': '#7c3aed',
22 'text': 'Redacción de permisos, validación de certificados y detección de riesgos en segundos. La IA al servicio de tu seguridad.'
23 },
24 ]
25 self.current_step = 0
26
27 def show(self):
28 if app.storage.user.get('tutorial_seen', False):
29 return
30
31 with ui.dialog() as self.dialog, ui.card().classes('w-[500px] p-0 rounded-[3rem] overflow-hidden shadow-2xl bg-white border-none'):
32 self.dialog.props('persistent transition-show=jump-up transition-hide=jump-down')
33 self.content_container = ui.column().classes('w-full items-center text-center')
34 self._render_step()
35 self.dialog.open()
36
37 def _render_step(self):
38 step = self.steps[self.current_step]
39 self.content_container.clear()
40
41 with self.content_container:
42 # Hero Section con Gradiente y Glassmorphism
43 with ui.element('div').classes('w-full h-64 flex items-center justify-center relative').style(f'background: linear-gradient(135deg, {step["color"]}, {step["color"]}cc)'):
44 ui.element('div').classes('absolute inset-0 opacity-20').style('background-image: radial-gradient(#ffffff 1px, transparent 1px); background-size: 20px 20px;')
45
46 with ui.element('div').classes('p-8 rounded-[2rem] bg-white/20 backdrop-blur-xl border border-white/30 shadow-2xl animate-bounce'):
47 ui.icon(step['icon'], size='80px', color='white')
48
49 # Contenido
50 with ui.column().classes('p-10 w-full gap-2'):
51 ui.label(step['subtitle']).classes('text-[10px] font-black tracking-[0.4em] mb-2 uppercase opacity-60').style(f'color: {step["color"]}')
52 ui.label(step['title']).classes('text-4xl font-black text-slate-800 tracking-tighter mb-4')
53 ui.label(step['text']).classes('text-slate-500 text-sm font-medium leading-relaxed px-6 mb-8')
54
55 # Indicadores
56 with ui.row().classes('w-full justify-center gap-1.5 mb-8'):
57 for i in range(len(self.steps)):
58 active = i == self.current_step
59 ui.element('div').classes('h-1 rounded-full transition-all duration-500').style(f'width: {"40px" if active else "8px"}; background: {step["color"] if active else "#e2e8f0"}')
60
61 # Botón Primario
62 with ui.row().classes('w-full items-center justify-center'):
63 if self.current_step < len(self.steps) - 1:
64 btn = ui.button('SIGUIENTE PASO', icon='arrow_forward', on_click=self._next_step)
65 btn.props('unelevated rounded-2xl h-16').classes('w-full font-black tracking-widest text-sm').style(f'background: {step["color"]}; color: white; box-shadow: 0 15px 30px -10px {step["color"]}66')
66 else:
67 btn = ui.button('¡COMENZAR AHORA!', icon='check_circle', on_click=lambda: (app.storage.user.update(tutorial_seen=True), self.dialog.close()))
68 btn.props('unelevated rounded-2xl h-16 color=emerald-600').classes('w-full font-black tracking-widest text-sm shadow-xl shadow-emerald-100')
69
70 if self.current_step == 0:
71 ui.button('SALTAR TUTORIAL', on_click=lambda: (app.storage.user.update(tutorial_seen=True), self.dialog.close())).props('flat color=slate-400 no-caps').classes('mt-4 text-xs font-bold')
72
73 def _next_step(self):
74 self.current_step += 1
75 self._render_step()
76
77def start_onboarding():
78 tutorial = OnboardingTutorial()
79 tutorial.show()
80 