← back to Jill Website

views/admin-login.ejs

244 lines

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Admin Login - Nosara Beachfront Rentals</title>
  <style>
    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }

    body {
      font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
      background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
      min-height: 100vh;
      display: flex;
      align-items: center;
      justify-content: center;
      padding: 20px;
    }

    .login-container {
      background: white;
      border-radius: 12px;
      box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
      width: 100%;
      max-width: 400px;
      padding: 40px;
    }

    .login-header {
      text-align: center;
      margin-bottom: 30px;
    }

    .login-header h1 {
      font-size: 28px;
      color: #333;
      margin-bottom: 8px;
    }

    .login-header p {
      color: #666;
      font-size: 14px;
    }

    .form-group {
      margin-bottom: 20px;
    }

    .form-group label {
      display: block;
      color: #333;
      font-weight: 500;
      margin-bottom: 8px;
      font-size: 14px;
    }

    .form-group input {
      width: 100%;
      padding: 12px 16px;
      border: 2px solid #e0e0e0;
      border-radius: 8px;
      font-size: 14px;
      transition: border-color 0.3s;
    }

    .form-group input:focus {
      outline: none;
      border-color: #667eea;
    }

    .btn-login {
      width: 100%;
      padding: 14px;
      background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
      color: white;
      border: none;
      border-radius: 8px;
      font-size: 16px;
      font-weight: 600;
      cursor: pointer;
      transition: transform 0.2s, box-shadow 0.2s;
    }

    .btn-login:hover {
      transform: translateY(-2px);
      box-shadow: 0 8px 20px rgba(102, 126, 234, 0.4);
    }

    .btn-login:active {
      transform: translateY(0);
    }

    .alert {
      padding: 12px 16px;
      border-radius: 8px;
      margin-bottom: 20px;
      font-size: 14px;
    }

    .alert-error {
      background: #fee;
      border: 1px solid #fcc;
      color: #c33;
    }

    .alert-success {
      background: #efe;
      border: 1px solid #cfc;
      color: #3c3;
    }

    .loader {
      display: none;
      width: 20px;
      height: 20px;
      border: 3px solid rgba(255, 255, 255, 0.3);
      border-top-color: white;
      border-radius: 50%;
      animation: spin 0.8s linear infinite;
      margin: 0 auto;
    }

    .btn-login.loading {
      pointer-events: none;
      opacity: 0.7;
    }

    .btn-login.loading .btn-text {
      display: none;
    }

    .btn-login.loading .loader {
      display: block;
    }

    @keyframes spin {
      to { transform: rotate(360deg); }
    }

    .footer-note {
      text-align: center;
      margin-top: 20px;
      color: #666;
      font-size: 12px;
    }
  </style>
</head>
<body>
  <div class="login-container">
    <div class="login-header">
      <h1>🏖️ Admin Login</h1>
      <p>Nosara Beachfront Rentals CMS</p>
    </div>

    <div id="alert-container"></div>

    <form id="login-form">
      <div class="form-group">
        <label for="username">Username</label>
        <input type="text" id="username" name="username" required autofocus>
      </div>

      <div class="form-group">
        <label for="password">Password</label>
        <input type="password" id="password" name="password" required>
      </div>

      <button type="submit" class="btn-login">
        <span class="btn-text">Login</span>
        <div class="loader"></div>
      </button>
    </form>

    <div class="footer-note">
      Default credentials: admin / admin123
    </div>
  </div>

  <script>
    const form = document.getElementById('login-form');
    const alertContainer = document.getElementById('alert-container');
    const loginBtn = form.querySelector('.btn-login');

    form.addEventListener('submit', async (e) => {
      e.preventDefault();

      const username = document.getElementById('username').value;
      const password = document.getElementById('password').value;

      // Clear previous alerts
      alertContainer.innerHTML = '';

      // Show loading state
      loginBtn.classList.add('loading');

      try {
        const response = await fetch('/api/cms/auth/login', {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json'
          },
          body: JSON.stringify({ username, password })
        });

        const data = await response.json();

        if (response.ok && data.success) {
          // Show success message
          alertContainer.innerHTML = `
            <div class="alert alert-success">
              ${data.message || 'Login successful!'} Redirecting...
            </div>
          `;

          // Redirect to admin dashboard
          setTimeout(() => {
            window.location.href = '/admin';
          }, 1000);
        } else {
          // Show error message
          alertContainer.innerHTML = `
            <div class="alert alert-error">
              ${data.message || 'Login failed. Please try again.'}
            </div>
          `;
          loginBtn.classList.remove('loading');
        }
      } catch (error) {
        alertContainer.innerHTML = `
          <div class="alert alert-error">
            Network error. Please check your connection and try again.
          </div>
        `;
        loginBtn.classList.remove('loading');
      }
    });
  </script>
</body>
</html>