This commit is contained in:
fullofempt
2025-12-14 18:47:14 +05:00
parent bb833d956e
commit 433b9e896c
18 changed files with 2891 additions and 1260 deletions

View File

@@ -5,71 +5,133 @@ import { useRouter } from "next/navigation";
const AuthContext = createContext(null);
// фейковые пользователи (3 логина/пароля)
const USERS = [
{
id: 1,
role: "user", // обычный пользователь
name: "Пользователь",
login: "user@mail.com",
password: "user123",
},
{
id: 2,
role: "volunteer",
name: "Волонтёр",
login: "vol@mail.com",
password: "vol123",
},
{
id: 3,
role: "moderator",
name: "Модератор",
login: "mod@mail.com",
password: "mod123",
},
];
// базовый URL из YAML (у себя можешь вынести в .env)
const API_BASE = process.env.NEXT_PUBLIC_API_BASE_URL;
export const AuthProvider = ({ children }) => {
const [user, setUser] = useState(null); // {id, role, name, login}
const [user, setUser] = useState(null); // {id, email, role, name, accessToken, refreshToken}
const [loading, setLoading] = useState(true);
const router = useRouter();
// Поднимаем пользователя из localStorage, чтобы контекст сохранялся между перезагрузками
// поднимаем пользователя из localStorage
useEffect(() => {
const saved = typeof window !== "undefined" ? localStorage.getItem("authUser") : null;
const saved =
typeof window !== "undefined"
? localStorage.getItem("authUser")
: null;
if (saved) {
setUser(JSON.parse(saved));
}
setLoading(false);
}, []);
const login = async (login, password) => {
// имитация запроса на бэк
const found = USERS.find(
(u) => u.login === login && u.password === password
);
if (!found) {
throw new Error("Неверный логин или пароль");
// основная авторизация: запрос на /auth/login
const login = async (email, password) => {
const res = await fetch(`${API_BASE}/auth/login`, {
method: "POST",
headers: {
"Content-Type": "application/json",
Accept: "application/json",
},
body: JSON.stringify({ email, password }),
});
// удобно смотреть в Postman: этот же URL, метод, тело из JSON[file:519]
// в Postman просто скопируй URL и тело — увидишь точный JSON-ответ
if (!res.ok) {
// читаем тело как текст, чтобы в консоли / Postman было понятно
let errorMessage = "Неверный логин или пароль";
try {
const data = await res.json();
if (data.error) {
errorMessage = data.error;
}
} catch {
const text = await res.text();
if (text) errorMessage = text;
}
throw new Error(errorMessage);
}
const data = await res.json();
// ожидаемый формат по YAML: AuthResponse[file:519]
// Примерно:
// {
// "access_token": "...",
// "refresh_token": "...",
// "token_type": "bearer",
// "user": { "id": 1, "email": "...", ... }
// }
const authUser = {
id: found.id,
role: found.role,
name: found.name,
login: found.login,
id: data.user?.id,
email: data.user?.email,
name: data.user?.first_name || data.user?.email,
// роль пока не знаем наверняка — вытащим отдельным запросом
role: null,
accessToken: data.access_token,
refreshToken: data.refresh_token,
};
// 1) сохраняем токены/пользователя
setUser(authUser);
localStorage.setItem("authUser", JSON.stringify(authUser));
// после логина перенаправляем на стартовую страницу по роли
if (found.role === "user") router.push("/home");
if (found.role === "volunteer") router.push("/mainValounter");
if (found.role === "moderator") router.push("/moderatorMain");
// 2) тянем роли пользователя (GET /users/me/roles)[file:519]
try {
const rolesRes = await fetch(`${API_BASE}/users/me/roles`, {
method: "GET",
headers: {
Authorization: `Bearer ${data.access_token}`,
Accept: "application/json",
},
});
if (rolesRes.ok) {
const roles = await rolesRes.json(); // массив объектов Role[file:519]
// ищем первую подходящую роль
const roleNames = roles.map((r) => r.name);
let appRole = null;
if (roleNames.includes("requester")) appRole = "requester";
if (roleNames.includes("volunteer")) appRole = "volunteer";
if (roleNames.includes("moderator")) appRole = "moderator";
if (roleNames.includes("admin")) appRole = "moderator"; // можно перекинуть в модераторский интерфейс
const updatedUser = { ...authUser, role: appRole };
setUser(updatedUser);
localStorage.setItem("authUser", JSON.stringify(updatedUser));
// 3) редирект по роли (как у тебя было)
if (appRole === "requester") router.push("/home");
else if (appRole === "volunteer") router.push("/mainValounter");
else if (appRole === "moderator") router.push("/moderatorMain");
else router.push("/home"); // запасной вариант
} else {
// если роли не достали, всё равно пускаем как обычного пользователя
router.push("/home");
}
} catch (e) {
console.error("Ошибка получения ролей:", e);
router.push("/home");
}
};
const logout = () => {
const logout = async () => {
try {
if (user?.accessToken) {
await fetch(`${API_BASE}/auth/logout`, {
method: "POST",
headers: {
Authorization: `Bearer ${user.accessToken}`,
Accept: "application/json",
},
});
}
} catch (e) {
console.error("Ошибка logout:", e);
}
setUser(null);
localStorage.removeItem("authUser");
router.push("/login");