{% extends "base.html" %} {% block content %}

Dashboard

Overview of today's activity, current sessions, and system health.

Sales Today
₱{{ data.sales_today_pesos }}
{{ data.sales_today_count }} voucher{{ '' if data.sales_today_count == 1 else 's' }}
Lifetime
₱{{ data.sales_lifetime_pesos }}
{{ data.sales_lifetime_count }} voucher{{ '' if data.sales_lifetime_count == 1 else 's' }} total
Active
{{ data.active_sessions }}
{{ data.paused_sessions }} paused
Uptime
{{ data.system.uptime }}
since last boot

Sales figures show this server vendo only — each ESP sub-vendo reports its own sales directly to vendorawifi.com.

Network

Connected customers and your sub-vendo fleet.

{% if data.wan_collision and data.wan_collision.collision %}
⚠ Your internet (WAN) is on the same IP range as your customer network ({{ data.wan_collision.wan_subnet }}) — nobody can reach the internet. Change LAN subnet →
{% endif %}
Connected customers
—
currently authorized on the AP
Sub-vendos
{{ data.sub_vendo_count }}
{% if data.sub_vendo_count %}ESP VLANs · view fleet{% else %}none configured{% endif %}

WAN Throughput

Live upstream usage. Updates every 3 seconds.

Download
— Mbps
of — Mbps WAN cap
Upload
— Mbps
of — Mbps WAN cap
{# Traffic history — rolling WAN usage from the tiered ring buffers in common/traffic_history.py. The range picker selects a resolution tier, so a 7-day view is 168 points, not thousands: the chart stays light on the SBC and light in the browser. #}

Traffic History

Upstream usage over time. Kept for 7 days.

Megabits per second
Download — Upload —
{# System Health — ring gauges (CPU / Memory / Disk) + a live per-core CPU equalizer. A single pegged core, which the CPU average hides, stands out in red on the equalizer. All three rings + the equalizer animate on the 5s /api/network-status poll. Styles scoped to this section. #}

System Health

CPU{% if data.system.cpu_cores %} · {{ data.system.cpu_cores | length }} cores{% endif %}
{{ data.system.cpu_used_pct }}% {% if data.system.cpu_temp_c is not none %}{{ data.system.cpu_temp_c }}°C{% else %}usage{% endif %}
{% for c in data.system.cpu_cores %}
= 90 %} style="color:var(--danger);font-weight:700;"{% endif %}>{{ c }}%
C{{ loop.index0 }}
{% endfor %}
Memory
{{ data.system.mem_used_pct }}%
{{ data.system.mem_available }} free of {{ data.system.mem_total }}
Disk
{{ data.system.disk_used_pct }}%
{{ data.system.disk_free }} free of {{ data.system.disk_total }}

Server Clock

—
{{ data.clock.tz }}
{% if data.clock.ntp_synced %} ✓ NTP synced{% if data.clock.last_sync_age_s is not none %} · {{ (data.clock.last_sync_age_s // 60) | duration if data.clock.last_sync_age_s >= 60 else (data.clock.last_sync_age_s ~ 's') }} ago{% endif %} {% else %} ⚠ NTP NOT synced — clock may be off {% endif %}
{# Business review. Every figure here is aggregated on demand from the vouchers table — no sampler, no stored series, so it costs the SD card nothing. #}

Business Review

Sales report →
Earned
—
— sales · avg —
Customers
—
— came back
Best hour
—
—
Time used
—
of minutes sold
Earnings
per day
—now
Earning hours
When customers actually buy
12amnoon11pm
What they buy
—
Session quality
Minutes sold—
Minutes actually used—
Repeat customers—
Average sale—

Recent Vouchers

View all →
{% if data.recent %}
{% for v in data.recent %} {% endfor %}
Code Status Time Paid MAC Created
{{ v.code }} {{ v.status }} {{ v.minutes_total | duration }} ₱{{ v.paid_pesos }} {% if v.mac %}{{ v.mac }}{% else %}—{% endif %} {{ v.created }}
{% else %}
No vouchers yet.
Drop a coin into the slot to generate the first one.
{% endif %}
{% endblock %}