Files
Balance/BalanceServer/internal/httpapi/web/index.html
T
2026-07-14 16:20:39 +07:00

107 lines
5.2 KiB
HTML

<!doctype html>
<html lang="ru">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
<meta name="theme-color" content="#5b5bd6">
<meta name="description" content="Balance — личные финансы на вашем сервере">
<title>Balance</title>
<link rel="icon" href="/icon.svg" type="image/svg+xml">
<link rel="manifest" href="/manifest.webmanifest">
<link rel="stylesheet" href="/styles.css">
</head>
<body>
<div id="toast-region" class="toast-region" aria-live="polite" aria-atomic="true"></div>
<main id="auth-view" class="auth-layout">
<section class="auth-card" aria-labelledby="auth-title">
<div class="brand brand-auth">
<img src="/icon.svg" alt="" width="58" height="58">
<div>
<span class="brand-name">Balance</span>
<span class="brand-caption">Ваши финансы. Ваш сервер.</span>
</div>
</div>
<div class="auth-copy">
<p class="eyebrow">SELF-HOSTED</p>
<h1 id="auth-title">Финансы под вашим контролем</h1>
<p>Войдите в аккаунт этого сервера. Операции синхронизируются с iPhone, Apple Watch, Mac и Android.</p>
</div>
<div class="segmented auth-switch" role="tablist" aria-label="Вход или регистрация">
<button type="button" class="is-active" data-auth-mode="login" role="tab">Войти</button>
<button type="button" data-auth-mode="register" role="tab">Регистрация</button>
</div>
<form id="auth-form" class="stack" autocomplete="on">
<label class="field">
<span>Email</span>
<input id="auth-email" name="email" type="email" inputmode="email" autocomplete="email" required maxlength="254" placeholder="name@example.com">
</label>
<label class="field">
<span>Пароль</span>
<input id="auth-password" name="password" type="password" autocomplete="current-password" required minlength="8" maxlength="1024" placeholder="Минимум 8 символов">
</label>
<p id="auth-error" class="form-error" role="alert" hidden></p>
<button id="auth-submit" class="button button-primary button-large" type="submit">Войти</button>
</form>
<p class="security-note"><span aria-hidden="true">🔒</span> Сессия хранится в защищённых HttpOnly-cookie и недоступна JavaScript.</p>
</section>
</main>
<div id="app-view" class="app-shell" hidden>
<aside class="sidebar">
<div class="brand sidebar-brand">
<img src="/icon.svg" alt="" width="42" height="42">
<div>
<span class="brand-name">Balance</span>
<span class="brand-caption">Личные финансы</span>
</div>
</div>
<nav class="side-nav" aria-label="Основная навигация">
<button type="button" data-route="dashboard"><span>⌂</span> Обзор</button>
<button type="button" data-route="transactions"><span>↕</span> Операции</button>
<button type="button" data-route="analytics"><span>◫</span> Аналитика</button>
<button type="button" data-route="budgets"><span>◎</span> Бюджеты</button>
<button type="button" data-route="categories"><span>◆</span> Категории</button>
<button type="button" data-route="settings"><span>⚙</span> Настройки</button>
</nav>
<div class="sidebar-footer">
<div id="sync-pill" class="sync-pill"><span></span><span>Синхронизировано</span></div>
<div class="account-mini">
<div class="avatar" id="account-avatar">Б</div>
<div>
<strong id="account-email">—</strong>
<span>Личный аккаунт</span>
</div>
</div>
</div>
</aside>
<main class="workspace">
<header class="mobile-header">
<div class="brand">
<img src="/icon.svg" alt="" width="36" height="36">
<span class="brand-name">Balance</span>
</div>
<button type="button" class="icon-button" data-action="sync" aria-label="Синхронизировать">↻</button>
</header>
<div id="content" class="content" tabindex="-1"></div>
</main>
<nav class="bottom-nav" aria-label="Мобильная навигация">
<button type="button" data-route="dashboard"><span>⌂</span><small>Обзор</small></button>
<button type="button" data-route="transactions"><span>↕</span><small>Операции</small></button>
<button type="button" data-route="analytics"><span>◫</span><small>Аналитика</small></button>
<button type="button" data-route="budgets"><span>◎</span><small>Бюджеты</small></button>
<button type="button" data-route="settings"><span>⚙</span><small>Ещё</small></button>
</nav>
</div>
<dialog id="editor-dialog" class="modal">
<div id="dialog-content"></div>
</dialog>
<noscript>Для работы Balance необходимо включить JavaScript.</noscript>
<script src="/app.js" defer></script>
</body>
</html>