05/07 Phase 3: initial codes
This commit is contained in:
@@ -1,10 +1,66 @@
|
||||
{% extends "tenant/layouts/base.html" %}
|
||||
{% block title %}Dashboard{% endblock %}
|
||||
{% block content %}
|
||||
<h4 class="mb-4">Dashboard
|
||||
{% if location %}<small class="text-muted fs-6">— {{ location.name }}</small>{% endif %}
|
||||
</h4>
|
||||
<div class="alert alert-info">
|
||||
Phase 3 KPI widgets will appear here (daily revenue, appointments, staff on-shift, low-stock alerts).
|
||||
<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>
|
||||
{% endblock %}
|
||||
|
||||
<!-- 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 %}
|
||||
Reference in New Issue
Block a user