dars-framework 1.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- dars/__init__.py +0 -0
- dars/all.py +52 -0
- dars/cli/__init__.py +0 -0
- dars/cli/hot_reload.py +33 -0
- dars/cli/main.py +637 -0
- dars/cli/preview.py +419 -0
- dars/cli/translations.py +389 -0
- dars/components/__init__.py +0 -0
- dars/components/advanced/__init__.py +8 -0
- dars/components/advanced/accordion.py +21 -0
- dars/components/advanced/card.py +28 -0
- dars/components/advanced/modal.py +40 -0
- dars/components/advanced/navbar.py +31 -0
- dars/components/advanced/table.py +24 -0
- dars/components/advanced/tabs.py +26 -0
- dars/components/basic/__init__.py +34 -0
- dars/components/basic/button.py +29 -0
- dars/components/basic/checkbox.py +34 -0
- dars/components/basic/container.py +23 -0
- dars/components/basic/datepicker.py +139 -0
- dars/components/basic/image.py +36 -0
- dars/components/basic/input.py +50 -0
- dars/components/basic/link.py +31 -0
- dars/components/basic/page.py +20 -0
- dars/components/basic/progressbar.py +17 -0
- dars/components/basic/radiobutton.py +34 -0
- dars/components/basic/select.py +81 -0
- dars/components/basic/slider.py +63 -0
- dars/components/basic/spinner.py +11 -0
- dars/components/basic/text.py +22 -0
- dars/components/basic/textarea.py +46 -0
- dars/components/basic/tooltip.py +18 -0
- dars/components/layout/__init__.py +0 -0
- dars/components/layout/anchor.py +13 -0
- dars/components/layout/flex.py +26 -0
- dars/components/layout/grid.py +45 -0
- dars/core/__init__.py +0 -0
- dars/core/app.py +630 -0
- dars/core/component.py +25 -0
- dars/core/events.py +101 -0
- dars/core/properties.py +127 -0
- dars/docs/__init__.py +0 -0
- dars/exporters/__init__.py +0 -0
- dars/exporters/base.py +69 -0
- dars/exporters/web/__init__.py +0 -0
- dars/exporters/web/html_css_js.py +1406 -0
- dars/scripts/__init__.py +0 -0
- dars/scripts/script.py +38 -0
- dars/templates/__init__.py +0 -0
- dars/templates/examples/advanced/all_components_demo.py +87 -0
- dars/templates/examples/advanced/dashboard.py +440 -0
- dars/templates/examples/advanced/modern_web_app.py +452 -0
- dars/templates/examples/basic/flex_layout_responsive.py +13 -0
- dars/templates/examples/basic/form_components.py +516 -0
- dars/templates/examples/basic/grid_layout_responsive.py +13 -0
- dars/templates/examples/basic/hello_world.py +104 -0
- dars/templates/examples/basic/layout_multipage_demo.py +23 -0
- dars/templates/examples/basic/multipage_example.py +70 -0
- dars/templates/examples/basic/pwa_custom_icons.py +31 -0
- dars/templates/examples/basic/simple_form.py +377 -0
- dars/templates/examples/demo/complete_app.py +720 -0
- dars/templates/html/__init__.py +0 -0
- dars_framework-1.0.0.dist-info/METADATA +146 -0
- dars_framework-1.0.0.dist-info/RECORD +68 -0
- dars_framework-1.0.0.dist-info/WHEEL +5 -0
- dars_framework-1.0.0.dist-info/entry_points.txt +2 -0
- dars_framework-1.0.0.dist-info/licenses/LICENSE +21 -0
- dars_framework-1.0.0.dist-info/top_level.txt +1 -0
dars/scripts/__init__.py
ADDED
|
File without changes
|
dars/scripts/script.py
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
from abc import ABC, abstractmethod
|
|
2
|
+
from typing import Optional
|
|
3
|
+
|
|
4
|
+
class Script(ABC):
|
|
5
|
+
"""Clase base para la definición de scripts"""
|
|
6
|
+
def __init__(self, target_language: str = "javascript"):
|
|
7
|
+
if target_language not in ["javascript", "typescript"]:
|
|
8
|
+
raise ValueError("El lenguaje objetivo debe ser 'javascript' o 'typescript'")
|
|
9
|
+
self.target_language = target_language
|
|
10
|
+
|
|
11
|
+
@abstractmethod
|
|
12
|
+
def get_code(self) -> str:
|
|
13
|
+
"""Retorna el código del script en el lenguaje objetivo"""
|
|
14
|
+
pass
|
|
15
|
+
|
|
16
|
+
class InlineScript(Script):
|
|
17
|
+
"""Script definido directamente en el código Python"""
|
|
18
|
+
def __init__(self, code: str, target_language: str = "javascript"):
|
|
19
|
+
super().__init__(target_language)
|
|
20
|
+
self.code = code
|
|
21
|
+
|
|
22
|
+
def get_code(self) -> str:
|
|
23
|
+
return self.code
|
|
24
|
+
|
|
25
|
+
class FileScript(Script):
|
|
26
|
+
"""Script cargado desde un archivo externo"""
|
|
27
|
+
def __init__(self, file_path: str, target_language: str = "javascript"):
|
|
28
|
+
super().__init__(target_language)
|
|
29
|
+
self.file_path = file_path
|
|
30
|
+
|
|
31
|
+
def get_code(self) -> str:
|
|
32
|
+
try:
|
|
33
|
+
with open(self.file_path, 'r') as f:
|
|
34
|
+
return f.read()
|
|
35
|
+
except FileNotFoundError:
|
|
36
|
+
raise FileNotFoundError(f"El archivo de script no se encontró: {self.file_path}")
|
|
37
|
+
|
|
38
|
+
|
|
File without changes
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Plantilla: Todos los Componentes Dars - Básicos y Avanzados
|
|
4
|
+
Demuestra el uso completo e integrado de todos los componentes básicos y avanzados:
|
|
5
|
+
Text, Button, Input, Container, Image, Link, Textarea, Checkbox, RadioButton, Select, Slider, DatePicker,
|
|
6
|
+
Table, Tabs, Accordion, ProgressBar, Spinner, Tooltip
|
|
7
|
+
|
|
8
|
+
Uso:
|
|
9
|
+
dars init mi_proyecto -t advanced/all_components_demo
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
from dars.core.app import App
|
|
13
|
+
from dars.components.basic.container import Container
|
|
14
|
+
from dars.components.basic.text import Text
|
|
15
|
+
from dars.components.basic.button import Button
|
|
16
|
+
from dars.components.basic.input import Input
|
|
17
|
+
from dars.components.basic.image import Image
|
|
18
|
+
from dars.components.basic.link import Link
|
|
19
|
+
from dars.components.basic.textarea import Textarea
|
|
20
|
+
from dars.components.basic.checkbox import Checkbox
|
|
21
|
+
from dars.components.basic.radiobutton import RadioButton
|
|
22
|
+
from dars.components.basic.select import Select, SelectOption
|
|
23
|
+
from dars.components.basic.slider import Slider
|
|
24
|
+
from dars.components.basic.datepicker import DatePicker
|
|
25
|
+
from dars.components.advanced.table import Table
|
|
26
|
+
from dars.components.advanced.tabs import Tabs
|
|
27
|
+
from dars.components.advanced.accordion import Accordion
|
|
28
|
+
from dars.components.basic.progressbar import ProgressBar
|
|
29
|
+
from dars.components.basic.spinner import Spinner
|
|
30
|
+
from dars.components.basic.tooltip import Tooltip
|
|
31
|
+
|
|
32
|
+
# App principal
|
|
33
|
+
app = App(title="Dars - Todos los Componentes Básicos y Avanzados")
|
|
34
|
+
|
|
35
|
+
main = Container(style={
|
|
36
|
+
'max-width': '900px',
|
|
37
|
+
'margin': '40px auto',
|
|
38
|
+
'padding': '32px',
|
|
39
|
+
'background': 'white',
|
|
40
|
+
'border-radius': '12px',
|
|
41
|
+
'box-shadow': '0 2px 12px rgba(0,0,0,0.08)'
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
main.children += [
|
|
45
|
+
Text("Demostración de TODOS los componentes de Dars", style={"font-size": "2rem", "font-weight": "bold", "margin-bottom": "24px"}),
|
|
46
|
+
# Básicos
|
|
47
|
+
Text("Componentes Básicos", style={"font-size": "1.3rem", "margin": "24px 0 12px 0", "color": "#007bff"}),
|
|
48
|
+
Text("Texto de ejemplo", style={"margin-bottom": "8px"}),
|
|
49
|
+
Button("Botón primario"),
|
|
50
|
+
Input(placeholder="Campo de texto"),
|
|
51
|
+
Image(src="https://via.placeholder.com/120x60.png?text=Logo", alt="Logo Demo", style={"margin": "10px 0"}),
|
|
52
|
+
Link("Ir a Dars Framework", href="https://github.com/zondahuman/Dars-Framework", target="_blank"),
|
|
53
|
+
Textarea(value="Texto multilinea de ejemplo", rows=3),
|
|
54
|
+
Checkbox(label="Acepto términos y condiciones", checked=True),
|
|
55
|
+
RadioButton(label="Opción A", name="grupo1", checked=True),
|
|
56
|
+
RadioButton(label="Opción B", name="grupo1"),
|
|
57
|
+
Select(options=[SelectOption("uno", "Uno"), SelectOption("dos", "Dos")], value="uno", placeholder="Selecciona una opción"),
|
|
58
|
+
Slider(min_value=0, max_value=100, value=50, label="Volumen", show_value=True),
|
|
59
|
+
DatePicker(value="2025-08-06"),
|
|
60
|
+
# Avanzados
|
|
61
|
+
Text("Componentes Avanzados", style={"font-size": "1.3rem", "margin": "32px 0 12px 0", "color": "#4a90e2"}),
|
|
62
|
+
Table(
|
|
63
|
+
columns=[{"title": "Nombre", "field": "nombre"}, {"title": "Edad", "field": "edad"}],
|
|
64
|
+
data=[{"nombre": "Ana", "edad": 28}, {"nombre": "Luis", "edad": 34}],
|
|
65
|
+
page_size=10
|
|
66
|
+
),
|
|
67
|
+
Tabs(
|
|
68
|
+
tabs=["Tab 1", "Tab 2"],
|
|
69
|
+
panels=[Text("Contenido de la pestaña 1"), Text("Contenido de la pestaña 2")],
|
|
70
|
+
selected=0
|
|
71
|
+
),
|
|
72
|
+
Accordion(
|
|
73
|
+
sections=[
|
|
74
|
+
("Sección 1", Text("Contenido de la sección 1")),
|
|
75
|
+
("Sección 2", Text("Contenido de la sección 2"))
|
|
76
|
+
],
|
|
77
|
+
open_indices=[0]
|
|
78
|
+
),
|
|
79
|
+
ProgressBar(value=70, max_value=100),
|
|
80
|
+
Spinner(),
|
|
81
|
+
Tooltip(child=Button("Pasa el mouse"), text="¡Tooltip de ejemplo!", position="top")
|
|
82
|
+
]
|
|
83
|
+
|
|
84
|
+
app.root = main
|
|
85
|
+
|
|
86
|
+
if __name__ == "__main__":
|
|
87
|
+
app.rTimeCompile()
|
|
@@ -0,0 +1,440 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Dars - Ejemplo Avanzado: Dashboard
|
|
4
|
+
Demuestra layouts complejos, múltiples componentes y funcionalidad avanzada
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import sys
|
|
8
|
+
import os
|
|
9
|
+
|
|
10
|
+
from dars.core.app import App
|
|
11
|
+
from dars.components.basic.text import Text
|
|
12
|
+
from dars.components.basic.button import Button
|
|
13
|
+
from dars.components.basic.input import Input
|
|
14
|
+
from dars.components.basic.container import Container
|
|
15
|
+
from dars.scripts.script import InlineScript
|
|
16
|
+
|
|
17
|
+
# Crear la aplicación
|
|
18
|
+
app = App(title="Dashboard Empresarial - Dars")
|
|
19
|
+
|
|
20
|
+
# Contenedor principal
|
|
21
|
+
main_container = Container(
|
|
22
|
+
style={
|
|
23
|
+
'display': 'flex',
|
|
24
|
+
'min-height': '100vh',
|
|
25
|
+
'background-color': '#f8f9fa',
|
|
26
|
+
'font-family': 'Arial, sans-serif'
|
|
27
|
+
}
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
# Sidebar
|
|
31
|
+
sidebar = Container(
|
|
32
|
+
id="sidebar",
|
|
33
|
+
style={
|
|
34
|
+
'width': '250px',
|
|
35
|
+
'background-color': '#2c3e50',
|
|
36
|
+
'color': 'white',
|
|
37
|
+
'padding': '20px',
|
|
38
|
+
'box-shadow': '2px 0 5px rgba(0,0,0,0.1)'
|
|
39
|
+
}
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
# Logo/Título del sidebar
|
|
43
|
+
logo = Text(
|
|
44
|
+
text="📊 Dashboard",
|
|
45
|
+
style={
|
|
46
|
+
'font-size': '24px',
|
|
47
|
+
'font-weight': 'bold',
|
|
48
|
+
'margin-bottom': '30px',
|
|
49
|
+
'text-align': 'center',
|
|
50
|
+
'color': '#ecf0f1'
|
|
51
|
+
}
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
# Menú de navegación
|
|
55
|
+
menu_items = [
|
|
56
|
+
("🏠 Inicio", "inicio"),
|
|
57
|
+
("📈 Ventas", "ventas"),
|
|
58
|
+
("👥 Usuarios", "usuarios"),
|
|
59
|
+
("⚙️ Configuración", "config")
|
|
60
|
+
]
|
|
61
|
+
|
|
62
|
+
menu_container = Container(style={'margin-bottom': '30px'})
|
|
63
|
+
|
|
64
|
+
for texto, id_item in menu_items:
|
|
65
|
+
menu_item = Button(
|
|
66
|
+
id=f"menu-{id_item}",
|
|
67
|
+
text=texto,
|
|
68
|
+
style={
|
|
69
|
+
'width': '100%',
|
|
70
|
+
'background-color': 'transparent',
|
|
71
|
+
'color': '#ecf0f1',
|
|
72
|
+
'border': 'none',
|
|
73
|
+
'padding': '12px 16px',
|
|
74
|
+
'text-align': 'left',
|
|
75
|
+
'cursor': 'pointer',
|
|
76
|
+
'border-radius': '6px',
|
|
77
|
+
'margin-bottom': '8px',
|
|
78
|
+
'font-size': '16px'
|
|
79
|
+
}
|
|
80
|
+
)
|
|
81
|
+
menu_container.add_child(menu_item)
|
|
82
|
+
|
|
83
|
+
# Área de contenido principal
|
|
84
|
+
content_area = Container(
|
|
85
|
+
id="content-area",
|
|
86
|
+
style={
|
|
87
|
+
'flex': '1',
|
|
88
|
+
'padding': '30px',
|
|
89
|
+
'overflow-y': 'auto'
|
|
90
|
+
}
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
# Header del contenido
|
|
94
|
+
header = Container(
|
|
95
|
+
style={
|
|
96
|
+
'display': 'flex',
|
|
97
|
+
'justify-content': 'space-between',
|
|
98
|
+
'align-items': 'center',
|
|
99
|
+
'margin-bottom': '30px',
|
|
100
|
+
'padding-bottom': '20px',
|
|
101
|
+
'border-bottom': '2px solid #dee2e6'
|
|
102
|
+
}
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
titulo_pagina = Text(
|
|
106
|
+
id="titulo-pagina",
|
|
107
|
+
text="Panel de Control",
|
|
108
|
+
style={
|
|
109
|
+
'font-size': '32px',
|
|
110
|
+
'color': '#2c3e50',
|
|
111
|
+
'font-weight': 'bold'
|
|
112
|
+
}
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
usuario_info = Text(
|
|
116
|
+
text="👤 Admin Usuario",
|
|
117
|
+
style={
|
|
118
|
+
'font-size': '16px',
|
|
119
|
+
'color': '#6c757d'
|
|
120
|
+
}
|
|
121
|
+
)
|
|
122
|
+
|
|
123
|
+
# Tarjetas de estadísticas
|
|
124
|
+
stats_container = Container(
|
|
125
|
+
id="stats-container",
|
|
126
|
+
style={
|
|
127
|
+
'display': 'grid',
|
|
128
|
+
'grid-template-columns': 'repeat(auto-fit, minmax(250px, 1fr))',
|
|
129
|
+
'gap': '20px',
|
|
130
|
+
'margin-bottom': '30px'
|
|
131
|
+
}
|
|
132
|
+
)
|
|
133
|
+
|
|
134
|
+
# Función para crear tarjetas de estadísticas
|
|
135
|
+
def crear_stat_card(titulo, valor, icono, color):
|
|
136
|
+
card = Container(
|
|
137
|
+
style={
|
|
138
|
+
'background-color': 'white',
|
|
139
|
+
'padding': '24px',
|
|
140
|
+
'border-radius': '12px',
|
|
141
|
+
'box-shadow': '0 2px 10px rgba(0,0,0,0.1)',
|
|
142
|
+
'border-left': f'4px solid {color}'
|
|
143
|
+
}
|
|
144
|
+
)
|
|
145
|
+
|
|
146
|
+
card_header = Container(
|
|
147
|
+
style={
|
|
148
|
+
'display': 'flex',
|
|
149
|
+
'justify-content': 'space-between',
|
|
150
|
+
'align-items': 'center',
|
|
151
|
+
'margin-bottom': '10px'
|
|
152
|
+
}
|
|
153
|
+
)
|
|
154
|
+
|
|
155
|
+
card_title = Text(
|
|
156
|
+
text=titulo,
|
|
157
|
+
style={
|
|
158
|
+
'font-size': '14px',
|
|
159
|
+
'color': '#6c757d',
|
|
160
|
+
'font-weight': '500'
|
|
161
|
+
}
|
|
162
|
+
)
|
|
163
|
+
|
|
164
|
+
card_icon = Text(
|
|
165
|
+
text=icono,
|
|
166
|
+
style={
|
|
167
|
+
'font-size': '24px'
|
|
168
|
+
}
|
|
169
|
+
)
|
|
170
|
+
|
|
171
|
+
card_value = Text(
|
|
172
|
+
text=valor,
|
|
173
|
+
style={
|
|
174
|
+
'font-size': '28px',
|
|
175
|
+
'color': '#2c3e50',
|
|
176
|
+
'font-weight': 'bold'
|
|
177
|
+
}
|
|
178
|
+
)
|
|
179
|
+
|
|
180
|
+
card_header.add_child(card_title)
|
|
181
|
+
card_header.add_child(card_icon)
|
|
182
|
+
card.add_child(card_header)
|
|
183
|
+
card.add_child(card_value)
|
|
184
|
+
|
|
185
|
+
return card
|
|
186
|
+
|
|
187
|
+
# Crear tarjetas de estadísticas
|
|
188
|
+
stats_data = [
|
|
189
|
+
("Ventas Totales", "$125,430", "💰", "#28a745"),
|
|
190
|
+
("Usuarios Activos", "1,234", "👥", "#007bff"),
|
|
191
|
+
("Pedidos Hoy", "89", "📦", "#ffc107"),
|
|
192
|
+
("Ingresos Mes", "$45,210", "📈", "#dc3545")
|
|
193
|
+
]
|
|
194
|
+
|
|
195
|
+
for titulo, valor, icono, color in stats_data:
|
|
196
|
+
stats_container.add_child(crear_stat_card(titulo, valor, icono, color))
|
|
197
|
+
|
|
198
|
+
# Área de contenido dinámico
|
|
199
|
+
dynamic_content = Container(
|
|
200
|
+
id="dynamic-content",
|
|
201
|
+
style={
|
|
202
|
+
'background-color': 'white',
|
|
203
|
+
'padding': '30px',
|
|
204
|
+
'border-radius': '12px',
|
|
205
|
+
'box-shadow': '0 2px 10px rgba(0,0,0,0.1)'
|
|
206
|
+
}
|
|
207
|
+
)
|
|
208
|
+
|
|
209
|
+
# Contenido inicial
|
|
210
|
+
contenido_inicial = Text(
|
|
211
|
+
id="contenido-texto",
|
|
212
|
+
text="Bienvenido al Dashboard. Selecciona una opción del menú para ver más información.",
|
|
213
|
+
style={
|
|
214
|
+
'font-size': '18px',
|
|
215
|
+
'color': '#6c757d',
|
|
216
|
+
'text-align': 'center',
|
|
217
|
+
'line-height': '1.6'
|
|
218
|
+
}
|
|
219
|
+
)
|
|
220
|
+
|
|
221
|
+
# Script para funcionalidad del dashboard
|
|
222
|
+
script = InlineScript("""
|
|
223
|
+
// Estado de la aplicación
|
|
224
|
+
let currentPage = 'inicio';
|
|
225
|
+
|
|
226
|
+
// Contenido de las páginas
|
|
227
|
+
const pageContent = {
|
|
228
|
+
inicio: {
|
|
229
|
+
titulo: 'Panel de Control',
|
|
230
|
+
contenido: 'Bienvenido al Dashboard. Aquí puedes ver un resumen de todas las métricas importantes de tu negocio.'
|
|
231
|
+
},
|
|
232
|
+
ventas: {
|
|
233
|
+
titulo: 'Gestión de Ventas',
|
|
234
|
+
contenido: 'Aquí puedes ver todas las ventas realizadas, generar reportes y analizar tendencias de ventas.'
|
|
235
|
+
},
|
|
236
|
+
usuarios: {
|
|
237
|
+
titulo: 'Gestión de Usuarios',
|
|
238
|
+
contenido: 'Administra los usuarios del sistema, sus permisos y actividad reciente.'
|
|
239
|
+
},
|
|
240
|
+
config: {
|
|
241
|
+
titulo: 'Configuración',
|
|
242
|
+
contenido: 'Configura los parámetros del sistema, notificaciones y preferencias generales.'
|
|
243
|
+
}
|
|
244
|
+
};
|
|
245
|
+
|
|
246
|
+
// Función para cambiar de página
|
|
247
|
+
function cambiarPagina(pagina) {
|
|
248
|
+
if (currentPage === pagina) return;
|
|
249
|
+
|
|
250
|
+
currentPage = pagina;
|
|
251
|
+
|
|
252
|
+
// Actualizar título
|
|
253
|
+
const titulo = document.getElementById('titulo-pagina');
|
|
254
|
+
if (titulo) {
|
|
255
|
+
titulo.textContent = pageContent[pagina].titulo;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// Actualizar contenido
|
|
259
|
+
const contenido = document.getElementById('contenido-texto');
|
|
260
|
+
if (contenido) {
|
|
261
|
+
contenido.textContent = pageContent[pagina].contenido;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
// Actualizar estilos del menú
|
|
265
|
+
actualizarMenuActivo(pagina);
|
|
266
|
+
|
|
267
|
+
// Animación de entrada
|
|
268
|
+
const dynamicContent = document.getElementById('dynamic-content');
|
|
269
|
+
if (dynamicContent) {
|
|
270
|
+
dynamicContent.style.opacity = '0';
|
|
271
|
+
setTimeout(() => {
|
|
272
|
+
dynamicContent.style.opacity = '1';
|
|
273
|
+
}, 150);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
// Actualizar elemento activo del menú
|
|
278
|
+
function actualizarMenuActivo(paginaActiva) {
|
|
279
|
+
const menuItems = ['inicio', 'ventas', 'usuarios', 'config'];
|
|
280
|
+
|
|
281
|
+
menuItems.forEach(item => {
|
|
282
|
+
const elemento = document.getElementById(`menu-${item}`);
|
|
283
|
+
if (elemento) {
|
|
284
|
+
if (item === paginaActiva) {
|
|
285
|
+
elemento.style.backgroundColor = '#34495e';
|
|
286
|
+
elemento.style.color = '#3498db';
|
|
287
|
+
} else {
|
|
288
|
+
elemento.style.backgroundColor = 'transparent';
|
|
289
|
+
elemento.style.color = '#ecf0f1';
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
// Animación de las tarjetas de estadísticas
|
|
296
|
+
function animarEstadisticas() {
|
|
297
|
+
const statsContainer = document.getElementById('stats-container');
|
|
298
|
+
if (!statsContainer) return;
|
|
299
|
+
|
|
300
|
+
const cards = statsContainer.children;
|
|
301
|
+
|
|
302
|
+
Array.from(cards).forEach((card, index) => {
|
|
303
|
+
card.style.opacity = '0';
|
|
304
|
+
card.style.transform = 'translateY(20px)';
|
|
305
|
+
|
|
306
|
+
setTimeout(() => {
|
|
307
|
+
card.style.transition = 'all 0.5s ease';
|
|
308
|
+
card.style.opacity = '1';
|
|
309
|
+
card.style.transform = 'translateY(0)';
|
|
310
|
+
}, index * 100);
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
// Efecto de hover en las tarjetas
|
|
315
|
+
function configurarEfectosHover() {
|
|
316
|
+
const statsContainer = document.getElementById('stats-container');
|
|
317
|
+
if (!statsContainer) return;
|
|
318
|
+
|
|
319
|
+
const cards = statsContainer.children;
|
|
320
|
+
|
|
321
|
+
Array.from(cards).forEach(card => {
|
|
322
|
+
card.addEventListener('mouseenter', function() {
|
|
323
|
+
this.style.transform = 'translateY(-5px)';
|
|
324
|
+
this.style.boxShadow = '0 4px 20px rgba(0,0,0,0.15)';
|
|
325
|
+
this.style.transition = 'all 0.3s ease';
|
|
326
|
+
});
|
|
327
|
+
|
|
328
|
+
card.addEventListener('mouseleave', function() {
|
|
329
|
+
this.style.transform = 'translateY(0)';
|
|
330
|
+
this.style.boxShadow = '0 2px 10px rgba(0,0,0,0.1)';
|
|
331
|
+
});
|
|
332
|
+
});
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
// Simulación de datos en tiempo real
|
|
336
|
+
function actualizarDatosEnTiempoReal() {
|
|
337
|
+
const valores = [
|
|
338
|
+
{ selector: 'Ventas Totales', base: 125430, variacion: 1000 },
|
|
339
|
+
{ selector: 'Usuarios Activos', base: 1234, variacion: 10 },
|
|
340
|
+
{ selector: 'Pedidos Hoy', base: 89, variacion: 5 },
|
|
341
|
+
{ selector: 'Ingresos Mes', base: 45210, variacion: 500 }
|
|
342
|
+
];
|
|
343
|
+
|
|
344
|
+
valores.forEach(item => {
|
|
345
|
+
const elementos = Array.from(document.querySelectorAll('span')).filter(el =>
|
|
346
|
+
el.parentElement && el.parentElement.textContent.includes(item.selector)
|
|
347
|
+
);
|
|
348
|
+
|
|
349
|
+
if (elementos.length > 0) {
|
|
350
|
+
const elemento = elementos[elementos.length - 1]; // Último elemento (el valor)
|
|
351
|
+
const variacion = Math.floor(Math.random() * item.variacion * 2) - item.variacion;
|
|
352
|
+
const nuevoValor = item.base + variacion;
|
|
353
|
+
|
|
354
|
+
if (item.selector.includes('$')) {
|
|
355
|
+
elemento.textContent = `$${nuevoValor.toLocaleString()}`;
|
|
356
|
+
} else {
|
|
357
|
+
elemento.textContent = nuevoValor.toLocaleString();
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
});
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
// Configurar sidebar responsive
|
|
364
|
+
function configurarSidebarResponsive() {
|
|
365
|
+
const sidebar = document.getElementById('sidebar');
|
|
366
|
+
const contentArea = document.getElementById('content-area');
|
|
367
|
+
|
|
368
|
+
function checkScreenSize() {
|
|
369
|
+
if (window.innerWidth < 768) {
|
|
370
|
+
sidebar.style.position = 'fixed';
|
|
371
|
+
sidebar.style.left = '-250px';
|
|
372
|
+
sidebar.style.zIndex = '1000';
|
|
373
|
+
sidebar.style.transition = 'left 0.3s ease';
|
|
374
|
+
contentArea.style.marginLeft = '0';
|
|
375
|
+
} else {
|
|
376
|
+
sidebar.style.position = 'static';
|
|
377
|
+
sidebar.style.left = '0';
|
|
378
|
+
contentArea.style.marginLeft = '0';
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
window.addEventListener('resize', checkScreenSize);
|
|
383
|
+
checkScreenSize();
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
// Inicialización
|
|
387
|
+
document.addEventListener('DOMContentLoaded', function() {
|
|
388
|
+
// Configurar eventos del menú
|
|
389
|
+
const menuItems = ['inicio', 'ventas', 'usuarios', 'config'];
|
|
390
|
+
menuItems.forEach(item => {
|
|
391
|
+
const elemento = document.getElementById(`menu-${item}`);
|
|
392
|
+
if (elemento) {
|
|
393
|
+
elemento.addEventListener('click', () => cambiarPagina(item));
|
|
394
|
+
}
|
|
395
|
+
});
|
|
396
|
+
|
|
397
|
+
// Configurar página inicial
|
|
398
|
+
cambiarPagina('inicio');
|
|
399
|
+
|
|
400
|
+
// Configurar animaciones y efectos
|
|
401
|
+
setTimeout(() => {
|
|
402
|
+
animarEstadisticas();
|
|
403
|
+
configurarEfectosHover();
|
|
404
|
+
}, 100);
|
|
405
|
+
|
|
406
|
+
// Configurar responsive
|
|
407
|
+
configurarSidebarResponsive();
|
|
408
|
+
|
|
409
|
+
// Actualizar datos cada 30 segundos
|
|
410
|
+
setInterval(actualizarDatosEnTiempoReal, 30000);
|
|
411
|
+
|
|
412
|
+
console.log('Dashboard Dars cargado correctamente');
|
|
413
|
+
});
|
|
414
|
+
""")
|
|
415
|
+
|
|
416
|
+
# Ensamblar la aplicación
|
|
417
|
+
sidebar.add_child(logo)
|
|
418
|
+
sidebar.add_child(menu_container)
|
|
419
|
+
|
|
420
|
+
header.add_child(titulo_pagina)
|
|
421
|
+
header.add_child(usuario_info)
|
|
422
|
+
|
|
423
|
+
dynamic_content.add_child(contenido_inicial)
|
|
424
|
+
|
|
425
|
+
content_area.add_child(header)
|
|
426
|
+
content_area.add_child(stats_container)
|
|
427
|
+
content_area.add_child(dynamic_content)
|
|
428
|
+
|
|
429
|
+
main_container.add_child(sidebar)
|
|
430
|
+
main_container.add_child(content_area)
|
|
431
|
+
|
|
432
|
+
app.set_root(main_container)
|
|
433
|
+
app.add_script(script)
|
|
434
|
+
|
|
435
|
+
# Para exportar esta aplicación, ejecuta:
|
|
436
|
+
# ./dars_exporter export examples/advanced/dashboard.py --format html --output ./dashboard_output
|
|
437
|
+
|
|
438
|
+
if __name__ == "__main__":
|
|
439
|
+
app.rTimeCompile() # Preview/compilación rápida
|
|
440
|
+
|