feat(tyres): доступ к выдаче резины по праву склада, не только админам
Плитка «Выдача резины» и маршруты /wh/tyres* открываются по признаку warehouse:tyres из /me (или is_admin) — новый гейт RequireTyres вместо RequireAdmin. Приёмка/инвентаризация остаются админскими. Бэкенд: право warehouse.tyres в crm2. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -44,6 +44,22 @@ function RequireAdmin({ children }: { children: React.ReactNode }) {
|
||||
return <>{children}</>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Выдача резины — по складскому праву (warehouse:tyres в /me), не только
|
||||
* админам. Приёмка и инвентаризация остаются под RequireAdmin.
|
||||
*/
|
||||
function RequireTyres({ children }: { children: React.ReactNode }) {
|
||||
const token = useAuth((s) => s.token);
|
||||
const meQuery = useQuery({ queryKey: ["me"], queryFn: getMe, staleTime: 60_000, enabled: !!token });
|
||||
if (!token) return <Navigate to="/login" replace />;
|
||||
if (meQuery.isLoading) return null;
|
||||
const me = meQuery.data;
|
||||
if (!me?.is_admin && !me?.permissions?.includes("warehouse:tyres")) {
|
||||
return <Navigate to="/" replace />;
|
||||
}
|
||||
return <>{children}</>;
|
||||
}
|
||||
|
||||
export default function App() {
|
||||
// У35: фоновая сверка прав механика раз в 5 минут — выкидывает на /login
|
||||
// с сообщением «Доступ отозван», если админ снял can_login_pwa или вывел
|
||||
@@ -72,10 +88,10 @@ export default function App() {
|
||||
<Route path="/wh/receipts/:id" element={<RequireAdmin><ReceiptDetailPage /></RequireAdmin>} />
|
||||
<Route path="/wh/stocktake" element={<RequireAdmin><StocktakePage /></RequireAdmin>} />
|
||||
<Route path="/wh/stocktake/:id" element={<RequireAdmin><StocktakeSessionPage /></RequireAdmin>} />
|
||||
{/* Сезонная выдача резины — тот же круг, что приёмка и инвентаризация. */}
|
||||
<Route path="/wh/tyres" element={<RequireAdmin><TyresPage /></RequireAdmin>} />
|
||||
<Route path="/wh/tyres/sizes" element={<RequireAdmin><TyreSizesPage /></RequireAdmin>} />
|
||||
<Route path="/wh/tyres/journal" element={<RequireAdmin><TyreJournalPage /></RequireAdmin>} />
|
||||
{/* Сезонная выдача резины — по складскому праву (не только админам). */}
|
||||
<Route path="/wh/tyres" element={<RequireTyres><TyresPage /></RequireTyres>} />
|
||||
<Route path="/wh/tyres/sizes" element={<RequireTyres><TyreSizesPage /></RequireTyres>} />
|
||||
<Route path="/wh/tyres/journal" element={<RequireTyres><TyreJournalPage /></RequireTyres>} />
|
||||
<Route path="*" element={<Navigate to="/" replace />} />
|
||||
</Routes>
|
||||
);
|
||||
|
||||
@@ -34,7 +34,7 @@ export default function ActionMenu() {
|
||||
emoji: "🔧",
|
||||
onClick: () => navigate("/repairs"),
|
||||
},
|
||||
// Складские разделы правят остатки и деньги — пока только админам
|
||||
// Приёмка и инвентаризация правят остатки и деньги — пока только админам
|
||||
// (тот же гейт стоит на сервере, здесь просто не показываем лишнего).
|
||||
...(meQuery.data?.is_admin
|
||||
? [
|
||||
@@ -52,6 +52,12 @@ export default function ActionMenu() {
|
||||
emoji: "📋",
|
||||
onClick: () => navigate("/wh/stocktake"),
|
||||
},
|
||||
]
|
||||
: []),
|
||||
// Выдача резины — по складскому праву (не только админам): признак
|
||||
// warehouse:tyres приходит в /me, если у механика есть право склада.
|
||||
...(meQuery.data?.is_admin || meQuery.data?.permissions?.includes("warehouse:tyres")
|
||||
? [
|
||||
{
|
||||
key: "tyres",
|
||||
title: "Выдача резины",
|
||||
|
||||
Reference in New Issue
Block a user