Files
drivers_bot/web/index.html
2026-05-12 04:36:30 +09:00

312 lines
13 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!doctype html>
<html lang="ru">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#16806a" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-title" content="Гараж" />
<title>Гараж</title>
<link rel="manifest" href="/manifest.webmanifest" />
<link rel="stylesheet" href="/static/styles.css" />
<script src="https://telegram.org/js/telegram-web-app.js"></script>
</head>
<body>
<div class="auth-overlay" id="authOverlay">
<div class="auth-panel">
<p class="eyebrow">Drivers</p>
<h1>Гараж</h1>
<p>Войди через Telegram, чтобы привязать гараж к твоему chat_id.</p>
<div id="telegramLoginSlot" class="telegram-login-slot"></div>
</div>
</div>
<main class="shell">
<header class="topbar">
<div>
<p class="eyebrow">Drivers</p>
<h1>Гараж</h1>
</div>
<div class="top-actions">
<button class="icon-btn" id="refreshBtn" title="Обновить" aria-label="Обновить"></button>
<button class="icon-btn" id="menuBtn" title="Меню" aria-label="Меню"></button>
</div>
</header>
<section class="hero-grid">
<div class="summary-card">
<span>Автомобиль</span>
<strong id="selectedCarTitle">Не выбран</strong>
<small id="selectedCarMeta">Добавь авто или выбери из списка</small>
</div>
<div class="summary-card accent">
<span>Расходы</span>
<strong id="summaryTotal">0</strong>
<small>топливо, сервис и ремонты</small>
</div>
<div class="summary-card blue">
<span>Средний расход</span>
<strong id="summaryConsumption">-</strong>
<small>л/100 км по полным данным</small>
</div>
</section>
<section class="layout">
<aside class="panel reveal">
<div class="section-head">
<h2>Автомобили</h2>
<button class="ghost-btn" id="addCarQuickBtn">+</button>
</div>
<div id="cars" class="cars"></div>
</aside>
<section class="workspace reveal">
<section class="progress-strip">
<div>
<span>Профиль учета</span>
<strong id="scoreTitle">Старт</strong>
</div>
<div class="progress-track"><span id="scoreBar"></span></div>
<small id="scoreHint">Добавь авто и первую запись, чтобы видеть точные отчеты</small>
</section>
<div class="status-bar" id="statusBar" aria-live="polite">Готов к работе</div>
<section class="report-bar">
<div>
<p class="eyebrow">Отчет</p>
<h2>Стоимость владения</h2>
</div>
<div class="period-controls">
<select id="periodPreset" aria-label="Период отчета">
<option value="all">Весь срок</option>
<option value="month">Месяц</option>
<option value="day">День</option>
<option value="quarter">Квартал</option>
<option value="year">Год</option>
<option value="custom">Свой период</option>
</select>
<input id="periodFrom" type="date" aria-label="Дата начала" />
<input id="periodTo" type="date" aria-label="Дата окончания" />
</div>
</section>
<div class="stats" id="stats"></div>
<section class="quick-actions">
<button class="action-card active" data-action="fuel">
<span>Заправка</span>
<strong>30 сек</strong>
</button>
<button class="action-card" data-action="service">
<span>Сервис</span>
<strong>ТО / ремонт</strong>
</button>
<button class="action-card" data-action="scan">
<span>Скан чека</span>
<strong>OCR</strong>
</button>
</section>
<section class="charts">
<div class="chart-card">
<div class="section-head">
<h2>Динамика расходов</h2>
</div>
<canvas id="expensesChart" width="720" height="260"></canvas>
</div>
<div class="chart-card compact">
<div class="section-head">
<h2>Структура</h2>
</div>
<canvas id="splitChart" width="280" height="260"></canvas>
</div>
</section>
<form id="fuelForm" class="entry-form quick-form">
<label>
Дата
<input name="entry_date" type="date" required />
</label>
<label>
Одометр, км
<input name="odometer" type="number" min="0" required />
</label>
<label>
Литры
<input name="liters" type="number" min="0" step="0.001" required />
</label>
<label>
Цена за литр
<input name="price_per_liter" type="number" min="0" step="0.01" required />
</label>
<label>
АЗС
<select name="station">
<option value="">Не выбрано</option>
<option>Shell</option>
<option>Lukoil</option>
<option>Gazprom</option>
<option>Rosneft</option>
<option>Neste</option>
</select>
</label>
<label class="check">
<input name="is_full_tank" type="checkbox" checked />
Полный бак
</label>
<button type="submit">Сохранить заправку</button>
</form>
<form id="serviceForm" class="entry-form hidden">
<label>
Дата
<input name="entry_date" type="date" required />
</label>
<label>
Одометр, км
<input name="odometer" type="number" min="0" />
</label>
<label>
Тип
<select name="service_type">
<option value="maintenance">Обслуживание</option>
<option value="repair">Ремонт</option>
<option value="fluid">Жидкости</option>
<option value="tire">Шины</option>
<option value="inspection">Осмотр</option>
<option value="insurance">Страховка</option>
<option value="tax">Налог</option>
<option value="other">Другое</option>
</select>
</label>
<label>
Что сделано
<input name="title" placeholder="Замена масла" required />
</label>
<div class="preset-row">
<button type="button" data-service-title="Замена масла" data-service-type="maintenance">Масло</button>
<button type="button" data-service-title="Шиномонтаж" data-service-type="tire">Шины</button>
<button type="button" data-service-title="Диагностика" data-service-type="inspection">Осмотр</button>
</div>
<label>
Стоимость
<input name="total_cost" type="number" min="0" step="0.01" required />
</label>
<label>
Исполнитель
<input name="vendor" placeholder="СТО / магазин" />
</label>
<label>
Следующая дата
<input name="next_due_date" type="date" />
</label>
<label>
Следующий пробег
<input name="next_due_odometer" type="number" min="0" />
</label>
<button type="submit">Сохранить запись</button>
</form>
</section>
</section>
</main>
<div class="drawer hidden" id="userDrawer">
<div class="drawer-panel">
<div class="section-head">
<h2>Меню</h2>
<button class="icon-btn" id="closeMenuBtn" aria-label="Закрыть">×</button>
</div>
<button class="menu-row" id="openCarFormBtn">Добавить автомобиль</button>
<button class="menu-row" id="openSettingsBtn">Локаль и валюта</button>
<button class="menu-row" id="openNotificationsBtn">Уведомления</button>
<button class="menu-row" id="openScanBtn">Сканировать чек</button>
<section class="drawer-section hidden" id="settingsSection">
<h2>Настройки</h2>
<form id="settingsForm" class="grid-form drawer-form">
<label>
Язык
<select name="locale" id="localeSelect">
<option value="ru">Русский</option>
<option value="en">English</option>
<option value="ko">한국어</option>
</select>
</label>
<label>
Валюта
<select name="currency" id="currencySelect">
<option value="RUB">RUB ₽</option>
<option value="USD">USD $</option>
<option value="EUR">EUR €</option>
<option value="KRW">KRW ₩</option>
<option value="KZT">KZT ₸</option>
</select>
</label>
<button type="submit">Сохранить настройки</button>
</form>
</section>
<section class="drawer-section hidden" id="notificationsSection">
<h2>Уведомления</h2>
<div class="tip-card" id="notificationStatus">Напомним о ТО, страховке и регулярном внесении пробега.</div>
<button type="button" class="wide-btn" id="enableNotificationsBtn">Включить уведомления</button>
</section>
<section class="drawer-section" id="carFormSection">
<h2>Новое авто</h2>
<form id="carForm" class="grid-form drawer-form">
<label>
Название авто
<input name="name" placeholder="Toyota Camry" required />
</label>
<label>
Марка
<select name="make" id="makeSelect" required></select>
</label>
<label>
Модель
<select name="model" id="modelSelect" required></select>
</label>
<label>
Год
<input name="year" type="number" min="1900" max="2100" />
</label>
<button type="submit">Добавить авто</button>
</form>
</section>
</div>
</div>
<div class="scan-modal hidden" id="scanModal">
<div class="scan-panel">
<div class="section-head">
<h2>Скан чека</h2>
<button class="icon-btn" id="closeScanBtn" aria-label="Закрыть">×</button>
</div>
<form id="ocrForm" class="scan-form">
<div class="scan-actions">
<button type="button" class="ghost-btn" id="scanCameraBtn">Сфотографировать</button>
<button type="button" class="ghost-btn" id="scanFileBtn">Выбрать файл</button>
</div>
<input id="receiptCameraInput" class="hidden-file" type="file" accept="image/*" capture="environment" />
<input id="receiptFileInput" class="hidden-file" type="file" accept="image/*,.pdf,.txt" />
<div id="receiptFileName" class="file-hint">Файл не выбран</div>
<button type="submit">Распознать</button>
</form>
<div id="ocrResult" class="tip-card">После распознавания поля заправки заполнятся автоматически.</div>
</div>
</div>
<div class="report-sheet hidden" id="reportSheet">
<div class="sheet-panel">
<div class="section-head">
<h2 id="reportTitle">Отчет</h2>
<button class="icon-btn" id="closeReportBtn" aria-label="Закрыть">×</button>
</div>
<div id="reportBody"></div>
</div>
</div>
<div class="toast hidden" id="toast" role="status" aria-live="polite"></div>
<script src="/static/app.js"></script>
</body>
</html>