login.js 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. const loginForm = document.querySelector('#loginForm');
  2. const registerForm = document.querySelector('#registerForm');
  3. const message = document.querySelector('#loginMessage');
  4. const modeTitle = document.querySelector('#modeTitle');
  5. const modeEyebrow = document.querySelector('#modeEyebrow');
  6. const tabs = document.querySelectorAll('[data-mode]');
  7. for (const tab of tabs) {
  8. tab.addEventListener('click', () => setMode(tab.dataset.mode));
  9. }
  10. loginForm.addEventListener('submit', async (event) => {
  11. event.preventDefault();
  12. await submitAuth('/api/login', loginForm, loginForm.querySelector('button'));
  13. });
  14. registerForm.addEventListener('submit', async (event) => {
  15. event.preventDefault();
  16. await submitAuth('/api/register', registerForm, registerForm.querySelector('button'));
  17. });
  18. if (window.location.pathname === '/register') setMode('register');
  19. function setMode(mode) {
  20. const registering = mode === 'register';
  21. loginForm.classList.toggle('hidden', registering);
  22. registerForm.classList.toggle('hidden', !registering);
  23. modeTitle.textContent = registering ? '注册账号' : '登录控制台';
  24. modeEyebrow.textContent = registering ? 'Register' : 'Sign in';
  25. for (const tab of tabs) tab.classList.toggle('active', tab.dataset.mode === mode);
  26. message.textContent = '';
  27. message.className = 'login-message';
  28. const input = (registering ? registerForm : loginForm).querySelector('input');
  29. input?.focus();
  30. }
  31. async function submitAuth(path, form, button) {
  32. message.textContent = '';
  33. message.className = 'login-message';
  34. button.disabled = true;
  35. try {
  36. const payload = Object.fromEntries(new FormData(form).entries());
  37. const response = await fetch(path, {
  38. method: 'POST',
  39. headers: { 'Content-Type': 'application/json' },
  40. body: JSON.stringify(payload)
  41. });
  42. const data = await response.json().catch(() => ({}));
  43. if (!response.ok) throw new Error(data.error || '请求失败。');
  44. window.location.href = '/';
  45. } catch (error) {
  46. message.textContent = error.message;
  47. message.classList.add('error');
  48. } finally {
  49. button.disabled = false;
  50. }
  51. }