diff --git a/apps/web/app/admin/actions/page.tsx b/apps/web/app/admin/actions/page.tsx new file mode 100644 index 00000000..51f7e5d4 --- /dev/null +++ b/apps/web/app/admin/actions/page.tsx @@ -0,0 +1,5 @@ +import AdminActions from "@/components/admin/AdminActions"; + +export default function AdminActionsPage() { + return ; +} diff --git a/apps/web/app/admin/layout.tsx b/apps/web/app/admin/layout.tsx new file mode 100644 index 00000000..0d876736 --- /dev/null +++ b/apps/web/app/admin/layout.tsx @@ -0,0 +1,40 @@ +import { redirect } from "next/navigation"; +import { AdminCard } from "@/components/admin/AdminCard"; +import { AdminNotices } from "@/components/admin/AdminNotices"; +import MobileAdminSidebar from "@/components/admin/sidebar/MobileSidebar"; +import AdminSidebar from "@/components/admin/sidebar/Sidebar"; +import Header from "@/components/dashboard/header/Header"; +import { Separator } from "@/components/ui/separator"; +import { getServerAuthSession } from "@/server/auth"; + +export default async function AdminLayout({ + children, +}: Readonly<{ + children: React.ReactNode; +}>) { + const session = await getServerAuthSession(); + if (!session || session.user.role !== "admin") { + redirect("/"); + } + + return ( +
+
+
+
+ +
+
+
+ + +
+
+ + {children} +
+
+
+
+ ); +} diff --git a/apps/web/app/admin/overview/page.tsx b/apps/web/app/admin/overview/page.tsx new file mode 100644 index 00000000..226fb9d5 --- /dev/null +++ b/apps/web/app/admin/overview/page.tsx @@ -0,0 +1,5 @@ +import ServerStats from "@/components/admin/ServerStats"; + +export default function AdminOverviewPage() { + return ; +} diff --git a/apps/web/app/admin/page.tsx b/apps/web/app/admin/page.tsx new file mode 100644 index 00000000..7fed8185 --- /dev/null +++ b/apps/web/app/admin/page.tsx @@ -0,0 +1,6 @@ +import { redirect } from "next/navigation"; + +export default function AdminHomepage() { + redirect("/admin/overview"); + return null; +} diff --git a/apps/web/app/admin/users/page.tsx b/apps/web/app/admin/users/page.tsx new file mode 100644 index 00000000..be5cfe81 --- /dev/null +++ b/apps/web/app/admin/users/page.tsx @@ -0,0 +1,5 @@ +import UserList from "@/components/admin/UserList"; + +export default function AdminUsersPage() { + return ; +} diff --git a/apps/web/app/dashboard/admin/page.tsx b/apps/web/app/dashboard/admin/page.tsx deleted file mode 100644 index cf97698b..00000000 --- a/apps/web/app/dashboard/admin/page.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import { redirect } from "next/navigation"; -import AdminActions from "@/components/dashboard/admin/AdminActions"; -import { AdminCard } from "@/components/dashboard/admin/AdminCard"; -import { AdminNotices } from "@/components/dashboard/admin/AdminNotices"; -import ServerStats from "@/components/dashboard/admin/ServerStats"; -import UserList from "@/components/dashboard/admin/UserList"; -import { getServerAuthSession } from "@/server/auth"; - -export default async function AdminPage() { - const session = await getServerAuthSession(); - if (!session || session.user.role !== "admin") { - redirect("/"); - } - return ( -
- - - - - - - - -
- ); -} diff --git a/apps/web/components/dashboard/admin/AddUserDialog.tsx b/apps/web/components/admin/AddUserDialog.tsx similarity index 100% rename from apps/web/components/dashboard/admin/AddUserDialog.tsx rename to apps/web/components/admin/AddUserDialog.tsx diff --git a/apps/web/components/dashboard/admin/AdminActions.tsx b/apps/web/components/admin/AdminActions.tsx similarity index 97% rename from apps/web/components/dashboard/admin/AdminActions.tsx rename to apps/web/components/admin/AdminActions.tsx index 3b95045c..34b3d63a 100644 --- a/apps/web/components/dashboard/admin/AdminActions.tsx +++ b/apps/web/components/admin/AdminActions.tsx @@ -71,7 +71,7 @@ export default function AdminActions() { return (
-
{t("common.actions")}
+
{t("common.actions")}
+
{t("admin.server_stats.server_stats")}
@@ -143,6 +143,6 @@ export default function ServerStats() {
- +
); } diff --git a/apps/web/components/dashboard/admin/UserList.tsx b/apps/web/components/admin/UserList.tsx similarity index 98% rename from apps/web/components/dashboard/admin/UserList.tsx rename to apps/web/components/admin/UserList.tsx index 8c788ef4..3dfcaad1 100644 --- a/apps/web/components/dashboard/admin/UserList.tsx +++ b/apps/web/components/admin/UserList.tsx @@ -55,7 +55,7 @@ export default function UsersSection() { } return ( - <> +
{t("admin.users_list.users_list")} @@ -125,6 +125,6 @@ export default function UsersSection() { ))} - +
); } diff --git a/apps/web/components/admin/sidebar/MobileSidebar.tsx b/apps/web/components/admin/sidebar/MobileSidebar.tsx new file mode 100644 index 00000000..416b944c --- /dev/null +++ b/apps/web/components/admin/sidebar/MobileSidebar.tsx @@ -0,0 +1,21 @@ +import MobileSidebarItem from "@/components/shared/sidebar/ModileSidebarItem"; +import { useTranslation } from "@/lib/i18n/server"; + +import { adminSidebarItems } from "./items"; + +export default async function MobileSidebar() { + const { t } = await useTranslation(); + return ( + + ); +} diff --git a/apps/web/components/admin/sidebar/Sidebar.tsx b/apps/web/components/admin/sidebar/Sidebar.tsx new file mode 100644 index 00000000..8a5d615a --- /dev/null +++ b/apps/web/components/admin/sidebar/Sidebar.tsx @@ -0,0 +1,36 @@ +import { redirect } from "next/navigation"; +import SidebarItem from "@/components/shared/sidebar/SidebarItem"; +import { useTranslation } from "@/lib/i18n/server"; +import { getServerAuthSession } from "@/server/auth"; + +import serverConfig from "@hoarder/shared/config"; + +import { adminSidebarItems } from "./items"; + +export default async function Sidebar() { + const { t } = await useTranslation(); + const session = await getServerAuthSession(); + if (!session) { + redirect("/"); + } + + return ( + + ); +} diff --git a/apps/web/components/admin/sidebar/items.tsx b/apps/web/components/admin/sidebar/items.tsx new file mode 100644 index 00000000..78dfee34 --- /dev/null +++ b/apps/web/components/admin/sidebar/items.tsx @@ -0,0 +1,31 @@ +import { TFunction } from "i18next"; +import { Activity, ArrowLeft, Settings, Users } from "lucide-react"; + +export const adminSidebarItems = ( + t: TFunction, +): { + name: string; + icon: JSX.Element; + path: string; +}[] => [ + { + name: t("settings.back_to_app"), + icon: , + path: "/dashboard/bookmarks", + }, + { + name: t("admin.server_stats.server_stats"), + icon: , + path: "/admin/overview", + }, + { + name: t("admin.users_list.users_list"), + icon: , + path: "/admin/users", + }, + { + name: t("common.actions"), + icon: , + path: "/admin/actions", + }, +]; diff --git a/apps/web/components/dashboard/header/ProfileOptions.tsx b/apps/web/components/dashboard/header/ProfileOptions.tsx index fc18e9d2..3d125606 100644 --- a/apps/web/components/dashboard/header/ProfileOptions.tsx +++ b/apps/web/components/dashboard/header/ProfileOptions.tsx @@ -16,7 +16,7 @@ import { LogOut, Moon, Paintbrush, Settings, Shield, Sun } from "lucide-react"; import { signOut, useSession } from "next-auth/react"; import { useTheme } from "next-themes"; -import { AdminNoticeBadge } from "../admin/AdminNotices"; +import { AdminNoticeBadge } from "../../admin/AdminNotices"; function DarkModeToggle() { const { t } = useTranslation(); @@ -74,7 +74,7 @@ export default function SidebarProfileOptions() { {session.user.role == "admin" && ( - +
{t("admin.admin_settings")}