view mrjunejune/src/notes/login.html @ 211:a6d8d32a0261

[MrJuneJune] Simple animations for darkmode.
author MrJuneJune <me@mrjunejune.com>
date Sun, 15 Feb 2026 21:38:23 -0800
parents 6cdee35a7ba9
children
line wrap: on
line source

<!DOCTYPE html>
<html lang="en">
<head>
  {{/parts/base_head.html}}
  <title>Login | Notes</title>
  <style>
    .login-page {
      max-width: 400px;
      margin: 100px auto;
      padding: 20px;
    }
    .login-box {
      background: #fff;
      border: 1px solid #ddd;
      border-radius: 8px;
      padding: 32px;
      box-shadow: 0 2px 8px rgba(0,0,0,0.1);
    }
    .login-box h1 {
      margin: 0 0 24px 0;
      font-size: 24px;
      text-align: center;
    }
    .login-box label {
      display: block;
      margin-bottom: 8px;
      font-weight: 500;
    }
    .login-box input {
      width: 100%;
      padding: 12px;
      border: 1px solid #ccc;
      border-radius: 4px;
      font-size: 16px;
      box-sizing: border-box;
    }
    .login-box input:focus {
      outline: none;
      border-color: #0078ff;
    }
    .login-box button {
      width: 100%;
      padding: 12px;
      margin-top: 16px;
      background: #0078ff;
      color: white;
      border: none;
      border-radius: 4px;
      font-size: 16px;
      cursor: pointer;
    }
    .login-box button:hover {
      background: #0066dd;
    }
    .error-msg {
      color: #d32f2f;
      margin-top: 12px;
      text-align: center;
      display: none;
    }
  </style>
</head>
<body>
  {{/parts/header.html}}

  <main class="login-page">
    <div class="login-box">
      <h1>Notes Login</h1>
      <form id="login-form">
        <label for="token">Access Token</label>
        <input type="password" id="token" placeholder="Enter your access token" required>
        <button type="submit">Login</button>
        <p class="error-msg" id="error-msg">Invalid token</p>
      </form>
    </div>
  </main>

  {{/parts/footer.html}}

  <script>
    // Check if already logged in
    const savedToken = localStorage.getItem('notes-auth-token');
    if (savedToken) {
      window.location.href = '/notes/';
    }

    document.getElementById('login-form').addEventListener('submit', async function(e) {
      e.preventDefault();

      const token = document.getElementById('token').value.trim();
      if (!token) return;

      // Verify token by trying to load a document
      try {
        const response = await fetch('/api/editor/load/index', {
          headers: { 'Authorization': 'Bearer ' + token }
        });

        if (response.ok) {
          localStorage.setItem('notes-auth-token', token);
          // Redirect to originally requested page or /notes/
          const returnUrl = new URLSearchParams(window.location.search).get('return') || '/notes/';
          window.location.href = returnUrl;
        } else {
          document.getElementById('error-msg').style.display = 'block';
        }
      } catch (err) {
        document.getElementById('error-msg').style.display = 'block';
      }
    });
  </script>
</body>
</html>