| 1 | <!DOCTYPE html>
|
|---|
| 2 | <html lang="en">
|
|---|
| 3 | <head>
|
|---|
| 4 | <meta charset="UTF-8"/>
|
|---|
| 5 | <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
|---|
| 6 | <title>Wedding Planner โ Login</title>
|
|---|
| 7 | <link href="https://fonts.googleapis.com/css2?family=Cormorant+Garamond:ital,wght@0,400;0,500;0,600;0,700;1,400;1,600&family=DM+Sans:wght@300;400;500;600&display=swap" rel="stylesheet"/>
|
|---|
| 8 | <style>
|
|---|
| 9 | :root {
|
|---|
| 10 | --cream:#fdf8f3; --cream-2:#f9f1e8; --cream-3:#f2e8db;
|
|---|
| 11 | --blush-light:#fce8e8; --blush:#f4b8b8; --blush-mid:#e8949c;
|
|---|
| 12 | --rose:#d4606a; --rose-deep:#b84550;
|
|---|
| 13 | --gold-light:#f7e6b0; --gold:#c9a84c; --gold-dark:#9e7a28;
|
|---|
| 14 | --text-dark:#2c1f1f; --text-mid:#6b4f4f; --text-light:#a08080;
|
|---|
| 15 | --border:#ecddd0; --border-light:#f4ebe2;
|
|---|
| 16 | --green:#3a9e6b; --red:#c94545;
|
|---|
| 17 | --shadow-md:0 6px 20px rgba(44,31,31,.10),0 2px 6px rgba(44,31,31,.06);
|
|---|
| 18 | --shadow-lg:0 16px 40px rgba(44,31,31,.14),0 4px 12px rgba(44,31,31,.08);
|
|---|
| 19 | --radius-md:10px; --radius-lg:16px; --radius-xl:22px;
|
|---|
| 20 | --transition:200ms cubic-bezier(.4,0,.2,1);
|
|---|
| 21 | }
|
|---|
| 22 | *,*::before,*::after{box-sizing:border-box;margin:0;padding:0;}
|
|---|
| 23 | html,body{height:100%;font-family:'DM Sans',sans-serif;background:var(--cream);color:var(--text-dark);-webkit-font-smoothing:antialiased;}
|
|---|
| 24 |
|
|---|
| 25 | body {
|
|---|
| 26 | display:flex; align-items:center; justify-content:center;
|
|---|
| 27 | min-height:100vh;
|
|---|
| 28 | background: linear-gradient(135deg, #fdf8f3 0%, #f9f1e8 50%, #fce8e8 100%);
|
|---|
| 29 | }
|
|---|
| 30 |
|
|---|
| 31 | /* floating petals background */
|
|---|
| 32 | body::before {
|
|---|
| 33 | content:'๐';
|
|---|
| 34 | position:fixed; top:10%; left:8%; font-size:80px; opacity:.06;
|
|---|
| 35 | transform:rotate(-15deg); pointer-events:none;
|
|---|
| 36 | }
|
|---|
| 37 | body::after {
|
|---|
| 38 | content:'๐ธ';
|
|---|
| 39 | position:fixed; bottom:10%; right:8%; font-size:100px; opacity:.06;
|
|---|
| 40 | transform:rotate(20deg); pointer-events:none;
|
|---|
| 41 | }
|
|---|
| 42 |
|
|---|
| 43 | .auth-wrapper {
|
|---|
| 44 | width:100%; max-width:460px; padding:20px;
|
|---|
| 45 | }
|
|---|
| 46 |
|
|---|
| 47 | /* logo top */
|
|---|
| 48 | .auth-logo {
|
|---|
| 49 | text-align:center; margin-bottom:28px;
|
|---|
| 50 | }
|
|---|
| 51 | .auth-logo .logo-mark {
|
|---|
| 52 | width:52px; height:52px; margin:0 auto 12px;
|
|---|
| 53 | background:linear-gradient(135deg,var(--rose),var(--blush-mid));
|
|---|
| 54 | border-radius:14px;
|
|---|
| 55 | display:flex; align-items:center; justify-content:center;
|
|---|
| 56 | box-shadow:0 4px 16px rgba(212,96,106,.35);
|
|---|
| 57 | }
|
|---|
| 58 | .auth-logo .logo-mark svg{width:26px;height:26px;}
|
|---|
| 59 | .auth-logo h1 {
|
|---|
| 60 | font-family:'Cormorant Garamond',serif;
|
|---|
| 61 | font-size:28px; font-weight:700; color:var(--text-dark);
|
|---|
| 62 | }
|
|---|
| 63 | .auth-logo p { font-size:13px; color:var(--text-light); margin-top:4px; }
|
|---|
| 64 |
|
|---|
| 65 | /* card */
|
|---|
| 66 | .auth-card {
|
|---|
| 67 | background:#fff;
|
|---|
| 68 | border-radius:var(--radius-xl);
|
|---|
| 69 | border:1px solid var(--border-light);
|
|---|
| 70 | box-shadow:var(--shadow-lg);
|
|---|
| 71 | overflow:hidden;
|
|---|
| 72 | }
|
|---|
| 73 |
|
|---|
| 74 | /* tabs */
|
|---|
| 75 | .auth-tabs {
|
|---|
| 76 | display:grid; grid-template-columns:1fr 1fr;
|
|---|
| 77 | border-bottom:1px solid var(--border-light);
|
|---|
| 78 | }
|
|---|
| 79 | .auth-tab {
|
|---|
| 80 | padding:16px; text-align:center; cursor:pointer;
|
|---|
| 81 | font-size:14px; font-weight:500; color:var(--text-light);
|
|---|
| 82 | background:#fff; border:none; outline:none;
|
|---|
| 83 | transition:color var(--transition), background var(--transition);
|
|---|
| 84 | }
|
|---|
| 85 | .auth-tab.active {
|
|---|
| 86 | color:var(--rose); font-weight:600;
|
|---|
| 87 | background:var(--blush-light);
|
|---|
| 88 | border-bottom:2px solid var(--rose);
|
|---|
| 89 | }
|
|---|
| 90 | .auth-tab:hover:not(.active){ background:var(--cream); color:var(--text-mid); }
|
|---|
| 91 |
|
|---|
| 92 | /* form panels */
|
|---|
| 93 | .auth-panel { display:none; padding:32px; }
|
|---|
| 94 | .auth-panel.active { display:block; }
|
|---|
| 95 |
|
|---|
| 96 | .gold-rule {
|
|---|
| 97 | width:36px; height:2px;
|
|---|
| 98 | background:linear-gradient(90deg,var(--gold),transparent);
|
|---|
| 99 | border-radius:2px; margin:0 0 22px;
|
|---|
| 100 | }
|
|---|
| 101 |
|
|---|
| 102 | .form-group { margin-bottom:16px; }
|
|---|
| 103 | .form-label {
|
|---|
| 104 | display:block; font-size:12px; font-weight:600;
|
|---|
| 105 | color:var(--text-mid); text-transform:uppercase;
|
|---|
| 106 | letter-spacing:.06em; margin-bottom:6px;
|
|---|
| 107 | }
|
|---|
| 108 | input, select {
|
|---|
| 109 | width:100%; padding:10px 14px;
|
|---|
| 110 | border-radius:var(--radius-md); border:1px solid var(--border);
|
|---|
| 111 | background:var(--cream); font-family:'DM Sans',sans-serif;
|
|---|
| 112 | font-size:14px; color:var(--text-dark); outline:none;
|
|---|
| 113 | transition:border-color var(--transition), background var(--transition);
|
|---|
| 114 | }
|
|---|
| 115 | input:focus, select:focus { border-color:var(--blush-mid); background:#fff; }
|
|---|
| 116 |
|
|---|
| 117 | .form-row { display:grid; grid-template-columns:1fr 1fr; gap:12px; }
|
|---|
| 118 |
|
|---|
| 119 | .btn-submit {
|
|---|
| 120 | width:100%; padding:12px;
|
|---|
| 121 | background:var(--rose); color:#fff; border:none;
|
|---|
| 122 | border-radius:var(--radius-md); font-family:'DM Sans',sans-serif;
|
|---|
| 123 | font-size:15px; font-weight:600; cursor:pointer; margin-top:8px;
|
|---|
| 124 | box-shadow:0 3px 12px rgba(212,96,106,.35);
|
|---|
| 125 | transition:background var(--transition), box-shadow var(--transition), transform var(--transition);
|
|---|
| 126 | }
|
|---|
| 127 | .btn-submit:hover { background:var(--rose-deep); box-shadow:0 5px 18px rgba(212,96,106,.45); }
|
|---|
| 128 | .btn-submit:active { transform:translateY(1px); }
|
|---|
| 129 | .btn-submit:disabled { background:var(--blush); cursor:not-allowed; box-shadow:none; }
|
|---|
| 130 |
|
|---|
| 131 | /* alert */
|
|---|
| 132 | .alert {
|
|---|
| 133 | padding:10px 14px; border-radius:var(--radius-md);
|
|---|
| 134 | font-size:13px; font-weight:500; margin-bottom:16px;
|
|---|
| 135 | display:none;
|
|---|
| 136 | }
|
|---|
| 137 | .alert.show { display:block; }
|
|---|
| 138 | .alert-error { background:var(--red-light,#fdeaea); color:var(--red); border:1px solid #f5c2c2; }
|
|---|
| 139 | .alert-success { background:#e4f5ec; color:var(--green); border:1px solid #b2e0ca; }
|
|---|
| 140 |
|
|---|
| 141 | /* divider */
|
|---|
| 142 | .form-divider {
|
|---|
| 143 | display:flex; align-items:center; gap:10px;
|
|---|
| 144 | margin:14px 0; color:var(--text-light); font-size:12px;
|
|---|
| 145 | }
|
|---|
| 146 | .form-divider::before, .form-divider::after {
|
|---|
| 147 | content:''; flex:1; height:1px; background:var(--border-light);
|
|---|
| 148 | }
|
|---|
| 149 |
|
|---|
| 150 | /* footer note */
|
|---|
| 151 | .auth-footer {
|
|---|
| 152 | text-align:center; padding:16px 32px;
|
|---|
| 153 | background:var(--cream); border-top:1px solid var(--border-light);
|
|---|
| 154 | font-size:12px; color:var(--text-light);
|
|---|
| 155 | }
|
|---|
| 156 |
|
|---|
| 157 | /* loading spinner inside button */
|
|---|
| 158 | .spinner {
|
|---|
| 159 | display:inline-block; width:14px; height:14px;
|
|---|
| 160 | border:2px solid rgba(255,255,255,.4);
|
|---|
| 161 | border-top-color:#fff; border-radius:50%;
|
|---|
| 162 | animation:spin .6s linear infinite; margin-right:6px; vertical-align:middle;
|
|---|
| 163 | }
|
|---|
| 164 | @keyframes spin { to { transform:rotate(360deg); } }
|
|---|
| 165 | </style>
|
|---|
| 166 | </head>
|
|---|
| 167 | <body>
|
|---|
| 168 |
|
|---|
| 169 | <div class="auth-wrapper">
|
|---|
| 170 |
|
|---|
| 171 | <!-- Logo -->
|
|---|
| 172 | <div class="auth-logo">
|
|---|
| 173 | <div class="logo-mark">
|
|---|
| 174 | <svg viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round">
|
|---|
| 175 | <path d="M12 21.593c-5.63-5.539-11-10.297-11-14.402C1 3.402 4.248 1 7.5 1 9.849 1 11.271 2.007 12 3.011 12.729 2.007 14.151 1 16.5 1 19.752 1 23 3.402 23 7.191c0 4.105-5.37 8.863-11 14.402z"/>
|
|---|
| 176 | </svg>
|
|---|
| 177 | </div>
|
|---|
| 178 | <h1>Wedding Planner</h1>
|
|---|
| 179 | <p>Plan your perfect day</p>
|
|---|
| 180 | </div>
|
|---|
| 181 |
|
|---|
| 182 | <!-- Card -->
|
|---|
| 183 | <div class="auth-card">
|
|---|
| 184 |
|
|---|
| 185 | <!-- Tabs -->
|
|---|
| 186 | <div class="auth-tabs">
|
|---|
| 187 | <button class="auth-tab active" id="tabLogin" onclick="switchTab('login')">Sign In</button>
|
|---|
| 188 | <button class="auth-tab" id="tabRegister" onclick="switchTab('register')">Create Account</button>
|
|---|
| 189 | </div>
|
|---|
| 190 |
|
|---|
| 191 | <!-- LOGIN PANEL -->
|
|---|
| 192 | <div class="auth-panel active" id="panelLogin">
|
|---|
| 193 | <div class="gold-rule"></div>
|
|---|
| 194 |
|
|---|
| 195 | <div class="alert alert-error" id="loginError"></div>
|
|---|
| 196 | <div class="alert alert-success" id="loginSuccess"></div>
|
|---|
| 197 |
|
|---|
| 198 | <div class="form-group">
|
|---|
| 199 | <label class="form-label">Email Address</label>
|
|---|
| 200 | <input type="email" id="loginEmail" placeholder="your@email.com" autocomplete="email"/>
|
|---|
| 201 | </div>
|
|---|
| 202 | <div class="form-group">
|
|---|
| 203 | <label class="form-label">Password</label>
|
|---|
| 204 | <input type="password" id="loginPassword" placeholder="Your password" autocomplete="current-password"/>
|
|---|
| 205 | </div>
|
|---|
| 206 |
|
|---|
| 207 | <button class="btn-submit" id="btnLogin" onclick="doLogin()">Sign In</button>
|
|---|
| 208 |
|
|---|
| 209 | <div class="form-divider">or</div>
|
|---|
| 210 | <p style="text-align:center;font-size:13px;color:var(--text-light);">
|
|---|
| 211 | Don't have an account?
|
|---|
| 212 | <a href="#" onclick="switchTab('register')" style="color:var(--rose);font-weight:600;text-decoration:none;">Create one free</a>
|
|---|
| 213 | </p>
|
|---|
| 214 | </div>
|
|---|
| 215 |
|
|---|
| 216 | <!-- REGISTER PANEL -->
|
|---|
| 217 | <div class="auth-panel" id="panelRegister">
|
|---|
| 218 | <div class="gold-rule"></div>
|
|---|
| 219 |
|
|---|
| 220 | <div class="alert alert-error" id="registerError"></div>
|
|---|
| 221 | <div class="alert alert-success" id="registerSuccess"></div>
|
|---|
| 222 |
|
|---|
| 223 | <div class="form-row">
|
|---|
| 224 | <div class="form-group">
|
|---|
| 225 | <label class="form-label">First Name</label>
|
|---|
| 226 | <input type="text" id="regFirst" placeholder="Ana"/>
|
|---|
| 227 | </div>
|
|---|
| 228 | <div class="form-group">
|
|---|
| 229 | <label class="form-label">Last Name</label>
|
|---|
| 230 | <input type="text" id="regLast" placeholder="Trajkovska"/>
|
|---|
| 231 | </div>
|
|---|
| 232 | </div>
|
|---|
| 233 |
|
|---|
| 234 | <div class="form-group">
|
|---|
| 235 | <label class="form-label">Email Address</label>
|
|---|
| 236 | <input type="email" id="regEmail" placeholder="your@email.com"/>
|
|---|
| 237 | </div>
|
|---|
| 238 |
|
|---|
| 239 | <div class="form-group">
|
|---|
| 240 | <label class="form-label">Password</label>
|
|---|
| 241 | <input type="password" id="regPassword" placeholder="Min. 6 characters"/>
|
|---|
| 242 | </div>
|
|---|
| 243 |
|
|---|
| 244 | <div class="form-row">
|
|---|
| 245 | <div class="form-group">
|
|---|
| 246 | <label class="form-label">Phone (optional)</label>
|
|---|
| 247 | <input type="text" id="regPhone" placeholder="+38970..."/>
|
|---|
| 248 | </div>
|
|---|
| 249 | <div class="form-group">
|
|---|
| 250 | <label class="form-label">Gender (optional)</label>
|
|---|
| 251 | <select id="regGender">
|
|---|
| 252 | <option value="">Select...</option>
|
|---|
| 253 | <option value="Female">Female</option>
|
|---|
| 254 | <option value="Male">Male</option>
|
|---|
| 255 | <option value="Other">Other</option>
|
|---|
| 256 | </select>
|
|---|
| 257 | </div>
|
|---|
| 258 | </div>
|
|---|
| 259 |
|
|---|
| 260 | <div class="form-group">
|
|---|
| 261 | <label class="form-label">Birthday (optional)</label>
|
|---|
| 262 | <input type="date" id="regBirthday"/>
|
|---|
| 263 | </div>
|
|---|
| 264 |
|
|---|
| 265 | <button class="btn-submit" id="btnRegister" onclick="doRegister()">Create Account</button>
|
|---|
| 266 |
|
|---|
| 267 | <div class="form-divider">or</div>
|
|---|
| 268 | <p style="text-align:center;font-size:13px;color:var(--text-light);">
|
|---|
| 269 | Already have an account?
|
|---|
| 270 | <a href="#" onclick="switchTab('login')" style="color:var(--rose);font-weight:600;text-decoration:none;">Sign in</a>
|
|---|
| 271 | </p>
|
|---|
| 272 | </div>
|
|---|
| 273 |
|
|---|
| 274 | <div class="auth-footer">
|
|---|
| 275 | Wedding Planner ยท University Database Project 2025
|
|---|
| 276 | </div>
|
|---|
| 277 | </div>
|
|---|
| 278 | </div>
|
|---|
| 279 |
|
|---|
| 280 | <script>
|
|---|
| 281 | const API = 'http://localhost:3000';
|
|---|
| 282 |
|
|---|
| 283 | // โโ Check if already logged in โโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|---|
| 284 | window.addEventListener('DOMContentLoaded', async () => {
|
|---|
| 285 | try {
|
|---|
| 286 | const res = await fetch(`${API}/api/auth/me`, { credentials: 'include' });
|
|---|
| 287 | if (res.ok) {
|
|---|
| 288 | window.location.href = 'Wedding_Planner.html';
|
|---|
| 289 | }
|
|---|
| 290 | } catch (e) { /* not logged in, stay on page */ }
|
|---|
| 291 | });
|
|---|
| 292 |
|
|---|
| 293 | // โโ Tab switching โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|---|
| 294 | function switchTab(tab) {
|
|---|
| 295 | document.getElementById('panelLogin').classList.toggle('active', tab === 'login');
|
|---|
| 296 | document.getElementById('panelRegister').classList.toggle('active', tab === 'register');
|
|---|
| 297 | document.getElementById('tabLogin').classList.toggle('active', tab === 'login');
|
|---|
| 298 | document.getElementById('tabRegister').classList.toggle('active', tab === 'register');
|
|---|
| 299 | clearAlerts();
|
|---|
| 300 | }
|
|---|
| 301 |
|
|---|
| 302 | function clearAlerts() {
|
|---|
| 303 | ['loginError','loginSuccess','registerError','registerSuccess'].forEach(id => {
|
|---|
| 304 | const el = document.getElementById(id);
|
|---|
| 305 | el.classList.remove('show');
|
|---|
| 306 | el.textContent = '';
|
|---|
| 307 | });
|
|---|
| 308 | }
|
|---|
| 309 |
|
|---|
| 310 | function showAlert(id, msg) {
|
|---|
| 311 | const el = document.getElementById(id);
|
|---|
| 312 | el.textContent = msg;
|
|---|
| 313 | el.classList.add('show');
|
|---|
| 314 | }
|
|---|
| 315 |
|
|---|
| 316 | function setLoading(btnId, loading) {
|
|---|
| 317 | const btn = document.getElementById(btnId);
|
|---|
| 318 | if (loading) {
|
|---|
| 319 | btn.disabled = true;
|
|---|
| 320 | btn.innerHTML = '<span class="spinner"></span>Please wait...';
|
|---|
| 321 | } else {
|
|---|
| 322 | btn.disabled = false;
|
|---|
| 323 | btn.innerHTML = btnId === 'btnLogin' ? 'Sign In' : 'Create Account';
|
|---|
| 324 | }
|
|---|
| 325 | }
|
|---|
| 326 |
|
|---|
| 327 | // โโ Login โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|---|
| 328 | async function doLogin() {
|
|---|
| 329 | clearAlerts();
|
|---|
| 330 | const email = document.getElementById('loginEmail').value.trim();
|
|---|
| 331 | const password = document.getElementById('loginPassword').value;
|
|---|
| 332 |
|
|---|
| 333 | if (!email || !password) {
|
|---|
| 334 | showAlert('loginError', 'Please enter your email and password.');
|
|---|
| 335 | return;
|
|---|
| 336 | }
|
|---|
| 337 |
|
|---|
| 338 | setLoading('btnLogin', true);
|
|---|
| 339 | try {
|
|---|
| 340 | const res = await fetch(`${API}/api/auth/login`, {
|
|---|
| 341 | method: 'POST',
|
|---|
| 342 | headers: { 'Content-Type': 'application/json' },
|
|---|
| 343 | credentials: 'include',
|
|---|
| 344 | body: JSON.stringify({ email, password })
|
|---|
| 345 | });
|
|---|
| 346 | const data = await res.json();
|
|---|
| 347 |
|
|---|
| 348 | if (!res.ok) {
|
|---|
| 349 | showAlert('loginError', data.error || 'Login failed.');
|
|---|
| 350 | } else {
|
|---|
| 351 | showAlert('loginSuccess', `Welcome back, ${data.user.first_name}! Redirecting...`);
|
|---|
| 352 | setTimeout(() => { window.location.href = 'Wedding_Planner.html'; }, 900);
|
|---|
| 353 | }
|
|---|
| 354 | } catch (err) {
|
|---|
| 355 | showAlert('loginError', 'Cannot connect to server. Is it running?');
|
|---|
| 356 | } finally {
|
|---|
| 357 | setLoading('btnLogin', false);
|
|---|
| 358 | }
|
|---|
| 359 | }
|
|---|
| 360 |
|
|---|
| 361 | // โโ Register โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|---|
| 362 | async function doRegister() {
|
|---|
| 363 | clearAlerts();
|
|---|
| 364 | const first_name = document.getElementById('regFirst').value.trim();
|
|---|
| 365 | const last_name = document.getElementById('regLast').value.trim();
|
|---|
| 366 | const email = document.getElementById('regEmail').value.trim();
|
|---|
| 367 | const password = document.getElementById('regPassword').value;
|
|---|
| 368 | const phone_number = document.getElementById('regPhone').value.trim();
|
|---|
| 369 | const gender = document.getElementById('regGender').value;
|
|---|
| 370 | const birthday = document.getElementById('regBirthday').value;
|
|---|
| 371 |
|
|---|
| 372 | if (!first_name || !last_name || !email || !password) {
|
|---|
| 373 | showAlert('registerError', 'First name, last name, email and password are required.');
|
|---|
| 374 | return;
|
|---|
| 375 | }
|
|---|
| 376 | if (password.length < 6) {
|
|---|
| 377 | showAlert('registerError', 'Password must be at least 6 characters.');
|
|---|
| 378 | return;
|
|---|
| 379 | }
|
|---|
| 380 |
|
|---|
| 381 | setLoading('btnRegister', true);
|
|---|
| 382 | try {
|
|---|
| 383 | const res = await fetch(`${API}/api/auth/register`, {
|
|---|
| 384 | method: 'POST',
|
|---|
| 385 | headers: { 'Content-Type': 'application/json' },
|
|---|
| 386 | credentials: 'include',
|
|---|
| 387 | body: JSON.stringify({ first_name, last_name, email, password, phone_number, gender, birthday })
|
|---|
| 388 | });
|
|---|
| 389 | const data = await res.json();
|
|---|
| 390 |
|
|---|
| 391 | if (!res.ok) {
|
|---|
| 392 | showAlert('registerError', data.error || 'Registration failed.');
|
|---|
| 393 | } else {
|
|---|
| 394 | showAlert('registerSuccess', `Account created! Welcome, ${data.user.first_name}! Redirecting...`);
|
|---|
| 395 | setTimeout(() => { window.location.href = 'Wedding_Planner.html'; }, 1200);
|
|---|
| 396 | }
|
|---|
| 397 | } catch (err) {
|
|---|
| 398 | showAlert('registerError', 'Cannot connect to server. Is it running?');
|
|---|
| 399 | } finally {
|
|---|
| 400 | setLoading('btnRegister', false);
|
|---|
| 401 | }
|
|---|
| 402 | }
|
|---|
| 403 |
|
|---|
| 404 | // โโ Allow Enter key to submit โโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|---|
| 405 | document.addEventListener('keydown', e => {
|
|---|
| 406 | if (e.key === 'Enter') {
|
|---|
| 407 | const loginActive = document.getElementById('panelLogin').classList.contains('active');
|
|---|
| 408 | if (loginActive) doLogin(); else doRegister();
|
|---|
| 409 | }
|
|---|
| 410 | });
|
|---|
| 411 | </script>
|
|---|
| 412 | </body>
|
|---|
| 413 | </html>
|
|---|