Mercurial
comparison mrjunejune/src/notes/login.html @ 201:6cdee35a7ba9
[MrJuneJune] notes
| author | MrJuneJune <me@mrjunejune.com> |
|---|---|
| date | Sun, 15 Feb 2026 07:07:50 -0800 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 200:90dfcef375fb | 201:6cdee35a7ba9 |
|---|---|
| 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; | |
| 10 padding: 20px; | |
| 11 } | |
| 12 .login-box { | |
| 13 background: #fff; | |
| 14 border: 1px solid #ddd; | |
| 15 border-radius: 8px; | |
| 16 padding: 32px; | |
| 17 box-shadow: 0 2px 8px rgba(0,0,0,0.1); | |
| 18 } | |
| 19 .login-box h1 { | |
| 20 margin: 0 0 24px 0; | |
| 21 font-size: 24px; | |
| 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%; | |
| 31 padding: 12px; | |
| 32 border: 1px solid #ccc; | |
| 33 border-radius: 4px; | |
| 34 font-size: 16px; | |
| 35 box-sizing: border-box; | |
| 36 } | |
| 37 .login-box input:focus { | |
| 38 outline: none; | |
| 39 border-color: #0078ff; | |
| 40 } | |
| 41 .login-box button { | |
| 42 width: 100%; | |
| 43 padding: 12px; | |
| 44 margin-top: 16px; | |
| 45 background: #0078ff; | |
| 46 color: white; | |
| 47 border: none; | |
| 48 border-radius: 4px; | |
| 49 font-size: 16px; | |
| 50 cursor: pointer; | |
| 51 } | |
| 52 .login-box button:hover { | |
| 53 background: #0066dd; | |
| 54 } | |
| 55 .error-msg { | |
| 56 color: #d32f2f; | |
| 57 margin-top: 12px; | |
| 58 text-align: center; | |
| 59 display: none; | |
| 60 } | |
| 61 </style> | |
| 62 </head> | |
| 63 <body> | |
| 64 {{/parts/header.html}} | |
| 65 | |
| 66 <main class="login-page"> | |
| 67 <div class="login-box"> | |
| 68 <h1>Notes Login</h1> | |
| 69 <form id="login-form"> | |
| 70 <label for="token">Access Token</label> | |
| 71 <input type="password" id="token" placeholder="Enter your access token" required> | |
| 72 <button type="submit">Login</button> | |
| 73 <p class="error-msg" id="error-msg">Invalid token</p> | |
| 74 </form> | |
| 75 </div> | |
| 76 </main> | |
| 77 | |
| 78 {{/parts/footer.html}} | |
| 79 | |
| 80 <script> | |
| 81 // Check if already logged in | |
| 82 const savedToken = localStorage.getItem('notes-auth-token'); | |
| 83 if (savedToken) { | |
| 84 window.location.href = '/notes/'; | |
| 85 } | |
| 86 | |
| 87 document.getElementById('login-form').addEventListener('submit', async function(e) { | |
| 88 e.preventDefault(); | |
| 89 | |
| 90 const token = document.getElementById('token').value.trim(); | |
| 91 if (!token) return; | |
| 92 | |
| 93 // Verify token by trying to load a document | |
| 94 try { | |
| 95 const response = await fetch('/api/editor/load/index', { | |
| 96 headers: { 'Authorization': 'Bearer ' + token } | |
| 97 }); | |
| 98 | |
| 99 if (response.ok) { | |
| 100 localStorage.setItem('notes-auth-token', token); | |
| 101 // Redirect to originally requested page or /notes/ | |
| 102 const returnUrl = new URLSearchParams(window.location.search).get('return') || '/notes/'; | |
| 103 window.location.href = returnUrl; | |
| 104 } else { | |
| 105 document.getElementById('error-msg').style.display = 'block'; | |
| 106 } | |
| 107 } catch (err) { | |
| 108 document.getElementById('error-msg').style.display = 'block'; | |
| 109 } | |
| 110 }); | |
| 111 </script> | |
| 112 </body> | |
| 113 </html> |