WIP API
This commit is contained in:
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user