diff --git a/devfront/src/components/layout/AppLayout.tsx b/devfront/src/components/layout/AppLayout.tsx index c3a2d809..515fe28e 100644 --- a/devfront/src/components/layout/AppLayout.tsx +++ b/devfront/src/components/layout/AppLayout.tsx @@ -1,8 +1,11 @@ -import { BadgeCheck, Moon, ShieldHalf, Sun } from "lucide-react"; +import { BadgeCheck, LogOut, Moon, ShieldHalf, Sun, User } from "lucide-react"; import { useEffect, useState } from "react"; +import { useAuth } from "react-oidc-context"; import { NavLink, Outlet } from "react-router-dom"; +import { useQuery } from "@tanstack/react-query"; import { t } from "../../lib/i18n"; import { Toaster } from "../ui/toaster"; +import { fetchMe } from "../../features/auth/authApi"; const navItems = [ { @@ -14,10 +17,17 @@ const navItems = [ ]; function AppLayout() { - const [theme, setTheme] = useState<"light" | "dark">(() => { - const stored = window.localStorage.getItem("admin_theme"); - return stored === "dark" ? "dark" : "light"; - }); + const auth = useAuth(); + const { data: profile } = useQuery({ + queryKey: ["me"], + queryFn: fetchMe, + enabled: auth.isAuthenticated, + }); + + const [theme, setTheme] = useState<"light" | "dark">(() => { + const stored = window.localStorage.getItem("admin_theme"); + return stored === "dark" ? "dark" : "light"; + }); useEffect(() => { const root = document.documentElement; @@ -30,9 +40,20 @@ function AppLayout() { window.localStorage.setItem("admin_theme", theme); }, [theme]); - const toggleTheme = () => { - setTheme((prev) => (prev === "light" ? "dark" : "light")); - }; + const toggleTheme = () => { + setTheme((prev) => (prev === "light" ? "dark" : "light")); + }; + + const handleLogout = () => { + auth.signoutRedirect(); + }; + + // Set initial tenant ID if profile is loaded and no tenant is selected + useEffect(() => { + if (profile?.tenantId && !window.localStorage.getItem("dev_tenant_id")) { + window.localStorage.setItem("dev_tenant_id", profile.tenantId); + } + }, [profile]); return (
@@ -61,6 +82,11 @@ function AppLayout() { {t("ui.dev.env_badge", "Env: dev")} + {profile?.tenant && ( + + Tenant: {profile.tenant.name} + + )}
{navItems.map(({ labelKey, labelFallback, to, icon: Icon }) => ( @@ -116,6 +142,16 @@ function AppLayout() { ? t("ui.common.theme_light", "Light") : t("ui.common.theme_dark", "Dark")} + {auth.isAuthenticated && ( + + )}
diff --git a/devfront/src/components/ui/toaster.tsx b/devfront/src/components/ui/toaster.tsx index 864901c9..0c2640c3 100644 --- a/devfront/src/components/ui/toaster.tsx +++ b/devfront/src/components/ui/toaster.tsx @@ -1,4 +1,5 @@ -import { AlertCircle, CheckCircle2, Info } from "lucide-react"; +import { CheckCircle2, AlertCircle, Info } from "lucide-react"; + import { cn } from "../../lib/utils"; import { useToastState } from "./use-toast";