You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
114 lines
5.2 KiB
114 lines
5.2 KiB
from nicegui import ui |
|
from services.api_client import APIClient |
|
import asyncio |
|
from datetime import datetime, date |
|
|
|
class DashboardPage: |
|
def __init__(self, api_client: APIClient): |
|
self.api_client = api_client |
|
self.stats = {} |
|
|
|
def render(self): |
|
"""Render dashboard page""" |
|
ui.label('Dashboard').classes('text-3xl font-bold text-gray-800 mb-6') |
|
|
|
# KPI Cards Row |
|
with ui.row().classes('w-full gap-6 mb-8'): |
|
self._render_kpi_cards() |
|
|
|
# Charts and Tables Row |
|
with ui.row().classes('w-full gap-6'): |
|
with ui.column().classes('flex-1'): |
|
self._render_recent_prenotazioni() |
|
with ui.column().classes('flex-1'): |
|
self._render_pasti_disponibili() |
|
|
|
# Load initial data |
|
asyncio.create_task(self._load_dashboard_data()) |
|
|
|
def _render_kpi_cards(self): |
|
"""Render KPI metric cards""" |
|
# Prenotazioni Oggi |
|
with ui.card().classes('p-6 bg-gradient-to-r from-blue-500 to-blue-600 text-white'): |
|
with ui.column().classes('items-center'): |
|
ui.icon('book_online').classes('text-4xl mb-2') |
|
ui.label('0').classes('text-3xl font-bold').bind_text_from(self, 'prenotazioni_oggi', lambda x: str(x)) |
|
ui.label('Prenotazioni Oggi').classes('text-blue-100') |
|
|
|
# Pasti Serviti |
|
with ui.card().classes('p-6 bg-gradient-to-r from-green-500 to-green-600 text-white'): |
|
with ui.column().classes('items-center'): |
|
ui.icon('restaurant').classes('text-4xl mb-2') |
|
ui.label('0').classes('text-3xl font-bold').bind_text_from(self, 'pasti_serviti', lambda x: str(x)) |
|
ui.label('Pasti Serviti').classes('text-green-100') |
|
|
|
# Pietanze Disponibili |
|
with ui.card().classes('p-6 bg-gradient-to-r from-purple-500 to-purple-600 text-white'): |
|
with ui.column().classes('items-center'): |
|
ui.icon('restaurant_menu').classes('text-4xl mb-2') |
|
ui.label('0').classes('text-3xl font-bold').bind_text_from(self, 'pietanze_disponibili', lambda x: str(x)) |
|
ui.label('Pietanze Disponibili').classes('text-purple-100') |
|
|
|
# Utilizzo Capacità |
|
with ui.card().classes('p-6 bg-gradient-to-r from-orange-500 to-orange-600 text-white'): |
|
with ui.column().classes('items-center'): |
|
ui.icon('analytics').classes('text-4xl mb-2') |
|
ui.label('0%').classes('text-3xl font-bold').bind_text_from(self, 'utilizzo_capacita', lambda x: f"{x}%") |
|
ui.label('Utilizzo Capacità').classes('text-orange-100') |
|
|
|
def _render_recent_prenotazioni(self): |
|
"""Render recent prenotazioni table""" |
|
with ui.card().classes('p-6'): |
|
ui.label('Prenotazioni Recenti').classes('text-xl font-semibold mb-4') |
|
|
|
self.prenotazioni_table = ui.table( |
|
columns=[ |
|
{'name': 'user_id', 'label': 'Utente', 'field': 'user_id'}, |
|
{'name': 'stato', 'label': 'Stato', 'field': 'stato'}, |
|
{'name': 'created_at', 'label': 'Ora', 'field': 'created_at'}, |
|
], |
|
rows=[], |
|
row_key='id' |
|
).classes('w-full') |
|
|
|
def _render_pasti_disponibili(self): |
|
"""Render available pasti""" |
|
with ui.card().classes('p-6'): |
|
ui.label('Pasti Disponibili Oggi').classes('text-xl font-semibold mb-4') |
|
|
|
self.pasti_container = ui.column().classes('space-y-2') |
|
|
|
async def _load_dashboard_data(self): |
|
"""Load dashboard data from API""" |
|
try: |
|
# Mock data for demonstration (replace with actual API calls) |
|
self.prenotazioni_oggi = 25 |
|
self.pasti_serviti = 18 |
|
self.pietanze_disponibili = 12 |
|
self.utilizzo_capacita = 75 |
|
|
|
# Load recent prenotazioni |
|
prenotazioni_data = [ |
|
{'id': 1, 'user_id': 'mario.rossi', 'stato': 'attiva', 'created_at': '10:30'}, |
|
{'id': 2, 'user_id': 'luigi.verdi', 'stato': 'servita', 'created_at': '10:45'}, |
|
{'id': 3, 'user_id': 'anna.bianchi', 'stato': 'attiva', 'created_at': '11:00'}, |
|
] |
|
self.prenotazioni_table.rows = prenotazioni_data |
|
|
|
# Load available pasti |
|
pasti_data = [ |
|
{'nome': 'Pranzo Completo', 'turni': ['12:30', '13:00', '13:30']}, |
|
{'nome': 'Menu Vegetariano', 'turni': ['12:30', '13:00']}, |
|
] |
|
|
|
self.pasti_container.clear() |
|
for pasto in pasti_data: |
|
with self.pasti_container: |
|
with ui.row().classes('w-full justify-between items-center p-3 bg-gray-50 rounded'): |
|
ui.label(pasto['nome']).classes('font-medium') |
|
ui.label(f"Turni: {', '.join(pasto['turni'])}").classes('text-sm text-gray-600') |
|
|
|
ui.update() |
|
|
|
except Exception as e: |
|
ui.notify(f'Errore nel caricamento dati: {str(e)}', type='negative')
|
|
|