| [f4b7b6a] | 1 | <%
|
|---|
| [834bcc3] | 2 | // adminLogin = the hidden admin login page (/auth/admin): shows the
|
|---|
| 3 | // username/password form. The public /auth/login shows visitors
|
|---|
| 4 | // ONLY Google login (listeners/fans). This keeps the admin login
|
|---|
| 5 | // off the page where visitors are directed.
|
|---|
| [f4b7b6a] | 6 | var _admin = (typeof adminLogin !== 'undefined' && adminLogin);
|
|---|
| 7 | %>
|
|---|
| [7bc636b] | 8 | <div class="container auth-page">
|
|---|
| [137cca5] | 9 | <h1><%= _admin ? t('auth.admin_login_title') : t('nav.login') %></h1>
|
|---|
| [9e27d64] | 10 | <% if (typeof success !== 'undefined' && success) { %><div class="alert alert-success"><%= success %></div><% } %>
|
|---|
| [b919a67] | 11 | <%
|
|---|
| 12 | var GMAP = {
|
|---|
| [4885eab] | 13 | admin: { icon: '🔐', title: t('glog.admin_title'),
|
|---|
| 14 | body: t('glog.admin_body'),
|
|---|
| 15 | list: [t('glog.admin_li1'), t('glog.admin_li2'), t('glog.admin_li3')] },
|
|---|
| 16 | session: { icon: '⏱️', title: t('glog.session_title'), body: t('glog.session_body') },
|
|---|
| 17 | email: { icon: '✉️', title: t('glog.email_title'), body: t('glog.email_body') },
|
|---|
| 18 | linked: { icon: '🔗', title: t('glog.linked_title'), body: t('glog.linked_body') },
|
|---|
| 19 | unavailable: { icon: '🚫', title: t('glog.unavailable_title'), body: t('glog.unavailable_body') },
|
|---|
| 20 | failed: { icon: '⚠️', title: t('glog.failed_title'), body: t('glog.failed_body') },
|
|---|
| [b919a67] | 21 | };
|
|---|
| 22 | var _g = (typeof gerr !== 'undefined' && gerr && GMAP[gerr]) ? GMAP[gerr] : null;
|
|---|
| 23 | %>
|
|---|
| 24 | <% if (_g) { %>
|
|---|
| [70679063] | 25 | <div class="auth-notice">
|
|---|
| [b919a67] | 26 | <div class="auth-notice-icon"><%= _g.icon %></div>
|
|---|
| 27 | <h2 class="auth-notice-title"><%= _g.title %></h2>
|
|---|
| 28 | <p><%= _g.body %></p>
|
|---|
| 29 | <% if (_g.list) { %><ul class="auth-notice-list"><% _g.list.forEach(function(li){ %><li><%- li %></li><% }); %></ul><% } %>
|
|---|
| [70679063] | 30 | </div>
|
|---|
| 31 | <% } else if (error) { %><div class="alert alert-error"><%= error %></div><% } %>
|
|---|
| [c80e78b] | 32 |
|
|---|
| [f4b7b6a] | 33 | <% if (_admin) { %>
|
|---|
| [834bcc3] | 34 | <%# Hidden admin login (password). %>
|
|---|
| [f4b7b6a] | 35 | <form method="post" action="/auth/login" class="auth-form">
|
|---|
| 36 | <% if (typeof next !== 'undefined' && next) { %>
|
|---|
| 37 | <input type="hidden" name="next" value="<%= next %>">
|
|---|
| 38 | <% } %>
|
|---|
| 39 | <label>
|
|---|
| [137cca5] | 40 | <span><%= t('auth.username_or_email') %></span>
|
|---|
| [f4b7b6a] | 41 | <input type="text" name="username" value="<%= username %>" required autofocus autocomplete="username">
|
|---|
| 42 | </label>
|
|---|
| 43 | <label>
|
|---|
| [137cca5] | 44 | <span><%= t('auth.password') %></span>
|
|---|
| [f4b7b6a] | 45 | <input type="password" name="password" required autocomplete="current-password">
|
|---|
| 46 | </label>
|
|---|
| [137cca5] | 47 | <button type="submit" class="btn btn-primary"><%= t('nav.login') %></button>
|
|---|
| 48 | <p class="auth-link auth-link-muted"><a href="/auth/reset-request"><%= t('auth.forgot') %></a></p>
|
|---|
| [f4b7b6a] | 49 | </form>
|
|---|
| [77b6fca] | 50 | <% } %>
|
|---|
| [7bc636b] | 51 | </div>
|
|---|
| [70679063] | 52 |
|
|---|
| 53 | <style>
|
|---|
| 54 | .auth-notice { border: 1px solid rgba(128,128,128,.28); border-radius: 14px; padding: 18px 20px; margin-bottom: 18px; background: rgba(128,128,128,.06); }
|
|---|
| 55 | .auth-notice-icon { font-size: 26px; }
|
|---|
| 56 | .auth-notice-title { font-size: 17px; margin: 4px 0 8px; }
|
|---|
| 57 | .auth-notice p { margin: 0 0 10px; line-height: 1.55; opacity: .9; }
|
|---|
| 58 | .auth-notice-list { margin: 0; padding-left: 18px; line-height: 1.6; }
|
|---|
| 59 | .auth-notice-list li { margin: 4px 0; }
|
|---|
| [3fb8390] | 60 | .auth-sub { color: var(--ink-muted); margin: 0 0 1rem; text-align: center; }
|
|---|
| [834bcc3] | 61 | /* Google button is white → keep text dark at all times, including hover (the global
|
|---|
| 62 | a.btn:hover rule would otherwise make it near-white on white = unreadable). */
|
|---|
| [36afccd] | 63 | a.btn-google, a.btn-google:hover { color: #1f1f1f; }
|
|---|
| [77b6fca] | 64 | .auth-admin-box {
|
|---|
| 65 | display: flex; align-items: center; gap: .75rem;
|
|---|
| 66 | margin-top: 1.25rem; padding: .8rem 1rem;
|
|---|
| 67 | border: 1px solid var(--rule); border-radius: 12px;
|
|---|
| 68 | background: var(--paper-2); color: var(--ink); text-decoration: none;
|
|---|
| 69 | transition: border-color 120ms, background 120ms;
|
|---|
| 70 | }
|
|---|
| 71 | .auth-admin-box:hover { border-color: var(--accent); background: var(--paper); }
|
|---|
| 72 | .auth-admin-box-icon { font-size: 1.3rem; }
|
|---|
| 73 | .auth-admin-box-text { display: flex; flex-direction: column; line-height: 1.3; flex: 1; }
|
|---|
| 74 | .auth-admin-box-text small { color: var(--ink-muted); font-size: .8rem; }
|
|---|
| 75 | .auth-admin-box-arrow { color: var(--ink-muted); font-size: 1.1rem; }
|
|---|
| [70679063] | 76 | </style>
|
|---|