This commit is contained in:
Андрей Дувакин 2024-10-07 17:03:24 +05:00
parent 7e2bfc7489
commit 732809a25f
12 changed files with 78 additions and 21 deletions

View File

@ -10,20 +10,24 @@ import Statuses from "./pages/Statuses.jsx";
import Trucks from "./pages/Trucks.jsx"; import Trucks from "./pages/Trucks.jsx";
import Users from "./pages/Users.jsx"; import Users from "./pages/Users.jsx";
import DeliveryOrderDetails from "./pages/DeliveryOrderDetails.jsx"; import DeliveryOrderDetails from "./pages/DeliveryOrderDetails.jsx";
import RoleRoute from "./components/RoleRoute.jsx";
const RoutesComponent = () => ( const RoutesComponent = () => (
<Routes> <Routes>
<Route path="/login" element={<Login />} /> <Route path="/login" element={<Login />} />
<Route element={<PrivateRoute />}> <Route element={<PrivateRoute />}>
<Route path="/" element={<Home />} /> <Route path="/" element={<Home />} />
<Route path="/accessories" element={<Accessories />} />
<Route path="/cities" element={<Cities />} />
<Route path="/federal_districts" element={<FederalDistricts />} />
<Route path="/roles" element={<Roles />} />
<Route path="/statuses" element={<Statuses />} />
<Route path="/trucks" element={<Trucks />} />
<Route path="/users" element={<Users />} />
<Route path="/sub-orders/:id" element={<DeliveryOrderDetails />} /> <Route path="/sub-orders/:id" element={<DeliveryOrderDetails />} />
<Route element={<RoleRoute allowedRoles={["Администратор"]} />}>
<Route path="/accessories" element={<Accessories />} />
<Route path="/cities" element={<Cities />} />
<Route path="/federal_districts" element={<FederalDistricts />} />
<Route path="/roles" element={<Roles />} />
<Route path="/statuses" element={<Statuses />} />
<Route path="/trucks" element={<Trucks />} />
<Route path="/users" element={<Users />} />
</Route>
</Route> </Route>
</Routes> </Routes>
); );

View File

@ -12,8 +12,14 @@ export const AuthProvider = ({ children }) => {
return savedAuth === "true"; return savedAuth === "true";
}); });
const [role, setRole] = useState(() => {
const savedUser = localStorage.getItem("user");
return savedUser ? JSON.parse(savedUser).role : null;
});
const login = (userData) => { const login = (userData) => {
setIsAuthenticated(true); setIsAuthenticated(true);
setRole(userData.user.role_name);
localStorage.setItem("token", userData.token); localStorage.setItem("token", userData.token);
localStorage.setItem("user", JSON.stringify(userData.user)); localStorage.setItem("user", JSON.stringify(userData.user));
localStorage.setItem("isAuthenticated", true); localStorage.setItem("isAuthenticated", true);
@ -21,6 +27,7 @@ export const AuthProvider = ({ children }) => {
const logout = () => { const logout = () => {
setIsAuthenticated(false); setIsAuthenticated(false);
setRole(null);
localStorage.removeItem("token"); localStorage.removeItem("token");
localStorage.removeItem("isAuthenticated"); localStorage.removeItem("isAuthenticated");
localStorage.removeItem("user"); localStorage.removeItem("user");
@ -31,7 +38,7 @@ export const AuthProvider = ({ children }) => {
}, [isAuthenticated]); }, [isAuthenticated]);
return ( return (
<AuthContext.Provider value={{ isAuthenticated, login, logout }}> <AuthContext.Provider value={{ isAuthenticated, role, login, logout }}>
{children} {children}
</AuthContext.Provider> </AuthContext.Provider>
); );

View File

@ -0,0 +1,19 @@
import React from "react";
import { Navigate, Outlet } from "react-router-dom";
import { useAuth } from "../AuthContext";
const RoleRoute = ({ allowedRoles }) => {
const { isAuthenticated, role } = useAuth();
if (!isAuthenticated) {
return <Navigate to="/login" />;
}
if (allowedRoles && !allowedRoles.includes(role)) {
return <Navigate to="/" />;
}
return <Outlet />;
};
export default RoleRoute;

View File

@ -35,6 +35,9 @@ const Accessories = () => {
const data = await getAccessories(); const data = await getAccessories();
setAccessories(data); setAccessories(data);
} catch (error) { } catch (error) {
if (error.response && error.response.status === 401) {
navigate("/login");
}
console.error("Ошибка при загрузке аксессуаров:", error); console.error("Ошибка при загрузке аксессуаров:", error);
} }
}; };
@ -44,6 +47,9 @@ const Accessories = () => {
const data = await getCities(); const data = await getCities();
setCities(data); setCities(data);
} catch (error) { } catch (error) {
if (error.response && error.response.status === 401) {
navigate("/login");
}
console.error("Ошибка при загрузке городов:", error); console.error("Ошибка при загрузке городов:", error);
} }
}; };

