From 99923dc406cd7b0c873192a8fc3b0d3610d6cb99 Mon Sep 17 00:00:00 2001 From: Aidan Honor Date: Sun, 9 Mar 2025 18:45:12 -0400 Subject: [PATCH] ui: dark mode and design cleanup --- app/admin/layout.tsx | 6 +- app/layout.tsx | 14 +- components/Header.tsx | 16 +- components/Sidebar.tsx | 2 +- components/ThemeProvider.tsx | 11 ++ components/buttons/ThemeSelect.tsx | 43 +++++ components/ui/dropdown-menu.tsx | 257 +++++++++++++++++++++++++++++ package.json | 2 + 8 files changed, 337 insertions(+), 14 deletions(-) create mode 100644 components/ThemeProvider.tsx create mode 100644 components/buttons/ThemeSelect.tsx create mode 100644 components/ui/dropdown-menu.tsx diff --git a/app/admin/layout.tsx b/app/admin/layout.tsx index 89fbe4f..38e8e01 100644 --- a/app/admin/layout.tsx +++ b/app/admin/layout.tsx @@ -1,5 +1,6 @@ -import { SidebarProvider } from "@/components/ui/sidebar" +import { SidebarProvider, SidebarTrigger } from "@/components/ui/sidebar" import Sidebar from "@/components/Sidebar" +import React from "react"; export default function Layout({ children }: { children: React.ReactNode }) { return ( @@ -7,6 +8,9 @@ export default function Layout({ children }: { children: React.ReactNode }) {
{children} +
+ +
) diff --git a/app/layout.tsx b/app/layout.tsx index bcecbf0..7dae129 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -1,6 +1,7 @@ import React from "react" +import { ThemeProvider } from "@/components/ThemeProvider" import "./globals.css" -import '@fontsource-variable/bricolage-grotesque' +import "@fontsource-variable/bricolage-grotesque" export default function RootLayout({ children, @@ -8,9 +9,16 @@ export default function RootLayout({ children: React.ReactNode; }>) { return ( - + - {children} + + {children} + ); diff --git a/components/Header.tsx b/components/Header.tsx index 0cf219a..6018f1c 100644 --- a/components/Header.tsx +++ b/components/Header.tsx @@ -1,26 +1,24 @@ -import { SidebarTrigger } from "@/components/ui/sidebar" +import { ThemeSelect } from "@/components/buttons/ThemeSelect" import Image from "next/image" interface HeaderProps { pageTitle: string; } -export default function Header( - { pageTitle }: HeaderProps -) { +export default function Header({ pageTitle }: HeaderProps) { return ( -
+
-

{pageTitle}

+ Avatar
diff --git a/components/Sidebar.tsx b/components/Sidebar.tsx index 860439c..f75cebc 100644 --- a/components/Sidebar.tsx +++ b/components/Sidebar.tsx @@ -25,7 +25,7 @@ export default function Sidebar() {
-

MailStrike

+

MailStrike

diff --git a/components/ThemeProvider.tsx b/components/ThemeProvider.tsx new file mode 100644 index 0000000..6a1ffe4 --- /dev/null +++ b/components/ThemeProvider.tsx @@ -0,0 +1,11 @@ +"use client" + +import * as React from "react" +import { ThemeProvider as NextThemesProvider } from "next-themes" + +export function ThemeProvider({ + children, + ...props +}: React.ComponentProps) { + return {children} +} diff --git a/components/buttons/ThemeSelect.tsx b/components/buttons/ThemeSelect.tsx new file mode 100644 index 0000000..68feda4 --- /dev/null +++ b/components/buttons/ThemeSelect.tsx @@ -0,0 +1,43 @@ +"use client" + +import * as React from "react" +import { Moon, Sun } from "lucide-react" +import { useTheme } from "next-themes" +import { Button } from "@/components/ui/button" +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuTrigger, +} from "@/components/ui/dropdown-menu" + +interface TsProps { + className?: string +} + +export function ThemeSelect({ className }: TsProps) { + const { setTheme } = useTheme() + + return ( + + + + + + setTheme("light")}> + Light + + setTheme("dark")}> + Dark + + setTheme("system")}> + System + + + + ) +} diff --git a/components/ui/dropdown-menu.tsx b/components/ui/dropdown-menu.tsx new file mode 100644 index 0000000..331a346 --- /dev/null +++ b/components/ui/dropdown-menu.tsx @@ -0,0 +1,257 @@ +"use client" + +import * as React from "react" +import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu" +import { CheckIcon, ChevronRightIcon, CircleIcon } from "lucide-react" + +import { cn } from "@/lib/utils" + +function DropdownMenu({ + ...props +}: React.ComponentProps) { + return +} + +function DropdownMenuPortal({ + ...props +}: React.ComponentProps) { + return ( + + ) +} + +function DropdownMenuTrigger({ + ...props +}: React.ComponentProps) { + return ( + + ) +} + +function DropdownMenuContent({ + className, + sideOffset = 4, + ...props +}: React.ComponentProps) { + return ( + + + + ) +} + +function DropdownMenuGroup({ + ...props +}: React.ComponentProps) { + return ( + + ) +} + +function DropdownMenuItem({ + className, + inset, + variant = "default", + ...props +}: React.ComponentProps & { + inset?: boolean + variant?: "default" | "destructive" +}) { + return ( + + ) +} + +function DropdownMenuCheckboxItem({ + className, + children, + checked, + ...props +}: React.ComponentProps) { + return ( + + + + + + + {children} + + ) +} + +function DropdownMenuRadioGroup({ + ...props +}: React.ComponentProps) { + return ( + + ) +} + +function DropdownMenuRadioItem({ + className, + children, + ...props +}: React.ComponentProps) { + return ( + + + + + + + {children} + + ) +} + +function DropdownMenuLabel({ + className, + inset, + ...props +}: React.ComponentProps & { + inset?: boolean +}) { + return ( + + ) +} + +function DropdownMenuSeparator({ + className, + ...props +}: React.ComponentProps) { + return ( + + ) +} + +function DropdownMenuShortcut({ + className, + ...props +}: React.ComponentProps<"span">) { + return ( + + ) +} + +function DropdownMenuSub({ + ...props +}: React.ComponentProps) { + return +} + +function DropdownMenuSubTrigger({ + className, + inset, + children, + ...props +}: React.ComponentProps & { + inset?: boolean +}) { + return ( + + {children} + + + ) +} + +function DropdownMenuSubContent({ + className, + ...props +}: React.ComponentProps) { + return ( + + ) +} + +export { + DropdownMenu, + DropdownMenuPortal, + DropdownMenuTrigger, + DropdownMenuContent, + DropdownMenuGroup, + DropdownMenuLabel, + DropdownMenuItem, + DropdownMenuCheckboxItem, + DropdownMenuRadioGroup, + DropdownMenuRadioItem, + DropdownMenuSeparator, + DropdownMenuShortcut, + DropdownMenuSub, + DropdownMenuSubTrigger, + DropdownMenuSubContent, +} diff --git a/package.json b/package.json index a3c5305..8fe9a32 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ "dependencies": { "@fontsource-variable/bricolage-grotesque": "^5.2.5", "@radix-ui/react-dialog": "^1.1.6", + "@radix-ui/react-dropdown-menu": "^2.1.6", "@radix-ui/react-progress": "^1.1.2", "@radix-ui/react-separator": "^1.1.2", "@radix-ui/react-slot": "^1.1.2", @@ -19,6 +20,7 @@ "clsx": "^2.1.1", "lucide-react": "^0.479.0", "next": "15.2.2-canary.5", + "next-themes": "^0.4.4", "react": "^19.0.0", "react-dom": "^19.0.0", "react-icons": "^5.5.0",