-
-
-
-
-
- {t("ui.admin.brand", "Baron 로그인")}
-
-
- {t("ui.admin.title", "Admin Control")}
-
-
+ LayoutGrid,
+ LogOut,
+ Moon,
+ NotebookTabs,
+ Rocket,
+ ShieldHalf,
+ Sun,
+ Users,
+} from "lucide-react";
+import { useEffect, useState } from "react";
+import { NavLink, Outlet, useNavigate } from "react-router-dom";
+import { t } from "../../lib/i18n";
+import RoleSwitcher from "./RoleSwitcher";
+
+const navItems = [
+ { label: "ui.admin.nav.overview", to: "/", icon: LayoutDashboard },
+ {
+ label: "ui.admin.nav.tenant_dashboard",
+ to: "/dashboard",
+ icon: ShieldHalf,
+ },
+ {
+ label: "ui.admin.nav.tenant_groups",
+ to: "/tenant-groups",
+ icon: LayoutGrid,
+ },
+ { label: "ui.admin.nav.tenants", to: "/tenants", icon: Building2 },
+ { label: "ui.admin.nav.users", to: "/users", icon: Users },
+ { label: "ui.admin.nav.api_keys", to: "/api-keys", icon: Key },
+ { label: "ui.admin.nav.audit_logs", to: "/audit-logs", icon: NotebookTabs },
+ { label: "ui.admin.nav.auth_guard", to: "/auth", icon: KeyRound },
+];
+function AppLayout() {
+ const navigate = useNavigate();
+ const [theme, setTheme] = useState<"light" | "dark">(() => {
+ const stored = window.localStorage.getItem("admin_theme");
+ return stored === "dark" ? "dark" : "light";
+ });
+
+ const handleLogout = () => {
+ if (
+ window.confirm(t("msg.admin.logout_confirm", "로그아웃 하시겠습니까?"))
+ ) {
+ window.localStorage.removeItem("admin_session");
+ navigate("/login");
+ }
+ };
+
+ useEffect(() => {
+ const session = window.localStorage.getItem("admin_session");
+ if (!session) {
+ navigate("/login");
+ }
+ }, [navigate]);
+
+ useEffect(() => {
+ const root = document.documentElement;
+ root.classList.remove("light", "dark");
+ if (theme === "light") {
+ root.classList.add("light");
+ } else {
+ root.classList.add("dark");
+ }
+ window.localStorage.setItem("admin_theme", theme);
+ }, [theme]);
+
+ const toggleTheme = () => {
+ setTheme((prev) => (prev === "light" ? "dark" : "light"));
+ };
+
+ return (
+
+
@@ -116,11 +117,12 @@ function TenantGroupCreatePage() {
권한 상속 안내
- 테넌트 그룹의 관리자는 소속된 모든 테넌트에 대한 관리 권한을 자동으로 가집니다.
+ 테넌트 그룹의 관리자는 소속된 모든 테넌트에 대한 관리 권한을
+ 자동으로 가집니다.
- 생성 후 상세 페이지에서 테넌트를 이 그룹에 할당할 수 있습니다.
+ 생성 후 상세 페이지에서 테넌트를 이 그룹에 할당할 수 있습니다.
diff --git a/adminfront/src/features/tenant-groups/routes/TenantGroupDetailPage.tsx b/adminfront/src/features/tenant-groups/routes/TenantGroupDetailPage.tsx
index 5b65a217..0bbf3cf0 100644
--- a/adminfront/src/features/tenant-groups/routes/TenantGroupDetailPage.tsx
+++ b/adminfront/src/features/tenant-groups/routes/TenantGroupDetailPage.tsx
@@ -22,7 +22,10 @@ function TenantGroupDetailPage() {
-
+
);
diff --git a/adminfront/src/features/tenant-groups/routes/TenantGroupListPage.tsx b/adminfront/src/features/tenant-groups/routes/TenantGroupListPage.tsx
index 91156bf6..cdb8ed64 100644
--- a/adminfront/src/features/tenant-groups/routes/TenantGroupListPage.tsx
+++ b/adminfront/src/features/tenant-groups/routes/TenantGroupListPage.tsx
@@ -1,6 +1,6 @@
import { useMutation, useQuery } from "@tanstack/react-query";
import type { AxiosError } from "axios";
-import { Pencil, Plus, RefreshCw, Trash2, LayoutGrid } from "lucide-react";
+import { LayoutGrid, Pencil, Plus, RefreshCw, Trash2 } from "lucide-react";
import { Link, useNavigate } from "react-router-dom";
import { Badge } from "../../../components/ui/badge";
import { Button } from "../../../components/ui/button";
@@ -85,8 +85,8 @@ function TenantGroupListPage() {