View File

@ -1,7 +1,6 @@
import React, { useState, useEffect } from "react"; import React, { useState, useEffect } from "react";
import SelectionDialog from "../components/SelectionDialog.jsx"; import SelectionDialog from "../components/SelectionDialog.jsx";
import { useNavigate } from "react-router-dom"; import { useNavigate } from "react-router-dom";
import { getAuthToken } from "../api.jsx";
import { getCoordinates } from "../geocoder.jsx"; import { getCoordinates } from "../geocoder.jsx";
import { import {
getCities, getCities,
@ -37,6 +36,9 @@ const Cities = () => {
const data = await getCities(); const data = await getCities();
setCities(data); setCities(data);
} catch (error) { } catch (error) {
if (error.response && error.response.status === 401) {
navigate("/login");
}
console.error("Ошибка при загрузке городов:", error); console.error("Ошибка при загрузке городов:", error);
} }
}; };
@ -46,6 +48,9 @@ const Cities = () => {
const data = await getFederalDistricts(); const data = await getFederalDistricts();
setFederalDistricts(data); setFederalDistricts(data);
} catch (error) { } catch (error) {
if (error.response && error.response.status === 401) {
navigate("/login");
}
console.error("Ошибка при загрузке федеральных округов:", error); console.error("Ошибка при загрузке федеральных округов:", error);
} }
}; };
@ -144,10 +149,6 @@ const Cities = () => {
setShowDistrictDialog(false); setShowDistrictDialog(false);
}; };
if (getAuthToken() === null) {
navigate("/login");
}
return ( return (
<div className="container mt-4"> <div className="container mt-4">
<h3>Города</h3> <h3>Города</h3>

View File

@ -54,6 +54,9 @@ const DeliveryOrderDetails = () => {
longitude: accessory.longitude, longitude: accessory.longitude,
}; };
} else { } else {
if (error.response && error.response.status === 401) {
navigate("/login");
}
const coords = await getCoordinates(accessory.city_name); const coords = await getCoordinates(accessory.city_name);
return { city: accessory.city_name, ...coords }; return { city: accessory.city_name, ...coords };
} }

View File

