From 3ac11aadaab44b15c587e316b96d77099a3368a1 Mon Sep 17 00:00:00 2001 From: Lorenzo Corallo Date: Thu, 4 Jun 2026 19:57:21 +0200 Subject: [PATCH 01/27] style: update (dark) sidebar css variables --- src/index.css | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/index.css b/src/index.css index 41a1b5f..1e1380b 100644 --- a/src/index.css +++ b/src/index.css @@ -92,13 +92,13 @@ --chart-3: oklch(0.72 0.15 58.79); --chart-4: oklch(0.66 0.2 335.4); --chart-5: oklch(0.76 0.12 214.15); - --sidebar: oklch(0.19 0.03 256.45); + --sidebar: oklch(0.24 0.03 259.05); --sidebar-foreground: oklch(0.82 0.02 256.74); - --sidebar-primary: oklch(0.49 0.22 264.38); - --sidebar-primary-foreground: oklch(1 0 0); - --sidebar-accent: oklch(0.27 0.03 254.37); - --sidebar-accent-foreground: oklch(0.97 0 286.38); - --sidebar-border: oklch(0 0 0); + --sidebar-primary: oklch(0.47 0.16 257.42); + --sidebar-primary-foreground: oklch(0.96 0.01 278.64); + --sidebar-accent: oklch(0.3 0.03 254.37); + --sidebar-accent-foreground: oklch(0.96 0.01 292.8); + --sidebar-border: oklch(0.35 0.04 254.63); --sidebar-ring: oklch(0.47 0.16 257.42); --font-sans: Poppins, sans-serif; --font-serif: Libre Baskerville, serif; From aaed723267f01d3b14ff045ad59df8d21acc46e2 Mon Sep 17 00:00:00 2001 From: Lorenzo Corallo Date: Thu, 4 Jun 2026 23:34:59 +0200 Subject: [PATCH 02/27] feat: sidebar boilerplate and breadcrumb header --- package.json | 3 +- pnpm-lock.yaml | 27 + src/app/dashboard/(active)/breadcrumb.tsx | 38 + src/app/dashboard/(active)/layout.tsx | 26 + .../(active)/telegram/groups/page.tsx | 2 +- src/app/dashboard/layout.tsx | 8 +- src/app/layout.tsx | 2 +- src/app/page.tsx | 4 +- src/components/dashboard-sidebar/data.tsx | 169 ++++ src/components/dashboard-sidebar/index.tsx | 38 + src/components/dashboard-sidebar/main-nav.tsx | 97 +++ src/components/ui/sidebar.tsx | 723 ++++++++++++++++++ tsconfig.json | 2 +- 13 files changed, 1126 insertions(+), 13 deletions(-) create mode 100644 src/app/dashboard/(active)/breadcrumb.tsx create mode 100644 src/app/dashboard/(active)/layout.tsx create mode 100644 src/components/dashboard-sidebar/data.tsx create mode 100644 src/components/dashboard-sidebar/index.tsx create mode 100644 src/components/dashboard-sidebar/main-nav.tsx create mode 100644 src/components/ui/sidebar.tsx diff --git a/package.json b/package.json index 9d621bd..4990011 100644 --- a/package.json +++ b/package.json @@ -48,7 +48,8 @@ "tailwind-scrollbar": "^4.0.2", "tailwindcss-animate": "^1.0.7", "tw-animate-css": "^1.4.0", - "zod": "^4.3.5" + "zod": "^4.3.5", + "zustand": "^5.0.14" }, "devDependencies": { "@biomejs/biome": "2.3.10", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3df57b1..623f594 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -116,6 +116,9 @@ importers: zod: specifier: ^4.3.5 version: 4.3.5 + zustand: + specifier: ^5.0.14 + version: 5.0.14(@types/react@18.3.18)(react@18.3.1)(use-sync-external-store@1.6.0(react@18.3.1)) devDependencies: '@biomejs/biome': specifier: 2.3.10 @@ -3457,6 +3460,24 @@ packages: zod@4.3.6: resolution: {integrity: sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==} + zustand@5.0.14: + resolution: {integrity: sha512-/8tAspM5LMPr28b3fwLYrtdj77ECpfZviaP75CMTnwO8ISyaE4GDIG/9rDDYq/cH9D2Xw2A2RXglLInmVBQB/g==} + engines: {node: '>=12.20.0'} + peerDependencies: + '@types/react': '>=18.0.0' + immer: '>=9.0.6' + react: '>=18.0.0' + use-sync-external-store: '>=1.2.0' + peerDependenciesMeta: + '@types/react': + optional: true + immer: + optional: true + react: + optional: true + use-sync-external-store: + optional: true + snapshots: '@alloc/quick-lru@5.2.0': {} @@ -6685,3 +6706,9 @@ snapshots: zod@4.3.5: {} zod@4.3.6: {} + + zustand@5.0.14(@types/react@18.3.18)(react@18.3.1)(use-sync-external-store@1.6.0(react@18.3.1)): + optionalDependencies: + '@types/react': 18.3.18 + react: 18.3.1 + use-sync-external-store: 1.6.0(react@18.3.1) diff --git a/src/app/dashboard/(active)/breadcrumb.tsx b/src/app/dashboard/(active)/breadcrumb.tsx new file mode 100644 index 0000000..65546a1 --- /dev/null +++ b/src/app/dashboard/(active)/breadcrumb.tsx @@ -0,0 +1,38 @@ +"use client" +import { usePathname } from "next/navigation" +import { Fragment, useMemo } from "react" +import { + BreadcrumbItem, + BreadcrumbLink, + BreadcrumbList, + BreadcrumbPage, + Breadcrumb as BreadcrumbRoot, + BreadcrumbSeparator, +} from "@/components/ui/breadcrumb" +import { getBreadcrumbs } from "@/components/dashboard-sidebar/main-nav" + +export function Breadcrumb() { + const pathname = usePathname() + const items = useMemo(() => getBreadcrumbs(pathname), [pathname]) + + return ( + + + {items.map((item, i) => ( + + + {i === items.length - 1 ? ( + {item.title} + ) : item.url ? ( + {item.title} + ) : ( + item.title + )} + + {i < items.length - 1 && } + + ))} + + + ) +} diff --git a/src/app/dashboard/(active)/layout.tsx b/src/app/dashboard/(active)/layout.tsx new file mode 100644 index 0000000..26541fd --- /dev/null +++ b/src/app/dashboard/(active)/layout.tsx @@ -0,0 +1,26 @@ +import { DashboardSidebar } from "@/components/dashboard-sidebar" +import { Separator } from "@/components/ui/separator" +import { SidebarInset, SidebarProvider, SidebarTrigger } from "@/components/ui/sidebar" +import { Breadcrumb } from "./breadcrumb" + +export default async function AdminLayout({ children }: { children: React.ReactNode }) { + return ( + + + +
+ + + +
+ {children} +
+
+ ) +} diff --git a/src/app/dashboard/(active)/telegram/groups/page.tsx b/src/app/dashboard/(active)/telegram/groups/page.tsx index 00a40eb..95f126e 100644 --- a/src/app/dashboard/(active)/telegram/groups/page.tsx +++ b/src/app/dashboard/(active)/telegram/groups/page.tsx @@ -28,7 +28,7 @@ export default async function TgGroups({ searchParams }: { searchParams: Promise

Title

Tag

Invite Link

-

Actions

+

Hide

{sorted.map((r) => ( diff --git a/src/app/dashboard/layout.tsx b/src/app/dashboard/layout.tsx index d55b79f..54aee61 100644 --- a/src/app/dashboard/layout.tsx +++ b/src/app/dashboard/layout.tsx @@ -1,5 +1,4 @@ import { redirect } from "next/navigation" -import { AdminHeader } from "@/components/admin-header" import { getServerSession } from "@/server/auth" import { trpc } from "@/server/trpc" @@ -21,10 +20,5 @@ export default async function AdminLayout({ children }: { children: React.ReactN if (!roles.includes("owner") && !roles.includes("direttivo") && !roles.includes("president")) redirect("/onboarding/unauthorized") - return ( - <> - - {children} - - ) + return children } diff --git a/src/app/layout.tsx b/src/app/layout.tsx index b503bb8..410fdf9 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -43,7 +43,7 @@ export default function RootLayout({ children }: Readonly<{ children: React.Reac disableTransitionOnChange > -
+
{children}
diff --git a/src/app/page.tsx b/src/app/page.tsx index abdba51..a658b62 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -9,12 +9,12 @@ export default async function IndexPage() { if (session.data?.user) redirect("/dashboard") return ( - <> +
- +
) } diff --git a/src/components/dashboard-sidebar/data.tsx b/src/components/dashboard-sidebar/data.tsx new file mode 100644 index 0000000..b3747e1 --- /dev/null +++ b/src/components/dashboard-sidebar/data.tsx @@ -0,0 +1,169 @@ +export type NavItem = { + title: string + url: string + items?: NavItem[] +} + +export const DSData = { + navMain: [ + { + title: "Telegram", + url: "/dashboard/telegram", + items: [ + { title: "Groups", url: "/dashboard/telegram/groups" }, + { title: "Users", url: "/dashboard/telegram/user-list" }, + ], + }, + { + title: "Getting Started", + url: "#", + items: [ + { + title: "Installation", + url: "#", + }, + { + title: "Project Structure", + url: "#", + }, + ], + }, + { + title: "Build Your Application", + url: "#", + items: [ + { + title: "Routing", + url: "#", + }, + { + title: "Data Fetching", + url: "#", + isActive: true, + }, + { + title: "Rendering", + url: "#", + }, + { + title: "Caching", + url: "#", + }, + { + title: "Styling", + url: "#", + }, + { + title: "Optimizing", + url: "#", + }, + { + title: "Configuring", + url: "#", + }, + { + title: "Testing", + url: "#", + }, + { + title: "Authentication", + url: "#", + }, + { + title: "Deploying", + url: "#", + }, + { + title: "Upgrading", + url: "#", + }, + { + title: "Examples", + url: "#", + }, + ], + }, + { + title: "API Reference", + url: "#", + items: [ + { + title: "Components", + url: "#", + }, + { + title: "File Conventions", + url: "#", + }, + { + title: "Functions", + url: "#", + }, + { + title: "next.config.js Options", + url: "#", + }, + { + title: "CLI", + url: "#", + }, + { + title: "Edge Runtime", + url: "#", + }, + ], + }, + { + title: "Architecture", + url: "#", + items: [ + { + title: "Accessibility", + url: "#", + }, + { + title: "Fast Refresh", + url: "#", + }, + { + title: "Next.js Compiler", + url: "#", + }, + { + title: "Supported Browsers", + url: "#", + }, + { + title: "Turbopack", + url: "#", + }, + ], + }, + { + title: "Community", + url: "#", + items: [ + { + title: "Contribution Guide", + url: "#", + }, + ], + }, + ], +} + +const flattenNavigation = (items: NavItem[]): Record => { + const map: Record = {} + const traverse = (list: NavItem[]) => { + for (const item of list) { + map[item.url] = item.title + if (item.items) traverse(item.items) + } + } + traverse(items) + return map +} + +console.time("navmap") +export const navMap = flattenNavigation(DSData.navMain) +console.timeEnd("navmap") diff --git a/src/components/dashboard-sidebar/index.tsx b/src/components/dashboard-sidebar/index.tsx new file mode 100644 index 0000000..3193a6e --- /dev/null +++ b/src/components/dashboard-sidebar/index.tsx @@ -0,0 +1,38 @@ +"use client" + +import { GalleryVerticalEndIcon } from "lucide-react" +import type * as React from "react" +import { + Sidebar, + SidebarContent, + SidebarHeader, + SidebarMenu, + SidebarMenuButton, + SidebarMenuItem, +} from "@/components/ui/sidebar" +import { DSMainNav } from "./main-nav" + +export function DashboardSidebar({ ...props }: React.ComponentProps) { + return ( + + + + + }> +
+ +
+
+ Documentation + v1.0.0 +
+
+
+
+
+ + + +
+ ) +} diff --git a/src/components/dashboard-sidebar/main-nav.tsx b/src/components/dashboard-sidebar/main-nav.tsx new file mode 100644 index 0000000..407f54e --- /dev/null +++ b/src/components/dashboard-sidebar/main-nav.tsx @@ -0,0 +1,97 @@ +"use client" +import { usePathname } from "next/navigation" +import { + SidebarGroup, + SidebarMenu, + SidebarMenuButton, + SidebarMenuItem, + SidebarMenuSub, + SidebarMenuSubButton, + SidebarMenuSubItem, +} from "../ui/sidebar" +import { DSData, navMap } from "./data" + +export type BreadcrumbItem = { + title: string + url?: string +} + +console.log(navMap) +export function getBreadcrumbs(pathname: string): BreadcrumbItem[] { + const segments = pathname.split("/").filter(Boolean) + const breadcrumbs: BreadcrumbItem[] = [] + + let currentPath = "" + + for (const segment of segments) { + currentPath += `/${segment}` + let title = navMap[currentPath] + if (!title) { + if (isUUIDorId(segment)) { + title = "Details" + } else { + title = segment.charAt(0).toUpperCase() + segment.slice(1) + } + } + + breadcrumbs.push({ title, url: currentPath }) + } + + return breadcrumbs +} + +function isUUIDorId(segment: string) { + return !isNaN(Number(segment)) || segment.length > 20 // Regex custom a seconda dei tuoi ID +} + +export function DSMainNav() { + return ( + + + {DSData.navMain.map((category) => ( + + }> + {category.title} + + {category.items?.length ? ( + + {category.items.map((item) => ( + + ))} + + ) : null} + + ))} + + + ) +} + +function DSMenuItem({ + parent, + item, +}: { + parent: (typeof DSData)["navMain"][0] + item: (typeof DSData)["navMain"][0]["items"][0] +}) { + const path = usePathname() + // const { setBreadcrumb } = useSidebar() + const isActive = path === item.url + + // useEffect(() => { + // if (isActive) { + // setBreadcrumb([ + // { title: parent.title, url: parent.url }, + // { title: item.title, url: item.url }, + // ]) + // } + // }, [isActive]) + + return ( + + }> + {item.title} + + + ) +} diff --git a/src/components/ui/sidebar.tsx b/src/components/ui/sidebar.tsx new file mode 100644 index 0000000..41b2135 --- /dev/null +++ b/src/components/ui/sidebar.tsx @@ -0,0 +1,723 @@ +"use client" + +import * as React from "react" +import { mergeProps } from "@base-ui/react/merge-props" +import { useRender } from "@base-ui/react/use-render" +import { cva, type VariantProps } from "class-variance-authority" + +import { useIsMobile } from "@/hooks/use-mobile" +import { cn } from "@/lib/utils/shadcn" +import { Button } from "@/components/ui/button" +import { Input } from "@/components/ui/input" +import { Separator } from "@/components/ui/separator" +import { + Sheet, + SheetContent, + SheetDescription, + SheetHeader, + SheetTitle, +} from "@/components/ui/sheet" +import { Skeleton } from "@/components/ui/skeleton" +import { + Tooltip, + TooltipContent, + TooltipTrigger, +} from "@/components/ui/tooltip" +import { PanelLeftIcon } from "lucide-react" + +const SIDEBAR_COOKIE_NAME = "sidebar_state" +const SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7 +const SIDEBAR_WIDTH = "16rem" +const SIDEBAR_WIDTH_MOBILE = "18rem" +const SIDEBAR_WIDTH_ICON = "3rem" +const SIDEBAR_KEYBOARD_SHORTCUT = "b" + +type SidebarContextProps = { + state: "expanded" | "collapsed" + open: boolean + setOpen: (open: boolean) => void + openMobile: boolean + setOpenMobile: (open: boolean) => void + isMobile: boolean + toggleSidebar: () => void +} + +const SidebarContext = React.createContext(null) + +function useSidebar() { + const context = React.useContext(SidebarContext) + if (!context) { + throw new Error("useSidebar must be used within a SidebarProvider.") + } + + return context +} + +function SidebarProvider({ + defaultOpen = true, + open: openProp, + onOpenChange: setOpenProp, + className, + style, + children, + ...props +}: React.ComponentProps<"div"> & { + defaultOpen?: boolean + open?: boolean + onOpenChange?: (open: boolean) => void +}) { + const isMobile = useIsMobile() + const [openMobile, setOpenMobile] = React.useState(false) + + // This is the internal state of the sidebar. + // We use openProp and setOpenProp for control from outside the component. + const [_open, _setOpen] = React.useState(defaultOpen) + const open = openProp ?? _open + const setOpen = React.useCallback( + (value: boolean | ((value: boolean) => boolean)) => { + const openState = typeof value === "function" ? value(open) : value + if (setOpenProp) { + setOpenProp(openState) + } else { + _setOpen(openState) + } + + // This sets the cookie to keep the sidebar state. + document.cookie = `${SIDEBAR_COOKIE_NAME}=${openState}; path=/; max-age=${SIDEBAR_COOKIE_MAX_AGE}` + }, + [setOpenProp, open] + ) + + // Helper to toggle the sidebar. + const toggleSidebar = React.useCallback(() => { + return isMobile ? setOpenMobile((open) => !open) : setOpen((open) => !open) + }, [isMobile, setOpen, setOpenMobile]) + + // Adds a keyboard shortcut to toggle the sidebar. + React.useEffect(() => { + const handleKeyDown = (event: KeyboardEvent) => { + if ( + event.key === SIDEBAR_KEYBOARD_SHORTCUT && + (event.metaKey || event.ctrlKey) + ) { + event.preventDefault() + toggleSidebar() + } + } + + window.addEventListener("keydown", handleKeyDown) + return () => window.removeEventListener("keydown", handleKeyDown) + }, [toggleSidebar]) + + // We add a state so that we can do data-state="expanded" or "collapsed". + // This makes it easier to style the sidebar with Tailwind classes. + const state = open ? "expanded" : "collapsed" + + const contextValue = React.useMemo( + () => ({ + state, + open, + setOpen, + isMobile, + openMobile, + setOpenMobile, + toggleSidebar, + }), + [state, open, setOpen, isMobile, openMobile, setOpenMobile, toggleSidebar] + ) + + return ( + +
+ {children} +
+
+ ) +} + +function Sidebar({ + side = "left", + variant = "sidebar", + collapsible = "offcanvas", + className, + children, + dir, + ...props +}: React.ComponentProps<"div"> & { + side?: "left" | "right" + variant?: "sidebar" | "floating" | "inset" + collapsible?: "offcanvas" | "icon" | "none" +}) { + const { isMobile, state, openMobile, setOpenMobile } = useSidebar() + + if (collapsible === "none") { + return ( +
+ {children} +
+ ) + } + + if (isMobile) { + return ( + + + + Sidebar + Displays the mobile sidebar. + +
{children}
+
+
+ ) + } + + return ( +
+ {/* This is what handles the sidebar gap on desktop */} +
+ +
+ ) +} + +function SidebarTrigger({ + className, + onClick, + ...props +}: React.ComponentProps) { + const { toggleSidebar } = useSidebar() + + return ( + + ) +} + +function SidebarRail({ className, ...props }: React.ComponentProps<"button">) { + const { toggleSidebar } = useSidebar() + + return ( + - } - /> - - - Account - - - - Settings - - - { - await signOut() - redirect("/login") - }} - variant="destructive" - > - Logout - - - - - ) : ( -
- ) -} diff --git a/src/components/dashboard-sidebar/user-nav.tsx b/src/components/dashboard-sidebar/user-nav.tsx index 62c7f06..580c2cc 100644 --- a/src/components/dashboard-sidebar/user-nav.tsx +++ b/src/components/dashboard-sidebar/user-nav.tsx @@ -15,7 +15,7 @@ import { DropdownMenuTrigger, } from "@/components/ui/dropdown-menu" import { SidebarMenu, SidebarMenuButton, SidebarMenuItem, useSidebar } from "@/components/ui/sidebar" -import { auth, useSession } from "@/lib/auth" +import { signOut, useSession } from "@/lib/auth" import { getInitials } from "@/lib/utils" import { Skeleton } from "../ui/skeleton" @@ -87,8 +87,9 @@ export function DSUserNav() { - auth.signOut({ + signOut({ fetchOptions: { onSuccess: () => { toast.success("Logged out!") diff --git a/src/index.css b/src/index.css index 1e1380b..307d683 100644 --- a/src/index.css +++ b/src/index.css @@ -82,7 +82,7 @@ --placeholder: oklch(0.5623 0.04 280.47); --accent: oklch(0.35 0.04 254.63); --accent-foreground: oklch(0.96 0.01 292.8); - --destructive: oklch(0.51 0.19 27.08); + --destructive: oklch(0.61 0.19 27.08); --destructive-foreground: oklch(1 0 0); --border: oklch(0.35 0.04 254.63); --input: oklch(0.3961 0.03 259.05); From fc32ad7dc6277a2ee0d65b778d90769626d05602 Mon Sep 17 00:00:00 2001 From: Lorenzo Corallo Date: Fri, 5 Jun 2026 22:54:51 +0200 Subject: [PATCH 14/27] style: container mx-auto by default --- src/index.css | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/index.css b/src/index.css index 307d683..d2dd450 100644 --- a/src/index.css +++ b/src/index.css @@ -174,3 +174,7 @@ @theme { --breakpoint-xs: 30rem; } + +@utility container { + margin-inline: auto; +} From 51e171edbf454d3789cd9d71bd302d9756e27b8f Mon Sep 17 00:00:00 2001 From: Lorenzo Corallo Date: Fri, 5 Jun 2026 22:55:49 +0200 Subject: [PATCH 15/27] fix: remove category pages, dont create link for category in breadcrumb --- src/app/dashboard/(active)/account/page.tsx | 2 +- src/app/dashboard/(active)/azure/page.tsx | 29 --------------------- src/app/dashboard/(active)/breadcrumb.tsx | 7 ++++- src/components/dashboard-sidebar/data.tsx | 8 +++--- 4 files changed, 11 insertions(+), 35 deletions(-) delete mode 100644 src/app/dashboard/(active)/azure/page.tsx diff --git a/src/app/dashboard/(active)/account/page.tsx b/src/app/dashboard/(active)/account/page.tsx index 0a91c06..e6c00a0 100644 --- a/src/app/dashboard/(active)/account/page.tsx +++ b/src/app/dashboard/(active)/account/page.tsx @@ -22,7 +22,7 @@ export default async function Account() { const { user } = session return ( -
+

Account

diff --git a/src/app/dashboard/(active)/azure/page.tsx b/src/app/dashboard/(active)/azure/page.tsx deleted file mode 100644 index 563c8e3..0000000 --- a/src/app/dashboard/(active)/azure/page.tsx +++ /dev/null @@ -1,29 +0,0 @@ -import { UsersRound } from "lucide-react" -import Image from "next/image" -import Link from "next/link" -import azureSvg from "@/assets/svg/azure.svg" -import { Card, CardDescription, CardHeader, CardTitle } from "@/components/ui/card" - -export default function AssocIndex() { - return ( -
-

- azure logo - Azure -

-
- - - - - - Members - - Manage all @polinetwork.org accounts - - - -
-
- ) -} diff --git a/src/app/dashboard/(active)/breadcrumb.tsx b/src/app/dashboard/(active)/breadcrumb.tsx index 7b28fa4..1b757c1 100644 --- a/src/app/dashboard/(active)/breadcrumb.tsx +++ b/src/app/dashboard/(active)/breadcrumb.tsx @@ -47,6 +47,7 @@ function getBreadcrumbs(navMap: Map, pathname: string): Breadcru const breadcrumbs: BreadcrumbItem[] = [] let currentPath = "" + let i = 0 for (const segment of segments) { currentPath += `/${segment}` @@ -59,9 +60,13 @@ function getBreadcrumbs(navMap: Map, pathname: string): Breadcru } } - breadcrumbs.push({ title, url: currentPath }) + // note: at the moment we do not plan to make category pages. + // If such pages are made in the future, this logic can be removed + breadcrumbs.push({ title, url: i !== 1 ? currentPath : undefined }) + i++ } + console.log(breadcrumbs) return breadcrumbs } diff --git a/src/components/dashboard-sidebar/data.tsx b/src/components/dashboard-sidebar/data.tsx index a87d1cc..b946fbe 100644 --- a/src/components/dashboard-sidebar/data.tsx +++ b/src/components/dashboard-sidebar/data.tsx @@ -7,7 +7,6 @@ export const DSData = { mainNav: [ { title: "Telegram", - url: "/dashboard/telegram", icon: telegram logo, items: [ { title: "Grants", url: "/dashboard/telegram/grants", icon: }, @@ -17,7 +16,6 @@ export const DSData = { }, { title: "Azure", - url: "/dashboard/azure", icon: azure logo, items: [{ title: "Members", url: "/dashboard/azure/members", icon: }], }, @@ -32,8 +30,10 @@ const flattenNavigation = (): Map => { map.set(item.url, item.title) } } - Object.entries(DSData).forEach(([_k, items]) => { - traverse(items) + Object.entries(DSData).forEach(([_k, nav]) => { + nav.forEach((category) => { + traverse(category.items) + }) }) return map } From 63625664bd15d90383508fa2a2d75609ad795c09 Mon Sep 17 00:00:00 2001 From: Lorenzo Corallo Date: Fri, 5 Jun 2026 23:13:30 +0200 Subject: [PATCH 16/27] fix: re-render issue with the use-cookie-storage hook --- src/components/dashboard-sidebar/main-nav.tsx | 16 ++++++++++------ src/hooks/use-cookie-storage.tsx | 6 +----- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/components/dashboard-sidebar/main-nav.tsx b/src/components/dashboard-sidebar/main-nav.tsx index d5d3a7c..b429ade 100644 --- a/src/components/dashboard-sidebar/main-nav.tsx +++ b/src/components/dashboard-sidebar/main-nav.tsx @@ -2,7 +2,7 @@ import { ChevronRight } from "lucide-react" import Link from "next/link" import { usePathname } from "next/navigation" -import { useEffect, useState } from "react" +import { useCallback, useEffect, useState } from "react" import { COOKIES } from "@/constants" import { useCookieStorage } from "@/hooks/use-cookie-storage" import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "../ui/collapsible" @@ -32,23 +32,27 @@ export function DSMainNav({ categoryState }: { categoryState: Record(initialOpen ?? pathname.startsWith(category.url)) + const categoryUrl = category.items[0]?.url.split("/").slice(0, 3).join("/") + const [open, setOpen] = useState(initialOpen ?? (categoryUrl ? pathname.startsWith(categoryUrl) : false)) const [_, setState] = useCookieStorage>( COOKIES.SIDEBAR_CATEGORY_STATE, {}, { expires: 60 * 60 * 24 * 7 } ) - useEffect(() => { - if (open !== undefined) + const handleOpenChange = useCallback( + (open: boolean) => { + setOpen(open) setState((state) => { state[category.title] = open return state }) - }, [open, setState, category.title]) + }, + [setState, category.title] + ) return open !== undefined ? ( - } open={open} onOpenChange={setOpen} className="group/collapsible"> + } open={open} onOpenChange={handleOpenChange} className="group/collapsible"> diff --git a/src/hooks/use-cookie-storage.tsx b/src/hooks/use-cookie-storage.tsx index ece3e52..462bb02 100644 --- a/src/hooks/use-cookie-storage.tsx +++ b/src/hooks/use-cookie-storage.tsx @@ -6,7 +6,7 @@ export function useCookieStorage( initialValue: T, options: CookieOptions = {} ): [T, Dispatch>] { - const envOptions = getDefaultCookieOptions() + const envOptions = useMemo(() => getDefaultCookieOptions(), []) const mergedOptions = useMemo(() => ({ ...envOptions, ...options }), [options, envOptions]) const readValue = useCallback((): T => { @@ -45,9 +45,5 @@ export function useCookieStorage( [key, storedValue, mergedOptions] ) - useEffect(() => { - setStoredValue(readValue()) - }, [readValue]) - return [storedValue, setValue] } From 075f156fdf94044d170cf36340fd5ac2b1a7d04f Mon Sep 17 00:00:00 2001 From: Lorenzo Corallo Date: Fri, 5 Jun 2026 23:15:30 +0200 Subject: [PATCH 17/27] fix: same as previous commit, but for use-session-storage --- src/hooks/use-session-storage.tsx | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/hooks/use-session-storage.tsx b/src/hooks/use-session-storage.tsx index 46a7ab8..b1de618 100644 --- a/src/hooks/use-session-storage.tsx +++ b/src/hooks/use-session-storage.tsx @@ -1,4 +1,4 @@ -import { type Dispatch, type SetStateAction, useCallback, useEffect, useState } from "react" +import { type Dispatch, type SetStateAction, useCallback, useState } from "react" export function useSessionStorage(key: string, initialValue: T): [T, Dispatch>] { // Read from sessionStorage on initialization @@ -35,10 +35,5 @@ export function useSessionStorage(key: string, initialValue: T): [T, Dispatch [key, storedValue] ) - // Keep state in sync if key changes - useEffect(() => { - setStoredValue(readValue()) - }, [readValue]) - return [storedValue, setValue] } From 21c64c5be4300ef6bd24476f8af53e35194e9aa5 Mon Sep 17 00:00:00 2001 From: Lorenzo Corallo Date: Fri, 5 Jun 2026 23:23:50 +0200 Subject: [PATCH 18/27] fix: coderabbit suggestion --- src/components/dashboard-sidebar/main-nav.tsx | 44 ++++++++++++------- 1 file changed, 27 insertions(+), 17 deletions(-) diff --git a/src/components/dashboard-sidebar/main-nav.tsx b/src/components/dashboard-sidebar/main-nav.tsx index b429ade..8fde2fb 100644 --- a/src/components/dashboard-sidebar/main-nav.tsx +++ b/src/components/dashboard-sidebar/main-nav.tsx @@ -19,37 +19,47 @@ import { Skeleton } from "../ui/skeleton" import { DSData } from "./data" export function DSMainNav({ categoryState }: { categoryState: Record }) { + const [_, setCategoryState] = useCookieStorage>( + COOKIES.SIDEBAR_CATEGORY_STATE, + {}, + { expires: 60 * 60 * 24 * 7 } + ) + return ( {DSData.mainNav.map((category) => ( - + { + setCategoryState((state) => ({ ...state, [category.title]: open })) + }} + /> ))} ) } -function DSMenuCategory({ category, initialOpen }: { category: (typeof DSData)["mainNav"][0]; initialOpen?: boolean }) { +function DSMenuCategory({ + category, + initialOpen, + onPersistOpen, +}: { + category: (typeof DSData)["mainNav"][0] + initialOpen?: boolean + onPersistOpen: (open: boolean) => void +}) { const pathname = usePathname() const categoryUrl = category.items[0]?.url.split("/").slice(0, 3).join("/") const [open, setOpen] = useState(initialOpen ?? (categoryUrl ? pathname.startsWith(categoryUrl) : false)) - const [_, setState] = useCookieStorage>( - COOKIES.SIDEBAR_CATEGORY_STATE, - {}, - { expires: 60 * 60 * 24 * 7 } - ) - const handleOpenChange = useCallback( - (open: boolean) => { - setOpen(open) - setState((state) => { - state[category.title] = open - return state - }) - }, - [setState, category.title] - ) + function handleOpenChange(open: boolean) { + setOpen(open) + onPersistOpen(open) + } return open !== undefined ? ( } open={open} onOpenChange={handleOpenChange} className="group/collapsible"> From e9fd9e73b1baa8fe2088287acc4a604dc5debe3a Mon Sep 17 00:00:00 2001 From: Lorenzo Corallo Date: Fri, 5 Jun 2026 23:26:11 +0200 Subject: [PATCH 19/27] fix: match also subroutes in category items --- src/app/dashboard/(active)/breadcrumb.tsx | 1 - src/components/dashboard-sidebar/main-nav.tsx | 6 +++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/app/dashboard/(active)/breadcrumb.tsx b/src/app/dashboard/(active)/breadcrumb.tsx index 1b757c1..39b19a8 100644 --- a/src/app/dashboard/(active)/breadcrumb.tsx +++ b/src/app/dashboard/(active)/breadcrumb.tsx @@ -66,7 +66,6 @@ function getBreadcrumbs(navMap: Map, pathname: string): Breadcru i++ } - console.log(breadcrumbs) return breadcrumbs } diff --git a/src/components/dashboard-sidebar/main-nav.tsx b/src/components/dashboard-sidebar/main-nav.tsx index 8fde2fb..a9bfc09 100644 --- a/src/components/dashboard-sidebar/main-nav.tsx +++ b/src/components/dashboard-sidebar/main-nav.tsx @@ -89,7 +89,11 @@ function DSMenuCategory({ function DSMenuItem({ item }: { item: (typeof DSData)["mainNav"][0]["items"][0] }) { const path = usePathname() - const isActive = path === item.url + + // NOTE: as of now, we have only 1 level depth of submenu, so using startsWith to + // match also subroutes is ok. + // If we go with multiple levels of depth it should be changed accordingly. + const isActive = path.startsWith(item.url) return ( From 60d36175765206e42173f2df4707d37dcf50cebe Mon Sep 17 00:00:00 2001 From: Lorenzo Corallo Date: Fri, 5 Jun 2026 23:45:31 +0200 Subject: [PATCH 20/27] fix: catch JSON parse error --- src/app/dashboard/(active)/layout.tsx | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/app/dashboard/(active)/layout.tsx b/src/app/dashboard/(active)/layout.tsx index 23c5c1b..d481f02 100644 --- a/src/app/dashboard/(active)/layout.tsx +++ b/src/app/dashboard/(active)/layout.tsx @@ -5,10 +5,19 @@ import { SidebarInset, SidebarProvider, SidebarTrigger } from "@/components/ui/s import { COOKIES } from "@/constants" import { Breadcrumb } from "./breadcrumb" +function parseCookie(cookie: string) { + try { + const parsed = JSON.parse(cookie) + return parsed + } catch (_e) { + return {} + } +} + export default async function AdminLayout({ children }: { children: React.ReactNode }) { const cookieStore = await cookies() const cookie = cookieStore.get(COOKIES.SIDEBAR_CATEGORY_STATE)?.value - const DSCategoryState = cookie ? JSON.parse(cookie) : {} + const DSCategoryState = cookie ? parseCookie(cookie) : {} return ( Date: Fri, 5 Jun 2026 23:46:52 +0200 Subject: [PATCH 21/27] fix: rename column in groups --- src/app/dashboard/(active)/telegram/groups/page.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/dashboard/(active)/telegram/groups/page.tsx b/src/app/dashboard/(active)/telegram/groups/page.tsx index 2946745..897bf1b 100644 --- a/src/app/dashboard/(active)/telegram/groups/page.tsx +++ b/src/app/dashboard/(active)/telegram/groups/page.tsx @@ -23,7 +23,7 @@ export default async function TgGroups({ searchParams }: { searchParams: Promise

Title

Tag

Invite Link

-

Hide

+

Actions

{sorted.map((r) => ( From f6e4fa30ea06b0a07a8fbcc4510a6c53dba119d3 Mon Sep 17 00:00:00 2001 From: Lorenzo Corallo Date: Fri, 5 Jun 2026 23:53:26 +0200 Subject: [PATCH 22/27] style: move breadcrumb to center --- src/app/dashboard/(active)/breadcrumb.tsx | 4 ++-- src/app/dashboard/(active)/layout.tsx | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/app/dashboard/(active)/breadcrumb.tsx b/src/app/dashboard/(active)/breadcrumb.tsx index 39b19a8..17052fe 100644 --- a/src/app/dashboard/(active)/breadcrumb.tsx +++ b/src/app/dashboard/(active)/breadcrumb.tsx @@ -16,12 +16,12 @@ export type BreadcrumbItem = { url?: string } -export function Breadcrumb() { +export function Breadcrumb({ className, ...props }: React.ComponentProps<"nav">) { const pathname = usePathname() const items = useMemo(() => getBreadcrumbs(NAV_MAP, pathname), [pathname]) return ( - + {items.map((item, i) => ( diff --git a/src/app/dashboard/(active)/layout.tsx b/src/app/dashboard/(active)/layout.tsx index d481f02..4c1745d 100644 --- a/src/app/dashboard/(active)/layout.tsx +++ b/src/app/dashboard/(active)/layout.tsx @@ -1,6 +1,5 @@ import { cookies } from "next/headers" import { DashboardSidebar } from "@/components/dashboard-sidebar" -import { Separator } from "@/components/ui/separator" import { SidebarInset, SidebarProvider, SidebarTrigger } from "@/components/ui/sidebar" import { COOKIES } from "@/constants" import { Breadcrumb } from "./breadcrumb" @@ -29,13 +28,14 @@ export default async function AdminLayout({ children }: { children: React.ReactN > -
+
- - + +
{children} ) } +// From fd76b346c5f7f44fd4ba57dc7366a604d7b708a8 Mon Sep 17 00:00:00 2001 From: Lorenzo Corallo Date: Fri, 5 Jun 2026 23:59:05 +0200 Subject: [PATCH 23/27] fix: cleanup home --- src/app/dashboard/(active)/page.tsx | 39 ++++++----------------------- src/components/ui/alert.tsx | 1 + 2 files changed, 8 insertions(+), 32 deletions(-) diff --git a/src/app/dashboard/(active)/page.tsx b/src/app/dashboard/(active)/page.tsx index d0256eb..0e13529 100644 --- a/src/app/dashboard/(active)/page.tsx +++ b/src/app/dashboard/(active)/page.tsx @@ -1,8 +1,5 @@ -import Image from "next/image" -import Link from "next/link" -import azureSvg from "@/assets/svg/azure.svg" -import telegramSvg from "@/assets/svg/telegram.svg" -import { Card, CardDescription, CardHeader, CardTitle } from "@/components/ui/card" +import { InfoIcon } from "lucide-react" +import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert" import { getServerSession } from "@/server/auth" import { CompleteProfile } from "./complete-profile" @@ -12,33 +9,11 @@ export default async function AdminHome() { session && (
-

Home

- -
- - - - - azure logo - Azure - - Manage Azure related things - - - - - - - - - telegram logo - Telegram - - Manage Telegram related things - - - -
+ + + Page under construction + Use the sidebar to access the sections +
) ) diff --git a/src/components/ui/alert.tsx b/src/components/ui/alert.tsx index e130133..52a36bc 100644 --- a/src/components/ui/alert.tsx +++ b/src/components/ui/alert.tsx @@ -9,6 +9,7 @@ const alertVariants = cva( variants: { variant: { default: "bg-card text-card-foreground", + info: "bg-primary/20 text-primary-foreground", destructive: "bg-card text-destructive *:data-[slot=alert-description]:text-destructive/90 *:[svg]:text-current", }, From d7388b5fb31a14bd712385b4af7dba3b61425eca Mon Sep 17 00:00:00 2001 From: Lorenzo Corallo Date: Sat, 6 Jun 2026 00:05:15 +0200 Subject: [PATCH 24/27] style: button icon svg size --- src/app/dashboard/(active)/layout.tsx | 2 +- src/components/ui/button.tsx | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/app/dashboard/(active)/layout.tsx b/src/app/dashboard/(active)/layout.tsx index 4c1745d..f0b6d5e 100644 --- a/src/app/dashboard/(active)/layout.tsx +++ b/src/app/dashboard/(active)/layout.tsx @@ -29,7 +29,7 @@ export default async function AdminLayout({ children }: { children: React.ReactN
- +
diff --git a/src/components/ui/button.tsx b/src/components/ui/button.tsx index 598ffa0..e696922 100644 --- a/src/components/ui/button.tsx +++ b/src/components/ui/button.tsx @@ -25,12 +25,12 @@ const buttonVariants = cva( xs: "h-6 gap-1 rounded-[min(var(--radius-md),10px)] px-2 text-xs in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3", sm: "h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 text-[0.8rem] in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5", lg: "h-9 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2", - icon: "size-8", + icon: "size-8 [&_svg:not([class*='size-'])]:size-4.5", "icon-xs": "size-6 rounded-[min(var(--radius-md),10px)] in-data-[slot=button-group]:rounded-lg [&_svg:not([class*='size-'])]:size-3", "icon-sm": - "size-7 rounded-[min(var(--radius-md),12px)] in-data-[slot=button-group]:rounded-lg", - "icon-lg": "size-9", + "size-7 rounded-[min(var(--radius-md),12px)] in-data-[slot=button-group]:rounded-lg [&_svg:not([class*='size-'])]:size-4", + "icon-lg": "size-9 [&_svg:not([class*='size-'])]:size-5", }, }, defaultVariants: { From 57d3a2324f62389946b89f06613dc9eb1be5e0ab Mon Sep 17 00:00:00 2001 From: Lorenzo Corallo Date: Sat, 6 Jun 2026 20:38:54 +0200 Subject: [PATCH 25/27] style: fix padding mismatch between pages and loadings --- src/app/dashboard/(active)/azure/members/loading.tsx | 2 +- src/app/dashboard/(active)/telegram/grants/loading.tsx | 4 ++-- src/app/dashboard/(active)/telegram/grants/page.tsx | 2 +- src/app/dashboard/(active)/telegram/groups/loading.tsx | 2 +- src/app/dashboard/(active)/telegram/groups/page.tsx | 2 +- src/app/dashboard/(active)/telegram/user-list/loading.tsx | 4 ++-- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/app/dashboard/(active)/azure/members/loading.tsx b/src/app/dashboard/(active)/azure/members/loading.tsx index ac43fc0..a6bd30c 100644 --- a/src/app/dashboard/(active)/azure/members/loading.tsx +++ b/src/app/dashboard/(active)/azure/members/loading.tsx @@ -2,7 +2,7 @@ import { SkeletonAssocTable } from "./table" export default function Loading() { return ( -
+
) diff --git a/src/app/dashboard/(active)/telegram/grants/loading.tsx b/src/app/dashboard/(active)/telegram/grants/loading.tsx index f74f889..753f796 100644 --- a/src/app/dashboard/(active)/telegram/grants/loading.tsx +++ b/src/app/dashboard/(active)/telegram/grants/loading.tsx @@ -4,8 +4,8 @@ import { NewGrant } from "./new-grant" export default async function Loading() { return ( -
-
+
+

Telegram Grants

diff --git a/src/app/dashboard/(active)/telegram/grants/page.tsx b/src/app/dashboard/(active)/telegram/grants/page.tsx index dc01bc8..ce41ade 100644 --- a/src/app/dashboard/(active)/telegram/grants/page.tsx +++ b/src/app/dashboard/(active)/telegram/grants/page.tsx @@ -9,7 +9,7 @@ export default async function GrantsPage() { return (
-
+

Telegram Grants

diff --git a/src/app/dashboard/(active)/telegram/groups/loading.tsx b/src/app/dashboard/(active)/telegram/groups/loading.tsx index 9bd5207..77b98c0 100644 --- a/src/app/dashboard/(active)/telegram/groups/loading.tsx +++ b/src/app/dashboard/(active)/telegram/groups/loading.tsx @@ -3,7 +3,7 @@ import { SearchInput } from "./search-input" export default async function Loading() { return ( -
+

Count:

diff --git a/src/app/dashboard/(active)/telegram/groups/page.tsx b/src/app/dashboard/(active)/telegram/groups/page.tsx index 897bf1b..8987115 100644 --- a/src/app/dashboard/(active)/telegram/groups/page.tsx +++ b/src/app/dashboard/(active)/telegram/groups/page.tsx @@ -12,7 +12,7 @@ export default async function TgGroups({ searchParams }: { searchParams: Promise const sorted = rows.sort((a, b) => a.title.localeCompare(b.title)) return ( -
+

Count: {rows.length} diff --git a/src/app/dashboard/(active)/telegram/user-list/loading.tsx b/src/app/dashboard/(active)/telegram/user-list/loading.tsx index 55f8aa6..0b79c1a 100644 --- a/src/app/dashboard/(active)/telegram/user-list/loading.tsx +++ b/src/app/dashboard/(active)/telegram/user-list/loading.tsx @@ -2,8 +2,8 @@ import { Skeleton } from "@/components/ui/skeleton" export default async function Loading() { return ( -

-
+
+

Count:

From 5003e80b1ab63e96819953cbee7703ffdbeb535e Mon Sep 17 00:00:00 2001 From: Lorenzo Corallo Date: Sat, 6 Jun 2026 20:43:06 +0200 Subject: [PATCH 26/27] feat: loading skeleton for account page --- .../dashboard/(active)/account/loading.tsx | 34 +++++++++++++++++++ src/components/dashboard-sidebar/main-nav.tsx | 2 +- src/hooks/use-cookie-storage.tsx | 2 +- 3 files changed, 36 insertions(+), 2 deletions(-) create mode 100644 src/app/dashboard/(active)/account/loading.tsx diff --git a/src/app/dashboard/(active)/account/loading.tsx b/src/app/dashboard/(active)/account/loading.tsx new file mode 100644 index 0000000..f67b7c1 --- /dev/null +++ b/src/app/dashboard/(active)/account/loading.tsx @@ -0,0 +1,34 @@ +import { Skeleton } from "@/components/ui/skeleton" +import { NewPasskeyButton } from "./passkey-button" + +export default function Loading() { + return ( +
+

Account

+
+ + +
+
+ Name: + +
+ +
+ Email: + +
+
+ Telegram: + +
+
+
+
+

Passkeys

+ + +
+
+ ) +} diff --git a/src/components/dashboard-sidebar/main-nav.tsx b/src/components/dashboard-sidebar/main-nav.tsx index a9bfc09..556d708 100644 --- a/src/components/dashboard-sidebar/main-nav.tsx +++ b/src/components/dashboard-sidebar/main-nav.tsx @@ -2,7 +2,7 @@ import { ChevronRight } from "lucide-react" import Link from "next/link" import { usePathname } from "next/navigation" -import { useCallback, useEffect, useState } from "react" +import { useState } from "react" import { COOKIES } from "@/constants" import { useCookieStorage } from "@/hooks/use-cookie-storage" import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "../ui/collapsible" diff --git a/src/hooks/use-cookie-storage.tsx b/src/hooks/use-cookie-storage.tsx index 462bb02..a6339cc 100644 --- a/src/hooks/use-cookie-storage.tsx +++ b/src/hooks/use-cookie-storage.tsx @@ -1,4 +1,4 @@ -import { type Dispatch, type SetStateAction, useCallback, useEffect, useMemo, useState } from "react" +import { type Dispatch, type SetStateAction, useCallback, useMemo, useState } from "react" import { type CookieOptions, deleteCookie, getCookie, getDefaultCookieOptions, setCookie } from "@/utils/cookies" export function useCookieStorage( From 0b1596c723876ae73d2afcd3c4aa8e5f5887bc43 Mon Sep 17 00:00:00 2001 From: Lorenzo Corallo Date: Sat, 6 Jun 2026 20:45:38 +0200 Subject: [PATCH 27/27] perf: make dashboard homepage static for now --- .../dashboard/(active)/complete-profile.tsx | 10 ++++++--- src/app/dashboard/(active)/page.tsx | 22 ++++++++----------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/app/dashboard/(active)/complete-profile.tsx b/src/app/dashboard/(active)/complete-profile.tsx index 8de2c3f..89fc4ac 100644 --- a/src/app/dashboard/(active)/complete-profile.tsx +++ b/src/app/dashboard/(active)/complete-profile.tsx @@ -1,13 +1,17 @@ "use client" -import type { User } from "better-auth" import { UserRoundPenIcon } from "lucide-react" import Link from "next/link" import { Button } from "@/components/ui/button" +import { useSession } from "@/lib/auth" + +export function CompleteProfile() { + const { data, isPending } = useSession() + + if (!data || isPending) return null -export function CompleteProfile({ user }: { user: User }) { return ( - !user.name && ( + !data.user.name && (

Your profile is incomplete, please enter the missing information.

diff --git a/src/app/dashboard/(active)/page.tsx b/src/app/dashboard/(active)/page.tsx index 0e13529..a0cb34b 100644 --- a/src/app/dashboard/(active)/page.tsx +++ b/src/app/dashboard/(active)/page.tsx @@ -1,20 +1,16 @@ import { InfoIcon } from "lucide-react" import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert" -import { getServerSession } from "@/server/auth" import { CompleteProfile } from "./complete-profile" -export default async function AdminHome() { - const { data: session } = await getServerSession() +export default function AdminHome() { return ( - session && ( -
- - - - Page under construction - Use the sidebar to access the sections - -
- ) +
+ + + + Page under construction + Use the sidebar to access the sections + +
) }