- Replace SB Admin 2 sidebar with a clean fixed sidebar (desktop) and a sticky bottom tab navigation (mobile, ≤767px) - Sidebar collapses to icon-only mode with state persisted in localStorage - Logo is a functional home link on all viewports - Mobile: full-width content, bottom nav replaces sidebar - Dashboard: 6 OBD stat cards (status, speed, RPM, coolant, throttle, fuel) wired to live socket events; removed all placeholder buttons/dropdowns - GPS info section cleaned up (lat/lon display instead of X/Y paragraphs) - DTC page: live /api/dtc wiring — MIL indicator + DTC table populated from API - New /api/dtc route added to app.py (mil + codes) - yaris.js: added obd_coolant_temp / obd_fuel_level / obd_throttle listeners - yaris.css: full rewrite — layout variables, sidebar, bottom nav, OBD cards, border-start utilities, mobile padding for bottom nav Co-authored-by: Copilot <[email protected]>
143 lines
6.5 KiB
HTML
143 lines
6.5 KiB
HTML
{% extends "base.html" %}
|
|
|
|
{% block title %}Dashboard - Yaris OBD{% endblock %}
|
|
|
|
{% block styles %}
|
|
<link rel="stylesheet" href="{{ url_for('static', filename='vendor/leaflet/leaflet.css') }}">
|
|
{% endblock %}
|
|
|
|
{% block content %}
|
|
<h3 class="text-dark mb-4 fw-bold">Dashboard</h3>
|
|
|
|
{# ── OBD stat cards ──────────────────────────────────────────────────── #}
|
|
<div class="row g-3 mb-4">
|
|
<div class="col-6 col-lg-4 col-xl-2">
|
|
<div class="card shadow-sm border-start-primary h-100">
|
|
<div class="card-body py-3">
|
|
<div class="text-uppercase text-primary fw-bold text-xs mb-1">OBD Status</div>
|
|
<div id="obd-status" class="fw-bold h5 mb-0 text-dark">—</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-6 col-lg-4 col-xl-2">
|
|
<div class="card shadow-sm border-start-success h-100">
|
|
<div class="card-body py-3">
|
|
<div class="text-uppercase text-success fw-bold text-xs mb-1">Speed</div>
|
|
<div id="obd-speed" class="fw-bold h5 mb-0 text-dark">—</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-6 col-lg-4 col-xl-2">
|
|
<div class="card shadow-sm border-start-info h-100">
|
|
<div class="card-body py-3">
|
|
<div class="text-uppercase text-info fw-bold text-xs mb-1">RPM</div>
|
|
<div id="obd-rpm" class="fw-bold h5 mb-0 text-dark">—</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-6 col-lg-4 col-xl-2">
|
|
<div class="card shadow-sm border-start-warning h-100">
|
|
<div class="card-body py-3">
|
|
<div class="text-uppercase text-warning fw-bold text-xs mb-1">Coolant temp</div>
|
|
<div id="obd-coolant" class="fw-bold h5 mb-0 text-dark">—</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-6 col-lg-4 col-xl-2">
|
|
<div class="card shadow-sm border-start-danger h-100">
|
|
<div class="card-body py-3">
|
|
<div class="text-uppercase text-danger fw-bold text-xs mb-1">Throttle</div>
|
|
<div id="obd-throttle" class="fw-bold h5 mb-0 text-dark">—</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-6 col-lg-4 col-xl-2">
|
|
<div class="card shadow-sm border-start-primary h-100">
|
|
<div class="card-body py-3">
|
|
<div class="text-uppercase text-primary fw-bold text-xs mb-1">Fuel level</div>
|
|
<div id="obd-fuel" class="fw-bold h5 mb-0 text-dark">—</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{# ── Pi health ───────────────────────────────────────────────────────── #}
|
|
<div class="card shadow-sm mb-4" id="pi-health-card">
|
|
<div class="card-header d-flex flex-wrap justify-content-between align-items-center gap-2">
|
|
<h6 class="text-primary fw-bold m-0">Pi health</h6>
|
|
<span id="pi-health-updated" class="small text-muted">Loading…</span>
|
|
</div>
|
|
<div class="card-body">
|
|
<div id="pi-health-warning" class="alert alert-warning" role="alert" hidden></div>
|
|
<div id="pi-health-error" class="alert alert-danger" role="alert" hidden></div>
|
|
<div class="row g-3">
|
|
<div class="col-6 col-lg-3">
|
|
<div class="text-uppercase text-muted fw-bold text-xs mb-1">CPU temperature</div>
|
|
<div id="pi-temperature" class="h5 text-dark fw-bold mb-0">--</div>
|
|
</div>
|
|
<div class="col-6 col-lg-3">
|
|
<div class="text-uppercase text-muted fw-bold text-xs mb-1">Memory used</div>
|
|
<div id="pi-memory" class="h5 text-dark fw-bold mb-0">--</div>
|
|
</div>
|
|
<div class="col-6 col-lg-3">
|
|
<div class="text-uppercase text-muted fw-bold text-xs mb-1">Disk used</div>
|
|
<div id="pi-disk" class="h5 text-dark fw-bold mb-0">--</div>
|
|
</div>
|
|
<div class="col-6 col-lg-3">
|
|
<div class="text-uppercase text-muted fw-bold text-xs mb-1">Uptime</div>
|
|
<div id="pi-uptime" class="h5 text-dark fw-bold mb-0">--</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{# ── Speed graph + GPS ───────────────────────────────────────────────── #}
|
|
<div class="row g-3">
|
|
<div class="col-lg-7 col-xl-8">
|
|
<div class="card shadow-sm mb-4">
|
|
<div class="card-header">
|
|
<h6 class="text-primary fw-bold m-0">Speed Graph</h6>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="chart-container" style="position:relative;height:40vh;text-align:center;">
|
|
<canvas id="speedGraph"></canvas>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-lg-5 col-xl-4">
|
|
<div class="card shadow-sm mb-3">
|
|
<div class="card-header">
|
|
<h6 class="text-primary fw-bold m-0">GPS</h6>
|
|
</div>
|
|
<div class="card-body p-0">
|
|
<div id="map"></div>
|
|
</div>
|
|
</div>
|
|
<div class="card shadow-sm mb-4">
|
|
<div class="card-header">
|
|
<h6 class="text-primary fw-bold m-0">GPS coordinates</h6>
|
|
</div>
|
|
<div class="card-body py-2">
|
|
<div class="d-flex gap-4">
|
|
<div>
|
|
<div class="text-xs text-muted fw-bold text-uppercase mb-1">Latitude</div>
|
|
<div id="gpsLocationX" class="fw-bold">—</div>
|
|
</div>
|
|
<div>
|
|
<div class="text-xs text-muted fw-bold text-uppercase mb-1">Longitude</div>
|
|
<div id="gpsLocationY" class="fw-bold">—</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endblock %}
|
|
|
|
{% block scripts %}
|
|
<script src="{{ url_for('static', filename='js/chart.min.js') }}"></script>
|
|
<script src="{{ url_for('static', filename='vendor/socketio/socket.io.min.js') }}"></script>
|
|
<script src="{{ url_for('static', filename='vendor/leaflet/leaflet.js') }}"></script>
|
|
<script src="{{ url_for('static', filename='js/yaris.js') }}"></script>
|
|
{% endblock %} |