1
0
forked from baron/baron-sso

인증 상태에 따른 레이아웃 및 UI 개선

This commit is contained in:
2026-02-11 17:34:26 +09:00
parent 7a25cf40aa
commit c23e0c925a
2 changed files with 46 additions and 9 deletions

View File

@@ -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 (
<div className="grid min-h-screen bg-background text-foreground md:grid-cols-[240px,1fr]">
@@ -61,6 +82,11 @@ function AppLayout() {
<span className="rounded-full border border-border px-3 py-1">
{t("ui.dev.env_badge", "Env: dev")}
</span>
{profile?.tenant && (
<span className="rounded-full bg-primary/10 px-3 py-1 text-primary border border-primary/20">
Tenant: {profile.tenant.name}
</span>
)}
</div>
<div className="flex flex-col gap-1">
{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")}
</button>
{auth.isAuthenticated && (
<button
type="button"
onClick={handleLogout}
className="inline-flex items-center gap-2 rounded-full border border-destructive/20 bg-destructive/5 px-3 py-2 text-destructive transition hover:bg-destructive/10"
>
<LogOut size={16} />
Logout
</button>
)}
</div>
</div>
</header>

View File

@@ -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";