66 lines
2.9 KiB
HTML
66 lines
2.9 KiB
HTML
{% extends "tenant/layouts/base.html" %}
|
|
{% block title %}Dashboard{% endblock %}
|
|
{% block content %}
|
|
<div class="d-flex justify-content-between align-items-center mb-4">
|
|
<h4 class="fw-bold mb-0">
|
|
<i class="bi bi-speedometer2 me-2"></i>Dashboard
|
|
{% if location %}<small class="text-muted fs-6 ms-2">— {{ location.name }}</small>{% endif %}
|
|
</h4>
|
|
<span class="text-muted small">{{ today.strftime('%A, %B %d, %Y') }}</span>
|
|
</div>
|
|
|
|
<!-- KPI cards -->
|
|
<div class="row g-3 mb-4">
|
|
{% set kpi_items = [
|
|
("Today's Revenue", "$" ~ "%.2f"|format(kpis.today_revenue), "graph-up-arrow", "success"),
|
|
("Appointments", kpis.total_appointments, "calendar3", "primary"),
|
|
("Completed", kpis.completed_appointments, "check-circle", "success"),
|
|
("Pending", kpis.pending_appointments, "hourglass-split", "warning"),
|
|
("Staff on Shift", kpis.staff_on_shift, "person-badge", "info"),
|
|
("Check-in Queue", kpis.queue_count, "door-open", "danger" if kpis.queue_count > 0 else "secondary"),
|
|
] %}
|
|
{% for label, value, icon, color in kpi_items %}
|
|
<div class="col-sm-6 col-lg-4 col-xl-2">
|
|
<div class="card border-0 shadow-sm h-100">
|
|
<div class="card-body d-flex align-items-center gap-3 py-3">
|
|
<div class="rounded-circle bg-{{ color }} bg-opacity-10 p-2">
|
|
<i class="bi bi-{{ icon }} fs-5 text-{{ color }}"></i>
|
|
</div>
|
|
<div>
|
|
<div class="fw-bold fs-5">{{ value }}</div>
|
|
<div class="text-muted" style="font-size:.75rem;">{{ label }}</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
|
|
<!-- Upcoming appointments -->
|
|
<div class="card shadow-sm">
|
|
<div class="card-header fw-semibold d-flex justify-content-between align-items-center">
|
|
<span><i class="bi bi-calendar-check me-2"></i>Upcoming Today</span>
|
|
<a href="{{ url_for('appointments.index') }}" class="btn btn-outline-primary btn-sm">Full Calendar</a>
|
|
</div>
|
|
{% if upcoming_appointments %}
|
|
<div class="table-responsive">
|
|
<table class="table table-hover mb-0">
|
|
<thead class="table-light"><tr><th>Time</th><th>Customer</th><th>Service</th><th>Staff</th><th>Status</th></tr></thead>
|
|
<tbody>
|
|
{% for appt in upcoming_appointments %}
|
|
<tr>
|
|
<td class="fw-semibold">{{ appt.start_time.strftime('%I:%M %p') }}</td>
|
|
<td>{{ appt.customer.name if appt.customer else '—' }}</td>
|
|
<td>{{ appt.service.name if appt.service else '—' }}</td>
|
|
<td>{{ appt.staff.name if appt.staff else '—' }}</td>
|
|
<td><span class="badge bg-{{ {'pending':'warning','confirmed':'primary','in_progress':'info','completed':'success'}.get(appt.status,'secondary') }}">{{ appt.status }}</span></td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
{% else %}
|
|
<div class="card-body text-muted small">No upcoming appointments for today.</div>
|
|
{% endif %}
|
|
</div>
|
|
{% endblock %} |