login.js 2.2 KB

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