From 7ddcfb630d3dec3d9fecbfd6a498ca7c572809ec Mon Sep 17 00:00:00 2001 From: MohamedBassem Date: Fri, 1 Mar 2024 23:17:27 +0000 Subject: feature: Add an admin page showing server stats and actions --- packages/web/app/dashboard/admin/page.tsx | 123 ++++++++++++++++++++++ packages/web/app/dashboard/components/Sidebar.tsx | 8 ++ 2 files changed, 131 insertions(+) create mode 100644 packages/web/app/dashboard/admin/page.tsx (limited to 'packages/web/app/dashboard') diff --git a/packages/web/app/dashboard/admin/page.tsx b/packages/web/app/dashboard/admin/page.tsx new file mode 100644 index 00000000..26b6447b --- /dev/null +++ b/packages/web/app/dashboard/admin/page.tsx @@ -0,0 +1,123 @@ +"use client"; + +import { ActionButton } from "@/components/ui/action-button"; +import LoadingSpinner from "@/components/ui/spinner"; +import { + Table, + TableBody, + TableCell, + TableHead, + TableHeader, + TableRow, +} from "@/components/ui/table"; +import { toast } from "@/components/ui/use-toast"; +import { api } from "@/lib/trpc"; +import { keepPreviousData } from "@tanstack/react-query"; +import { useSession } from "next-auth/react"; +import { useRouter } from "next/navigation"; + +export default function AdminPage() { + const router = useRouter(); + const { data: session, status } = useSession(); + + if (status == "loading") { + return ; + } + + if (!session || session.user.role != "admin") { + router.push("/"); + return; + } + + const { data } = api.admin.stats.useQuery(undefined, { + refetchInterval: 1000, + placeholderData: keepPreviousData, + }); + + const { mutate: recrawlLinks, isPending: isRecrawlPending } = + api.admin.recrawlAllLinks.useMutation({ + onSuccess: () => { + toast({ + description: "Recrawl enqueued", + }); + }, + onError: (e) => { + toast({ + variant: "destructive", + description: e.message, + }); + }, + }); + + const { mutate: reindexBookmarks, isPending: isReindexPending } = + api.admin.reindexAllBookmarks.useMutation({ + onSuccess: () => { + toast({ + description: "Reindex enqueued", + }); + }, + onError: (e) => { + toast({ + variant: "destructive", + description: e.message, + }); + }, + }); + + return ( +
+

Admin

+
+ {data ? ( + + + + Stats + Value + + + + + Num Users + {data.numUsers} + + + Num Bookmarks + {data.numBookmarks} + + + Pending Crawling Jobs + {data.pendingCrawls} + + + Pending Indexing Jobs + {data.pendingIndexing} + + + Pending OpenAI Jobs + {data.pendingOpenai} + + +
+ ) : ( + + )} +
+

Actions

+ recrawlLinks()} + > + Recrawl All Links + + reindexBookmarks()} + > + Reindex All Bookmarks + +
+ ); +} diff --git a/packages/web/app/dashboard/components/Sidebar.tsx b/packages/web/app/dashboard/components/Sidebar.tsx index 010ee103..29e5baed 100644 --- a/packages/web/app/dashboard/components/Sidebar.tsx +++ b/packages/web/app/dashboard/components/Sidebar.tsx @@ -6,6 +6,7 @@ import { PackageOpen, Settings, Search, + Shield, } from "lucide-react"; import { redirect } from "next/navigation"; import SidebarItem from "./SidebarItem"; @@ -61,6 +62,13 @@ export default async function Sidebar() { name="Settings" path="/dashboard/settings" /> + {session.user.role == "admin" && ( + } + name="Admin" + path="/dashboard/admin" + /> + )} -- cgit v1.2.3-70-g09d2