diff --git a/app/(dashboard)/layout.tsx b/app/(dashboard)/layout.tsx index ece0cc7..8266fdc 100644 --- a/app/(dashboard)/layout.tsx +++ b/app/(dashboard)/layout.tsx @@ -3,73 +3,12 @@ import { useEffect, useState } from "react"; import Link from "next/link"; import { usePathname, useRouter } from "next/navigation"; -import { - ClipboardCheck, - Flag, - ShieldCheck, - Gift, - Megaphone, - Quote, - FolderClosed, - LayoutDashboard, - LayoutGrid, - Link2, - LogOut, - MessageSquare, - Users, -} from "lucide-react"; -import { api, staff, MANAGE_STAFF, type Me, type StaffMe } from "@/lib/api"; +import { Menu } from "lucide-react"; +import { api, staff, type Me, type StaffMe } from "@/lib/api"; import { RequirePermission, StaffProvider } from "@/components/staff-context"; -import { cn } from "@/lib/utils"; import { Button } from "@/components/ui/button"; import { ConfirmProvider } from "@/components/confirm"; - -// Each entry names the permission that unlocks it, so the sidebar only shows -// what the signed-in role can actually use. -const NAV = [ - { href: "/", label: "Overview", icon: LayoutDashboard, perm: "stats:read" }, - { href: "/users", label: "Users", icon: Users, perm: "users:read" }, - { href: "/posts", label: "Posts", icon: LayoutGrid, perm: "posts:moderate" }, - { - href: "/collections", - label: "Collections", - icon: FolderClosed, - perm: "collections:read", - }, - { - href: "/short-urls", - label: "Short URLs", - icon: Link2, - perm: "short_urls:read", - }, - { - href: "/feedback", - label: "Feedback", - icon: MessageSquare, - perm: "feedback:read", - }, - { href: "/reports", label: "Reports", icon: Flag, perm: "reports:read" }, - { - href: "/broadcasts", - label: "Announcements", - icon: Megaphone, - perm: "broadcasts:read", - }, - { href: "/reward-gifts", label: "Gifts", icon: Gift, perm: "rewards:read" }, - { href: "/vani", label: "Vāṇī of the Day", icon: Quote, perm: "vani:read" }, - { - href: "/quizzes", - label: "Quizzes", - icon: ClipboardCheck, - perm: "quizzes:read", - }, - { - href: "/staff", - label: "Staff & roles", - icon: ShieldCheck, - perm: MANAGE_STAFF, - }, -]; +import { NAV, Sidebar } from "./sidebar"; export default function DashboardLayout({ children, @@ -81,6 +20,8 @@ export default function DashboardLayout({ const [me, setMe] = useState(null); const [staffMe, setStaffMe] = useState(null); const [checked, setChecked] = useState(false); + // Navigation drawer, below lg only. + const [navOpen, setNavOpen] = useState(false); // Staff gate: only an account holding an admin role, and not blocked from // the panel, may see the dashboard. /admin/me answers both at once — it 403s @@ -133,84 +74,59 @@ export default function DashboardLayout({ ); } + const section = + NAV.find( + (n) => + n.href !== "/" && + (pathname === n.href || pathname.startsWith(n.href + "/")), + ) ?? (pathname === "/" ? NAV[0] : undefined); + return (
- +

+ {section?.label ?? "Admin"} +

+ -
-
- - - {/* The section's own permission, so a URL typed straight in +
+
+ + + {/* The section's own permission, so a URL typed straight in explains itself instead of failing call by call. */} - {(() => { - const section = - NAV.find( - (n) => - n.href !== "/" && - (pathname === n.href || - pathname.startsWith(n.href + "/")), - ) ?? (pathname === "/" ? NAV[0] : undefined); - return section ? ( + {section ? ( {children} ) : ( children - ); - })()} - - -
-
+ )} +
+
+
+
+
); } diff --git a/app/(dashboard)/quizzes/[id]/results.tsx b/app/(dashboard)/quizzes/[id]/results.tsx index ab7165d..25d2038 100644 --- a/app/(dashboard)/quizzes/[id]/results.tsx +++ b/app/(dashboard)/quizzes/[id]/results.tsx @@ -174,7 +174,7 @@ export function Participants({ quizId }: { quizId: string }) { {!detail ? (

Loading…

) : ( -
+

{detail.completed_at ? `Scored ${detail.score} of ${detail.total}` diff --git a/app/(dashboard)/quizzes/page.tsx b/app/(dashboard)/quizzes/page.tsx index 1904843..a389ac9 100644 --- a/app/(dashboard)/quizzes/page.tsx +++ b/app/(dashboard)/quizzes/page.tsx @@ -41,8 +41,8 @@ export default function QuizzesPage() {

- - + + diff --git a/app/(dashboard)/quizzes/quiz-editor.tsx b/app/(dashboard)/quizzes/quiz-editor.tsx index c0dbf92..ed1a0bb 100644 --- a/app/(dashboard)/quizzes/quiz-editor.tsx +++ b/app/(dashboard)/quizzes/quiz-editor.tsx @@ -191,6 +191,7 @@ export function QuizEditor({

Paste the page's link, e.g. /books/bg/2 or /transcriptions/720720sb-london. Leave empty for a stand-alone + quiz. Each chapter, lecture or conversation can have only one quiz.

@@ -298,7 +299,7 @@ export function QuizEditor({ maxLength={2000} placeholder="Question" /> -