caddydash/frontend/js/login.js
wjqserver b10790c212 init
2025-06-20 16:33:27 +08:00

89 lines
No EOL
3.5 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

document.addEventListener('DOMContentLoaded', () => {
const DOMElements = {
loginForm: document.getElementById('login-form'),
toastContainer: document.getElementById('toast-container'),
};
const loginButton = DOMElements.loginForm.querySelector('button[type="submit"]');
const LOGIN_API_URL = '/v0/api/auth/login';
const theme = {
init: () => {
const storedTheme = localStorage.getItem('theme');
const systemPrefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
const currentTheme = storedTheme || (systemPrefersDark ? 'dark' : 'light');
document.documentElement.dataset.theme = currentTheme;
}
};
const toast = {
show: (message, type = 'info', duration = 3000) => {
const icons = { success: 'fa-check-circle', error: 'fa-times-circle', info: 'fa-info-circle' };
const iconClass = icons[type] || 'fa-info-circle';
const toastElement = document.createElement('div');
toastElement.className = `toast ${type}`;
toastElement.innerHTML = `<i class="toast-icon fa-solid ${iconClass}"></i><p class="toast-message">${message}</p><button class="toast-close" data-toast-close>×</button>`;
DOMElements.toastContainer.appendChild(toastElement);
requestAnimationFrame(() => toastElement.classList.add('show'));
const timeoutId = setTimeout(() => hideToast(toastElement), duration);
toastElement.querySelector('[data-toast-close]').addEventListener('click', () => {
clearTimeout(timeoutId);
hideToast(toastElement);
});
}
};
function hideToast(toastElement) {
if (!toastElement) return;
toastElement.classList.remove('show');
toastElement.addEventListener('transitionend', () => toastElement.remove(), { once: true });
}
async function handleLogin(e) {
e.preventDefault();
// 获取并确认值
const username = DOMElements.loginForm.username.value.trim();
const password = DOMElements.loginForm.password.value.trim();
if (username === '') {
toast.show('用户名不能为空', 'error');
DOMElements.loginForm.username.focus();
return;
}
if (password === '') {
toast.show('密码不能为空', 'error');
DOMElements.loginForm.password.focus();
return;
}
loginButton.disabled = true;
loginButton.querySelector('span').textContent = '登录中...';
try {
const response = await fetch(LOGIN_API_URL, {
method: 'POST',
body: new URLSearchParams(new FormData(DOMElements.loginForm))
});
const result = await response.json();
if (response.ok) {
toast.show('登录成功,正在跳转...', 'success');
setTimeout(() => { window.location.href = '/'; }, 500);
} else {
throw new Error(result.error || `登录失败: ${response.status}`);
}
} catch (error) {
toast.show(error.message, 'error');
loginButton.disabled = false;
loginButton.querySelector('span').textContent = '登录';
}
}
function init() {
theme.init();
if (DOMElements.loginForm) {
DOMElements.loginForm.addEventListener('submit', handleLogin);
}
}
init();
});