@ -82,10 +82,6 @@ const FederalDistricts = () => {
setEditingDistrictId(null); setEditingDistrictId(null);
}; };
if (getAuthToken() === null) {
navigate("/login");
}
return ( return (
<div className="container mt-4"> <div className="container mt-4">
<h3>Федеральные округа</h3> <h3>Федеральные округа</h3>

View File

@ -12,7 +12,7 @@ const Home = () => {
const [expandedOrderId, setExpandedOrderId] = useState(null); const [expandedOrderId, setExpandedOrderId] = useState(null);
const [loadingStatuses, setLoadingStatuses] = useState(true); const [loadingStatuses, setLoadingStatuses] = useState(true);
const [loadingOrders, setLoadingOrders] = useState(true); const [loadingOrders, setLoadingOrders] = useState(true);
const [loadingCreateOrder, setLoadingCreateOrder] = useState(false); const [loadingCreateOrder, setLoadingCreateOrder] = useState(false);
const [deliveryOrdersCount, setDeliveryOrdersCount] = useState(0); const [deliveryOrdersCount, setDeliveryOrdersCount] = useState(0);
const [deadline, setDeadline] = useState(new Date()); const [deadline, setDeadline] = useState(new Date());
const navigate = useNavigate(); const navigate = useNavigate();
@ -28,6 +28,9 @@ const Home = () => {
const data = await getStatuses(); const data = await getStatuses();
setStatuses(data); setStatuses(data);
} catch (error) { } catch (error) {
if (error.response && error.response.status === 401) {
navigate("/login");
}
console.error("Ошибка при загрузке статусов:", error); console.error("Ошибка при загрузке статусов:", error);
} finally { } finally {
setLoadingStatuses(false); setLoadingStatuses(false);
@ -39,6 +42,9 @@ const Home = () => {
const orders = await getTotalOrders(); const orders = await getTotalOrders();
setTotalOrders(orders); setTotalOrders(orders);
} catch (error) { } catch (error) {
if (error.response && error.response.status === 401) {
navigate("/login");
}
console.error("Ошибка при загрузке заказов:", error); console.error("Ошибка при загрузке заказов:", error);
} finally { } finally {
setLoadingOrders(false); setLoadingOrders(false);
@ -46,7 +52,7 @@ const Home = () => {
}; };
const handleCreateOrder = async () => { const handleCreateOrder = async () => {
setLoadingCreateOrder(true); setLoadingCreateOrder(true);
try { try {
await calculateTotalOrder(); await calculateTotalOrder();
alert("Начался расчет маршрутов. Заказ скоро появится в списке заказов."); alert("Начался расчет маршрутов. Заказ скоро появится в списке заказов.");
@ -54,7 +60,7 @@ const Home = () => {
} catch (error) { } catch (error) {
console.error("Ошибка при расчете заказа:", error); console.error("Ошибка при расчете заказа:", error);
} finally { } finally {
setLoadingCreateOrder(false); setLoadingCreateOrder(false);
} }
}; };
@ -88,7 +94,7 @@ const Home = () => {
<button <button
className="btn btn-primary" className="btn btn-primary"
onClick={handleCreateOrder} onClick={handleCreateOrder}
disabled={loadingCreateOrder || loadingStatuses} disabled={loadingCreateOrder || loadingStatuses}
> >
{loadingCreateOrder ? ( {loadingCreateOrder ? (
<> <>

View File

@ -21,6 +21,9 @@ const Roles = () => {
const data = await getRoles(); const data = await getRoles();
setRoles(data); setRoles(data);
} catch (error) { } catch (error) {
if (error.response && error.response.status === 401) {
navigate("/login");
}
console.error("Ошибка при загрузке ролей:", error); console.error("Ошибка при загрузке ролей:", error);
} }
}; };

View File

@ -26,6 +26,9 @@ const Statuses = () => {
const data = await getStatuses(); const data = await getStatuses();
setStatuses(data); setStatuses(data);
} catch (error) { } catch (error) {
if (error.response && error.response.status === 401) {
navigate("/login");
}
console.error("Ошибка при загрузке статусов:", error); console.error("Ошибка при загрузке статусов:", error);
} }
}; };

View File

@ -23,6 +23,9 @@ const Trucks = () => {
const data = await getTrucks(); const data = await getTrucks();
setTrucks(data); setTrucks(data);
} catch (error) { } catch (error) {
if (error.response && error.response.status === 401) {
navigate("/login");
}
console.error("Ошибка при загрузке грузовиков:", error); console.error("Ошибка при загрузке грузовиков:", error);
} }
}; };

View File

@ -36,6 +36,9 @@ const Users = () => {
console.log(data); console.log(data);
setUsers(data); setUsers(data);
} catch (error) { } catch (error) {
if (error.response && error.response.status === 401) {
navigate("/login");
}
console.error("Ошибка при загрузке пользователей:", error); console.error("Ошибка при загрузке пользователей:", error);
} }
}; };
@ -45,6 +48,9 @@ const Users = () => {
const data = await getRoles(); const data = await getRoles();
setRoles(data); setRoles(data);
} catch (error) { } catch (error) {
if (error.response && error.response.status === 401) {
navigate("/login");
}
console.error("Ошибка при загрузке ролей:", error); console.error("Ошибка при загрузке ролей:", error);
} }
}; };