login.js 2.4 KB

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