- Flask backend with TinyDB database - Multi-user auth with bcrypt password hashing - Goal CRUD with activation/deactivation and per-user limits - Task CRUD with status tracking (todo/doing/pending/done) - Focus rule: one doing task per goal - Time picker-style scroll view with drag-and-drop reordering - Admin panel for user management - uv environment management
93 lines
2.6 KiB
JavaScript
93 lines
2.6 KiB
JavaScript
async function checkAuth() {
|
|
try {
|
|
const user = await get("/api/auth/me");
|
|
const userInfo = document.getElementById("user-info");
|
|
if (userInfo) {
|
|
userInfo.textContent = user.username;
|
|
}
|
|
const adminLink = document.getElementById("admin-link");
|
|
if (adminLink && user.role === "admin") {
|
|
adminLink.style.display = "inline";
|
|
}
|
|
return user;
|
|
} catch (error) {
|
|
window.location.href = "/login";
|
|
return null;
|
|
}
|
|
}
|
|
|
|
async function handleLogin(event) {
|
|
event.preventDefault();
|
|
const form = event.target;
|
|
const errorMessage = document.getElementById("error-message");
|
|
errorMessage.textContent = "";
|
|
|
|
const username = form.username.value.trim();
|
|
const password = form.password.value;
|
|
|
|
try {
|
|
await post("/api/auth/login", { username, password });
|
|
window.location.href = "/goals";
|
|
} catch (error) {
|
|
errorMessage.textContent = error.message;
|
|
}
|
|
}
|
|
|
|
async function handleRegister(event) {
|
|
event.preventDefault();
|
|
const form = event.target;
|
|
const errorMessage = document.getElementById("error-message");
|
|
errorMessage.textContent = "";
|
|
|
|
const username = form.username.value.trim();
|
|
const password = form.password.value;
|
|
const confirmPassword = form["confirm-password"].value;
|
|
|
|
if (password !== confirmPassword) {
|
|
errorMessage.textContent = "Passwords do not match";
|
|
return;
|
|
}
|
|
|
|
if (password.length < 6) {
|
|
errorMessage.textContent = "Password must be at least 6 characters";
|
|
return;
|
|
}
|
|
|
|
try {
|
|
await post("/api/auth/register", { username, password });
|
|
window.location.href = "/goals";
|
|
} catch (error) {
|
|
errorMessage.textContent = error.message;
|
|
}
|
|
}
|
|
|
|
async function handleLogout() {
|
|
try {
|
|
await post("/api/auth/logout");
|
|
window.location.href = "/login";
|
|
} catch (error) {
|
|
console.error("Logout failed:", error);
|
|
}
|
|
}
|
|
|
|
document.addEventListener("DOMContentLoaded", () => {
|
|
const loginForm = document.getElementById("login-form");
|
|
if (loginForm) {
|
|
loginForm.addEventListener("submit", handleLogin);
|
|
}
|
|
|
|
const registerForm = document.getElementById("register-form");
|
|
if (registerForm) {
|
|
registerForm.addEventListener("submit", handleRegister);
|
|
}
|
|
|
|
const logoutBtn = document.getElementById("logout-btn");
|
|
if (logoutBtn) {
|
|
logoutBtn.addEventListener("click", handleLogout);
|
|
}
|
|
|
|
if (!document.body.classList.contains("auth-page")) {
|
|
checkAuth();
|
|
}
|
|
});
|