From 67b50bf713e7d30c285b08d813c49fc432480afc Mon Sep 17 00:00:00 2001 From: lekss361 Date: Mon, 13 Jul 2026 21:16:29 +0000 Subject: [PATCH] feat(tradein/ui): admin links to audit + analytics in UserMenu (#2524) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Admin-only «Аудит доступа» → /admin/audit and «Активность» → /admin/analytics links in the UserMenu dropdown. Navigates via API_BASE_URL prefix (Topbar convention, basePath-safe). Pilot menu unchanged. --- .../frontend/src/components/auth/UserMenu.tsx | 94 +++++++++++++++++++ 1 file changed, 94 insertions(+) diff --git a/tradein-mvp/frontend/src/components/auth/UserMenu.tsx b/tradein-mvp/frontend/src/components/auth/UserMenu.tsx index 3e7350b5..d8dd57ee 100644 --- a/tradein-mvp/frontend/src/components/auth/UserMenu.tsx +++ b/tradein-mvp/frontend/src/components/auth/UserMenu.tsx @@ -19,8 +19,10 @@ * покажется заново. */ +import type { CSSProperties } from "react"; import { useEffect, useRef, useState } from "react"; +import { API_BASE_URL } from "@/lib/api"; import { logout } from "@/lib/logout"; import { useMe } from "@/lib/useMe"; @@ -46,6 +48,69 @@ function LogOutIcon() { ); } +/** Inline Shield icon (lucide-react `Shield` SVG path, stroke 1.5) — для + admin-ссылки «Аудит доступа». Та же inline-SVG конвенция, что LogOutIcon + (tradein-mvp не тянет lucide-react в deps). */ +function ShieldIcon() { + return ( + + ); +} + +/** Inline BarChart icon (lucide-react `BarChart3` SVG path, stroke 1.5) — + для admin-ссылки «Активность». */ +function BarChartIcon() { + return ( + + ); +} + +/** Общий inline-стиль для admin-nav-пунктов дропдауна (Аудит/Активность) — + тот же паттерн, что «Выйти», но нейтральный цвет вместо var(--danger). */ +const adminMenuItemStyle: CSSProperties = { + display: "flex", + alignItems: "center", + gap: 8, + width: "100%", + background: "none", + border: "none", + padding: "4px 0", + cursor: "pointer", + color: "var(--fg-primary)", + fontWeight: 500, + fontSize: 14, + textAlign: "left", + fontFamily: "inherit", + textDecoration: "none", +}; + export function UserMenu() { const { data, isLoading, error } = useMe(); const [open, setOpen] = useState(false); @@ -159,6 +224,35 @@ export function UserMenu() { > {roleLabel} + {data.role === "admin" && ( + <> +
+ setOpen(false)} + style={adminMenuItemStyle} + > + + Аудит доступа + + setOpen(false)} + style={{ ...adminMenuItemStyle, marginTop: 4 }} + > + + Активность + + + )}