site: add launcher-style auth (login/register modal, JWT localStorage) + cabinet with Сборки tab (list /packs, download /pack/{name}/zip with Bearer, pass check, manual Prologue intercept)

This commit is contained in:
SashegDev
2026-09-02 04:35:57 +00:00
parent 146a56cdff
commit 025a21d01f
3 changed files with 364 additions and 0 deletions
+72
View File
@@ -33,6 +33,12 @@
<span class="lang-toggle-label" id="langToggleLabel">EN</span>
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="10"/><path d="M2 12h20"/><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"/></svg>
</button>
<button class="btn btn-ghost" id="auth-btn" style="padding:8px 14px;font-size:13px" data-i18n="nav.login">Войти</button>
<div id="user-menu" class="hidden" style="display:flex;align-items:center;gap:8px">
<span id="user-name" style="font-weight:600;font-size:13px;color:var(--text)"></span>
<button class="btn btn-ghost" id="cabinet-btn" style="padding:8px 14px;font-size:13px" data-i18n="nav.cabinet">Кабинет</button>
<button class="btn btn-ghost" id="logout-btn" style="padding:8px 14px;font-size:13px" data-i18n="nav.logout">Выйти</button>
</div>
<a class="nav-cta" href="#download" data-i18n="nav.play">Играть сейчас</a>
</div>
</div>
@@ -505,6 +511,72 @@
</div>
</footer>
<!-- Auth modal (launcher style) -->
<div id="auth-modal" class="modal-backdrop hidden" style="z-index:200">
<div class="modal" style="max-width:380px">
<div class="modal-head">
<h3 id="auth-title" data-i18n="auth.title">Вход</h3>
<button class="modal-close" id="auth-close">&times;</button>
</div>
<div class="modal-body" style="display:flex;flex-direction:column;gap:14px">
<div style="display:flex;gap:8px;margin-bottom:4px">
<button class="btn btn-ghost" id="auth-tab-login" style="flex:1;background:var(--accent);color:#fff" data-i18n="auth.login">Вход</button>
<button class="btn btn-ghost" id="auth-tab-register" style="flex:1" data-i18n="auth.register">Регистрация</button>
</div>
<div class="field">
<label for="auth-username" data-i18n="auth.username">Логин</label>
<input type="text" id="auth-username" placeholder="a-z, 0-9, _" autocomplete="username" style="width:100%;padding:10px 12px;background:var(--bg-surface);border:1px solid var(--border);border-radius:4px;color:var(--text);outline:none">
</div>
<div class="field">
<label for="auth-password" data-i18n="auth.password">Пароль</label>
<input type="password" id="auth-password" placeholder="••••••••" autocomplete="current-password" style="width:100%;padding:10px 12px;background:var(--bg-surface);border:1px solid var(--border);border-radius:4px;color:var(--text);outline:none">
</div>
<div class="field hidden" id="auth-confirm-field">
<label for="auth-confirm" data-i18n="auth.confirm">Повтор пароля</label>
<input type="password" id="auth-confirm" style="width:100%;padding:10px 12px;background:var(--bg-surface);border:1px solid var(--border);border-radius:4px;color:var(--text);outline:none">
</div>
<p id="auth-error" class="hidden" style="color:#f87171;font-size:13px;background:rgba(248,113,113,0.1);padding:10px;border-radius:4px;text-align:center"></p>
<button class="btn btn-primary" id="auth-submit" style="width:100%">Войти</button>
<p style="font-size:12px;color:var(--text-muted);text-align:center">Нажимая, вы соглашаетесь с правилами ZernMC</p>
</div>
</div>
</div>
<!-- Cabinet (personal area) -->
<section class="section hidden" id="cabinet">
<div class="section-head">
<span class="section-index">08 / 08</span>
<h2 class="section-title" data-i18n-html="cabinet.title">Личный <span class="accent">кабинет.</span></h2>
<p class="section-sub" data-i18n="cabinet.sub">Ваш профиль и доступные сборки для скачивания (требует проходку).</p>
</div>
<div style="display:flex;gap:8px;margin-bottom:16px;flex-wrap:wrap">
<button class="btn btn-primary" id="cab-tab-profile" data-i18n="cabinet.profile">Профиль</button>
<button class="btn btn-ghost" id="cab-tab-packs" data-i18n="cabinet.packs">Сборки</button>
</div>
<div id="cabinet-profile" style="background:var(--bg-card);border:1px solid var(--border);border-radius:16px;padding:20px;display:flex;flex-direction:column;gap:12px">
<div style="display:flex;align-items:center;gap:12px">
<div style="width:48px;height:48px;border-radius:12px;background:linear-gradient(135deg, #e94560, #ff6b6b);display:flex;align-items:center;justify-content:center;font-weight:700;color:#fff" id="cab-avatar">Z</div>
<div>
<div style="font-weight:700" id="cab-username"></div>
<div style="font-size:12px;color:var(--text-secondary)"><span id="cab-role"></span> · <span id="cab-pass"></span></div>
</div>
</div>
<div style="display:flex;gap:8px;flex-wrap:wrap">
<div class="setting-card" style="flex:1;min-width:180px;padding:12px"><div class="setting-info"><h4>UUID</h4><p id="cab-uuid" style="font-family:var(--mono);font-size:11px"></p></div></div>
<div class="setting-card" style="flex:1;min-width:180px;padding:12px"><div class="setting-info"><h4 data-i18n="cabinet.pass">Проходка</h4><p id="cab-pass2"></p></div></div>
</div>
</div>
<div id="cabinet-packs" class="hidden" style="background:var(--bg-card);border:1px solid var(--border);border-radius:16px;padding:20px;display:flex;flex-direction:column;gap:12px">
<div style="display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap">
<h3 style="font-size:15px;font-weight:700" data-i18n="cabinet.available">Доступные сборки</h3>
<span id="cab-packs-count" style="font-size:12px;color:var(--text-muted)"></span>
</div>
<div id="cab-packs-list" style="display:flex;flex-direction:column;gap:8px"><p style="color:var(--text-muted);font-size:13px">Загрузка...</p></div>
<p id="cab-packs-error" class="hidden" style="color:#f87171;font-size:13px"></p>
<p style="font-size:12px;color:var(--text-muted)">Скачивание требует активной проходки. Кнопка скачает zip для ручной установки в <code>%USERPROFILE%\.zernmc\instances</code></p>
</div>
</section>
<script src="/js/main.js"></script>
</body>
</html>