website_content / frontend /src /stores /authStore.jsx
Administrator
Claude Opus 5
fix(api): 7 màn còn lại dùng chung lớp đọc JSON an toàn
d94104e
Raw History Blame Contribute Delete
2.1 kB
import { createContext, useContext, useState, useEffect, useCallback } from "react";
import { jpost } from "../api";
const AuthContext = createContext(null);
export function AuthProvider({ children }) {
const [user, setUser] = useState(() => localStorage.getItem("tnt_user") || "");
const [authorized, setAuthorized] = useState(() => localStorage.getItem("tnt_auth") === "true");
const [uid, setUid] = useState(() => localStorage.getItem("tnt_uid") || "");
useEffect(() => {
localStorage.setItem("tnt_user", user);
localStorage.setItem("tnt_auth", authorized ? "true" : "");
// Mã U00N dùng làm user_id trong log (ngắn, ổn định). Thiếu mã -> để rỗng,
// track.js tự lùi về tên đăng nhập.
localStorage.setItem("tnt_uid", uid || "");
}, [user, authorized, uid]);
const login = useCallback(async (username) => {
try {
const data = await jpost("/api/auth/login", { username: username.trim() });
if (data.authorized) {
setUser(username.trim());
setUid(data.code || "");
setAuthorized(true);
return { ok: true };
}
setUser("");
setAuthorized(false);
// `denied` = máy chủ trả lời rành mạch "tài khoản này chưa được cấp quyền".
// Phân biệt với trường hợp máy chủ trục trặc ở catch bên dưới — hai thứ
// này cần hai câu khác nhau, và chỉ cái đầu mới nên gửi yêu cầu cấp quyền.
return { ok: false, denied: true, error: "Bạn chưa được cấp quyền truy cập. Liên hệ quản trị viên." };
} catch (e) {
return { ok: false, error: e.message };
}
}, []);
const logout = useCallback(() => {
setUser("");
setUid("");
setAuthorized(false);
}, []);
return (
<AuthContext.Provider value={{ user, uid, authorized, login, logout }}>
{children}
</AuthContext.Provider>
);
}
export function useAuth() {
const ctx = useContext(AuthContext);
if (!ctx) throw new Error("useAuth must be inside AuthProvider");
return ctx;
}