Mercurial
annotate mrjunejune/src/notes/login.html @ 279:b3b547563ec7
Add Google connector service and agent wiki
Implement the C/Seobeo Google Drive and Gmail connector with encrypted OAuth storage, Zenbu authentication, browser testing, AI tool discovery, chunked HTTP decoding, and Bazel coverage. Consolidate repository guidance into progressive wiki documentation and enforce arena-first allocation for new first-party C code.
Co-authored-by: Copilot <[email protected]>
Copilot-Session: 84c338fd-0939-4bb3-b7f3-1062eb213e5d
| author | MrJuneJune <me@mrjunejune.com> |
|---|---|
| date | Mon, 17 Aug 2026 22:22:36 -0700 |
| parents | 60a876c4587a |
| children |
| rev | line source |
|---|---|
| 201 | 1 <!DOCTYPE html> |
| 2 <html lang="en"> | |
| 3 <head> | |
| 4 {{/parts/base_head.html}} | |
| 5 <title>Login | Notes</title> | |
| 6 <style> | |
| 7 .login-page { | |
| 8 max-width: 400px; | |
| 9 margin: 100px auto; | |
|
258
60a876c4587a
[ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents:
201
diff
changeset
|
10 padding: var(--zenbu-sys-padding-lg); |
| 201 | 11 } |
| 12 .login-box { | |
| 13 background: #fff; | |
| 14 border: 1px solid #ddd; | |
|
258
60a876c4587a
[ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents:
201
diff
changeset
|
15 border-radius: var(--zenbu-sys-radius-control); |
|
60a876c4587a
[ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents:
201
diff
changeset
|
16 padding: var(--zenbu-sys-padding-xl); |
| 201 | 17 box-shadow: 0 2px 8px rgba(0,0,0,0.1); |
| 18 } | |
| 19 .login-box h1 { | |
| 20 margin: 0 0 24px 0; | |
|
258
60a876c4587a
[ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents:
201
diff
changeset
|
21 font-size: var(--zenbu-sys-font-size-2xl); |
| 201 | 22 text-align: center; |
| 23 } | |
| 24 .login-box label { | |
| 25 display: block; | |
| 26 margin-bottom: 8px; | |
| 27 font-weight: 500; | |
| 28 } | |
| 29 .login-box input { | |
| 30 width: 100%; | |
|
258
60a876c4587a
[ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents:
201
diff
changeset
|
31 min-height: var(--zenbu-control-height); |
|
60a876c4587a
[ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents:
201
diff
changeset
|
32 padding: |
|
60a876c4587a
[ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents:
201
diff
changeset
|
33 var(--zenbu-control-padding-block) |
|
60a876c4587a
[ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents:
201
diff
changeset
|
34 var(--zenbu-control-padding-inline); |
| 201 | 35 border: 1px solid #ccc; |
|
258
60a876c4587a
[ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents:
201
diff
changeset
|
36 border-radius: var(--zenbu-sys-radius-control-small); |
|
60a876c4587a
[ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents:
201
diff
changeset
|
37 font-size: var(--zenbu-control-font-size); |
|
60a876c4587a
[ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents:
201
diff
changeset
|
38 line-height: var(--zenbu-control-line-height); |
| 201 | 39 box-sizing: border-box; |
| 40 } | |
| 41 .login-box input:focus { | |
| 42 outline: none; | |
| 43 border-color: #0078ff; | |
| 44 } | |
| 45 .login-box button { | |
| 46 width: 100%; | |
| 47 margin-top: 16px; | |
| 48 background: #0078ff; | |
| 49 color: white; | |
| 50 border: none; | |
|
258
60a876c4587a
[ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents:
201
diff
changeset
|
51 border-radius: var(--zenbu-sys-radius-control-small); |
| 201 | 52 cursor: pointer; |
| 53 } | |
|
258
60a876c4587a
[ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents:
201
diff
changeset
|
54 .login-box zen-button { |
|
60a876c4587a
[ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents:
201
diff
changeset
|
55 width: 100%; |
|
60a876c4587a
[ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents:
201
diff
changeset
|
56 } |
| 201 | 57 .login-box button:hover { |
| 58 background: #0066dd; | |
| 59 } | |
| 60 .error-msg { | |
| 61 color: #d32f2f; | |
| 62 margin-top: 12px; | |
| 63 text-align: center; | |
| 64 display: none; | |
| 65 } | |
| 66 </style> | |
| 67 </head> | |
| 68 <body> | |
| 69 {{/parts/header.html}} | |
| 70 | |
| 71 <main class="login-page"> | |
| 72 <div class="login-box"> | |
| 73 <h1>Notes Login</h1> | |
| 74 <form id="login-form"> | |
|
258
60a876c4587a
[ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents:
201
diff
changeset
|
75 <zen-field appearance="plain" size="lg"> |
|
60a876c4587a
[ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents:
201
diff
changeset
|
76 <label for="token">Access Token</label> |
|
60a876c4587a
[ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents:
201
diff
changeset
|
77 <input type="password" id="token" placeholder="Enter your access token" required> |
|
60a876c4587a
[ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents:
201
diff
changeset
|
78 </zen-field> |
|
60a876c4587a
[ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents:
201
diff
changeset
|
79 <zen-button appearance="plain" size="lg"> |
|
60a876c4587a
[ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents:
201
diff
changeset
|
80 <button type="submit">Login</button> |
|
60a876c4587a
[ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents:
201
diff
changeset
|
81 </zen-button> |
| 201 | 82 <p class="error-msg" id="error-msg">Invalid token</p> |
| 83 </form> | |
| 84 </div> | |
| 85 </main> | |
| 86 | |
| 87 {{/parts/footer.html}} | |
| 88 | |
| 89 <script> | |
| 90 // Check if already logged in | |
| 91 const savedToken = localStorage.getItem('notes-auth-token'); | |
| 92 if (savedToken) { | |
| 93 window.location.href = '/notes/'; | |
| 94 } | |
| 95 | |
| 96 document.getElementById('login-form').addEventListener('submit', async function(e) { | |
| 97 e.preventDefault(); | |
| 98 | |
| 99 const token = document.getElementById('token').value.trim(); | |
| 100 if (!token) return; | |
| 101 | |
| 102 // Verify token by trying to load a document | |
| 103 try { | |
| 104 const response = await fetch('/api/editor/load/index', { | |
| 105 headers: { 'Authorization': 'Bearer ' + token } | |
| 106 }); | |
| 107 | |
| 108 if (response.ok) { | |
| 109 localStorage.setItem('notes-auth-token', token); | |
| 110 // Redirect to originally requested page or /notes/ | |
| 111 const returnUrl = new URLSearchParams(window.location.search).get('return') || '/notes/'; | |
| 112 window.location.href = returnUrl; | |
| 113 } else { | |
| 114 document.getElementById('error-msg').style.display = 'block'; | |
| 115 } | |
| 116 } catch (err) { | |
| 117 document.getElementById('error-msg').style.display = 'block'; | |
| 118 } | |
| 119 }); | |
| 120 </script> | |
| 121 </body> | |
| 122 </html> |