diff --git a/src/app/(PAGES)/layout.tsx b/src/app/(PAGES)/layout.tsx index 6d49978..c7f4ad4 100644 --- a/src/app/(PAGES)/layout.tsx +++ b/src/app/(PAGES)/layout.tsx @@ -2,18 +2,23 @@ import { AppSidebar } from "@/components/layout/app-sidebar"; import Navbar from "@/components/layout/navbar"; import { SidebarProvider } from "@/components/ui/sidebar"; import { auth } from "@/server/auth"; +import { api, HydrateClient } from "@/trpc/server"; import React from "react"; async function Layout({ children }: { children: React.ReactNode }) { const session = await auth(); + void api.app.getSidebarMain.prefetch(); + return ( - - -
- -
{children}
-
-
+ + + +
+ +
{children}
+
+
+
); } diff --git a/src/components/article/article-filter-bar.tsx b/src/components/article/article-filter-bar.tsx index 12462a3..2090c4f 100644 --- a/src/components/article/article-filter-bar.tsx +++ b/src/components/article/article-filter-bar.tsx @@ -91,7 +91,7 @@ function ArticleFilterBar({ sort: currentValue?.length ? currentValue : undefined, }); }} - className="w-full" + className="w-full lg:max-w-64" messageUi={{ selectIcon: FilterIcon, select: "Sortieren", diff --git a/src/components/layout/app-sidebar/index.tsx b/src/components/layout/app-sidebar/index.tsx index 5dba202..05235f0 100644 --- a/src/components/layout/app-sidebar/index.tsx +++ b/src/components/layout/app-sidebar/index.tsx @@ -1,6 +1,5 @@ "use client"; import * as React from "react"; -import { Folder, LifeBuoy, Newspaper, Send } from "lucide-react"; import { NavMain } from "./nav-main"; @@ -19,71 +18,6 @@ import NavBranding from "./nav-branding"; import { Icons } from "@/components/icons"; import { appConfig } from "@/config"; -const data = { - user: { - name: "shadcn", - email: "m@example.com", - avatar: "/avatars/shadcn.jpg", - }, - navMain: [ - { - title: "Artikel", - url: "/artikel", - isActive: true, - icon: Newspaper, - items: [ - { - title: "Genesis", - url: "#", - }, - { - title: "Explorer", - url: "#", - }, - { - title: "Quantum", - url: "#", - }, - { - title: "Alle Artikel", - url: "/artikel", - }, - ], - }, - { - title: "Kategorien", - url: "/kategorien", - icon: Folder, - items: [ - { - title: "History", - url: "#", - }, - { - title: "Starred", - url: "#", - }, - { - title: "Settings", - url: "#", - }, - { - title: "Alle Kategorien", - url: "#", - }, - ], - }, - ], - navSecondary: [ - { - title: "Discord", - url: appConfig.socials.discord, - icon: Icons.discord, - external: true, - }, - ], -}; - export function AppSidebar({ ...props }: React.ComponentProps & { user?: User | null }) { @@ -93,7 +27,8 @@ export function AppSidebar({ - + + @@ -103,3 +38,14 @@ export function AppSidebar({ ); } + +const data = { + navSecondary: [ + { + title: "Discord", + url: appConfig.socials.discord, + icon: Icons.discord, + external: true, + }, + ], +}; diff --git a/src/components/layout/app-sidebar/nav-branding.tsx b/src/components/layout/app-sidebar/nav-branding.tsx index 9548880..28b004a 100644 --- a/src/components/layout/app-sidebar/nav-branding.tsx +++ b/src/components/layout/app-sidebar/nav-branding.tsx @@ -1,18 +1,24 @@ +"use client"; import React from "react"; import { SidebarMenu, SidebarMenuButton, SidebarMenuItem, + useSidebar, } from "@/components/ui/sidebar"; import { Icons } from "@/components/icons"; import { appConfig } from "@/config"; import Link from "next/link"; +import { cn } from "@/lib/utils"; +import { XIcon } from "lucide-react"; +import { Button } from "@/components/ui/button"; function NavBranding({ subTitle }: { subTitle: string }) { + const { isMobile, toggleSidebar } = useSidebar(); return ( - - - + + +
@@ -24,6 +30,15 @@ function NavBranding({ subTitle }: { subTitle: string }) { + {isMobile && ( + + + + + + )} ); } diff --git a/src/components/layout/app-sidebar/nav-main.tsx b/src/components/layout/app-sidebar/nav-main.tsx index 07a5d9e..499691c 100644 --- a/src/components/layout/app-sidebar/nav-main.tsx +++ b/src/components/layout/app-sidebar/nav-main.tsx @@ -1,5 +1,4 @@ "use client"; - import { ChevronRight, type LucideIcon } from "lucide-react"; import { @@ -18,22 +17,45 @@ import { SidebarMenuSubButton, SidebarMenuSubItem, } from "@/components/ui/sidebar"; +import { Skeleton } from "@/components/ui/skeleton"; +import { api } from "@/trpc/react"; +import { Icons } from "@/components/icons"; -export function NavMain({ - items, -}: { - items: { - title: string; - url: string; - icon: LucideIcon; - isActive?: boolean; - items?: { - title: string; - url: string; - hideBorder?: boolean; - }[]; - }[]; -}) { +export function NavMain() { + const [{ articles, categories }] = api.app.getSidebarMain.useSuspenseQuery(); + const items = [ + { + title: "Artikel", + url: "/artikel", + isActive: true, + icon: Icons.article, + items: [ + ...articles.map((article) => ({ + title: article.title, + url: `/artikel/${article.slug}`, + })), + { + title: "Alle Artikel", + url: "/artikel", + }, + ], + }, + { + title: "Kategorien", + url: "/kategorie", + icon: Icons.category, + items: [ + ...categories.map((category) => ({ + title: category.name, + url: `/kategorie/${category.slug}`, + })), + { + title: "Alle Kategorien", + url: "#", + }, + ], + }, + ]; return ( Platform @@ -77,3 +99,20 @@ export function NavMain({ ); } + +export function NavMainSkeleton() { + return ( + + Platform + + {Array.from({ length: 6 }).map((_, i) => ( + + + + + + ))} + + + ); +} diff --git a/src/components/layout/app-sidebar/sidebar-trigger.tsx b/src/components/layout/app-sidebar/sidebar-trigger.tsx new file mode 100644 index 0000000..e348439 --- /dev/null +++ b/src/components/layout/app-sidebar/sidebar-trigger.tsx @@ -0,0 +1,24 @@ +"use client"; +import { Button } from "@/components/ui/button"; +import { useSidebar } from "@/components/ui/sidebar"; +import { cn } from "@/lib/utils"; +import { ChevronRightIcon, MenuIcon } from "lucide-react"; + +export function SidebarTrigger() { + const { toggleSidebar, state, isMobile } = useSidebar(); + const open = state === "expanded"; + return ( + + ); +} diff --git a/src/components/layout/navbar.tsx b/src/components/layout/navbar.tsx index 8752c65..2ab24e6 100644 --- a/src/components/layout/navbar.tsx +++ b/src/components/layout/navbar.tsx @@ -5,6 +5,7 @@ import { hasPermission, Role } from "@/lib/validation/permissions"; import { ModeToggle } from "../mode-switch"; import EditorDropdown from "../editor-dropdown"; +import { SidebarTrigger } from "./app-sidebar/sidebar-trigger"; async function Navbar() { const session = await auth(); @@ -13,10 +14,13 @@ async function Navbar() { : false; return ( -
- {isEditor && } +
+ +
+ {isEditor && } - + +
); } diff --git a/src/server/api/routers/app.ts b/src/server/api/routers/app.ts index 26ffe5a..6e5fb1d 100644 --- a/src/server/api/routers/app.ts +++ b/src/server/api/routers/app.ts @@ -24,16 +24,24 @@ export const appRouter = createTRPCRouter({ return { articles, categories }; }), - getSidebarContent: publicProcedure.query(async ({ ctx }) => { - return await ctx.db.query.categories.findMany({ - with: { - articles: { - columns: { - title: true, - slug: true, - }, - }, + getSidebarMain: publicProcedure.query(async ({ ctx }) => { + const categories = await ctx.db.query.categories.findMany({ + limit: 3, + columns: { + slug: true, + name: true, }, }); + const articles = await ctx.db.query.articles.findMany({ + limit: 3, + columns: { + slug: true, + title: true, + }, + }); + return { + categories, + articles, + }; }), }); diff --git a/src/styles/globals.css b/src/styles/globals.css index ef28557..29eab60 100644 --- a/src/styles/globals.css +++ b/src/styles/globals.css @@ -29,8 +29,8 @@ --chart-3: 197 37% 24%; --chart-4: 43 74% 66%; --chart-5: 27 87% 67%; - /* --sidebar-background: 0 0% 98%; - --sidebar-foreground: 240 5.3% 26.1%; */ + --sidebar-background: 0 0% 100%; + --sidebar-foreground: 240 10% 3.9%; --sidebar-primary: 240 5.9% 10%; --sidebar-primary-foreground: 0 0% 98%; --sidebar-accent: 240 4.8% 95.9%; @@ -40,9 +40,9 @@ } .dark { - --background: 240 10% 3.9%; + --background: 240 10% 1%; --foreground: 0 0% 98%; - --card: 240 10% 3.9%; + --card: 240 10% 1%; --card-foreground: 0 0% 98%; --popover: 240 10% 3.9%; --popover-foreground: 0 0% 98%; @@ -64,8 +64,8 @@ --chart-3: 30 80% 55%; --chart-4: 280 65% 60%; --chart-5: 340 75% 55%; - /* --sidebar-background: 240 5.9% 10%; - --sidebar-foreground: 240 4.8% 95.9%; */ + --sidebar-background: 240 10% 1%; + --sidebar-foreground: 0 0% 98%; --sidebar-primary: 224.3 76.3% 48%; --sidebar-primary-foreground: 0 0% 100%; --sidebar-accent: 240 3.7% 15.9%;