Skip to content

Commit 9df2527

Browse files
committed
Sidebar and Navbar added
1 parent c575890 commit 9df2527

14 files changed

Lines changed: 2121 additions & 52 deletions

package.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,11 @@
1717
"@radix-ui/react-icons": "^1.3.0",
1818
"@radix-ui/react-label": "^2.1.1",
1919
"@radix-ui/react-popover": "^1.1.5",
20+
"@radix-ui/react-scroll-area": "^1.2.2",
2021
"@radix-ui/react-select": "^2.1.5",
2122
"@radix-ui/react-separator": "^1.1.1",
22-
"@radix-ui/react-slot": "^1.1.0",
23+
"@radix-ui/react-slot": "^1.1.1",
24+
"@radix-ui/react-tooltip": "^1.1.7",
2325
"@t3-oss/env-nextjs": "^0.10.1",
2426
"@tanstack/react-query": "^5.53.1",
2527
"@tanstack/react-query-devtools": "^5.53.1",
@@ -36,6 +38,7 @@
3638
"react": "^18.3.1",
3739
"react-dom": "^18.3.1",
3840
"react-hot-toast": "^2.4.1",
41+
"shadcn-ui": "^0.9.4",
3942
"tailwind-merge": "^2.5.2",
4043
"tailwindcss-animate": "^1.0.7",
4144
"zod": "^3.23.3"

pnpm-lock.yaml

Lines changed: 922 additions & 10 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/app/layout.tsx

Lines changed: 133 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,37 @@
1+
// app/layout.tsx
12
import Providers from "@/lib/Providers";
23
import "@/styles/globals.css";
34
import { GeistSans } from "geist/font/sans";
45
import { type Metadata } from "next";
56
import { Toaster } from "react-hot-toast";
6-
import { ThemeProvider } from "@/components/theme-provider"
7+
import { ThemeProvider } from "@/components/theme-provider";
8+
import {
9+
Sheet,
10+
SheetContent,
11+
SheetTrigger,
12+
} from "@/components/ui/sheet";
13+
import { Button } from "@/components/ui/button";
14+
import Link from "next/link";
15+
import {
16+
Avatar,
17+
AvatarFallback,
18+
AvatarImage,
19+
} from "@/components/ui/avatar";
20+
import {
21+
DropdownMenu,
22+
DropdownMenuContent,
23+
DropdownMenuItem,
24+
DropdownMenuTrigger,
25+
} from "@/components/ui/dropdown-menu";
26+
import { ScrollArea } from "@/components/ui/scroll-area";
27+
import {
28+
HomeIcon,
29+
UsersIcon,
30+
GroupIcon,
31+
MenuIcon,
32+
LogOutIcon,
33+
} from "lucide-react";
34+
735

836
export const metadata: Metadata = {
937
title: "CodeChef-VIT",
@@ -26,25 +54,110 @@ export const metadata: Metadata = {
2654
],
2755
};
2856

57+
2958
export default function RootLayout({
30-
children,
31-
}: Readonly<{ children: React.ReactNode }>) {
32-
return (
33-
<html lang="en" className={`${GeistSans.variable}`}>
34-
<body>
35-
<div className="bg-black ">
36-
<Toaster position="top-right" toastOptions={{ id: "_toast" }} />
37-
<Providers>
38-
<ThemeProvider
39-
attribute="class"
40-
defaultTheme="dark"
41-
enableSystem
42-
disableTransitionOnChange
43-
>
59+
children,
60+
}: {
61+
children: React.ReactNode;
62+
}) {
63+
return (
64+
<html lang="en" className={`${GeistSans.variable}`}>
65+
<body >
66+
<Providers>
67+
<ThemeProvider
68+
attribute="class"
69+
defaultTheme="dark"
70+
enableSystem
71+
disableTransitionOnChange
72+
>
73+
<Toaster position="top-right" toastOptions={{ id: "_toast" }} />
74+
<div className="flex h-screen bg-black">
75+
<Sidebar />
76+
<div className="flex flex-col flex-1">
77+
<Navbar />
78+
<main className="flex-1 p-8">
79+
{children}
80+
</main>
81+
</div>
82+
</div>
83+
</ThemeProvider>
84+
</Providers>
85+
</body>
86+
</html>
87+
);
88+
}
89+
4490

45-
{children}</ThemeProvider></Providers>
91+
function Sidebar() {
92+
const navigation = [
93+
{ name: "Dashboard", href: "/dashboard", icon: HomeIcon },
94+
{ name: "Users", href: "/users", icon: UsersIcon },
95+
{ name: "Teams", href: "/teams", icon: GroupIcon },
96+
];
97+
98+
return (
99+
<aside className="border-r border-gray-200 h-full w-64 dark:border-gray-700">
100+
<ScrollArea className="h-full">
101+
<div className="p-4">
102+
<Link href="/" className="text-2xl font-bold mb-6 block">
103+
CodeChef Admin
104+
</Link>
105+
</div>
106+
<nav className="px-2 py-4">
107+
{navigation.map((item) => (
108+
<Link
109+
key={item.name}
110+
href={item.href}
111+
className="flex items-center space-x-2 px-3 py-2 rounded-md hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors duration-200 font-medium text-gray-700 dark:text-gray-300"
112+
>
113+
<item.icon className="h-4 w-4" />
114+
<span>{item.name}</span>
115+
</Link>
116+
))}
117+
</nav>
118+
</ScrollArea>
119+
</aside>
120+
);
121+
}
122+
function Navbar() {
123+
return (
124+
<nav className="flex items-center justify-between border-b border-gray-200 dark:border-gray-700 p-4">
125+
<div className="block md:hidden">
126+
<Sheet>
127+
<SheetTrigger asChild>
128+
<Button variant="ghost" size="icon">
129+
<MenuIcon className="h-5 w-5" />
130+
</Button>
131+
</SheetTrigger>
132+
<SheetContent side="left" className="p-0">
133+
<Sidebar />
134+
</SheetContent>
135+
</Sheet>
136+
</div>
137+
138+
<div className="text-xl font-semibold text-gray-700 dark:text-white">
139+
Admin Panel
140+
</div>
141+
<div className="flex items-center space-x-4">
142+
<DropdownMenu>
143+
<DropdownMenuTrigger asChild>
144+
<Button variant="ghost" className="relative">
145+
<Avatar>
146+
<AvatarImage src="https://github.com/shadcn.png" />
147+
<AvatarFallback>CN</AvatarFallback>
148+
</Avatar>
149+
</Button>
150+
</DropdownMenuTrigger>
151+
<DropdownMenuContent align="end">
152+
<DropdownMenuItem>
153+
<Link href="/api/auth/signout" className="flex items-center">
154+
<LogOutIcon className="mr-2 h-4 w-4" />
155+
Log out
156+
</Link>
157+
</DropdownMenuItem>
158+
</DropdownMenuContent>
159+
</DropdownMenu>
46160
</div>
47-
</body>
48-
</html>
49-
);
50-
}
161+
</nav>
162+
);
163+
}

src/components/ui/button.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { cva, type VariantProps } from "class-variance-authority"
55
import { cn } from "@/lib/utils"
66

77
const buttonVariants = cva(
8-
"inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50",
8+
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
99
{
1010
variants: {
1111
variant: {

src/components/ui/dropdown-menu.tsx

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,8 @@
22

33
import * as React from "react"
44
import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu"
5-
import { Check, ChevronRight, Circle } from "lucide-react"
6-
75
import { cn } from "@/lib/utils"
6+
import { CheckIcon, ChevronRightIcon, DotFilledIcon } from "@radix-ui/react-icons"
87

98
const DropdownMenu = DropdownMenuPrimitive.Root
109

@@ -34,7 +33,7 @@ const DropdownMenuSubTrigger = React.forwardRef<
3433
{...props}
3534
>
3635
{children}
37-
<ChevronRight className="ml-auto" />
36+
<ChevronRightIcon className="ml-auto" />
3837
</DropdownMenuPrimitive.SubTrigger>
3938
))
4039
DropdownMenuSubTrigger.displayName =
@@ -108,7 +107,7 @@ const DropdownMenuCheckboxItem = React.forwardRef<
108107
>
109108
<span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
110109
<DropdownMenuPrimitive.ItemIndicator>
111-
<Check className="h-4 w-4" />
110+
<CheckIcon className="h-4 w-4" />
112111
</DropdownMenuPrimitive.ItemIndicator>
113112
</span>
114113
{children}
@@ -131,7 +130,7 @@ const DropdownMenuRadioItem = React.forwardRef<
131130
>
132131
<span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
133132
<DropdownMenuPrimitive.ItemIndicator>
134-
<Circle className="h-2 w-2 fill-current" />
133+
<DotFilledIcon className="h-2 w-2 fill-current" />
135134
</DropdownMenuPrimitive.ItemIndicator>
136135
</span>
137136
{children}

src/components/ui/input.tsx

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,22 @@
1-
import * as React from "react";
1+
import * as React from "react"
22

3-
import { cn } from "@/lib/utils";
3+
import { cn } from "@/lib/utils"
44

5-
export type InputProps = React.InputHTMLAttributes<HTMLInputElement>
6-
7-
const Input = React.forwardRef<HTMLInputElement, InputProps>(
5+
const Input = React.forwardRef<HTMLInputElement, React.ComponentProps<"input">>(
86
({ className, type, ...props }, ref) => {
97
return (
108
<input
119
type={type}
1210
className={cn(
13-
"flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50",
14-
className,
11+
"flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
12+
className
1513
)}
1614
ref={ref}
1715
{...props}
1816
/>
19-
);
20-
},
21-
);
22-
Input.displayName = "Input";
17+
)
18+
}
19+
)
20+
Input.displayName = "Input"
2321

24-
export { Input };
22+
export { Input }

src/components/ui/scroll-area.tsx

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
"use client"
2+
3+
import * as React from "react"
4+
import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area"
5+
6+
import { cn } from "@/lib/utils"
7+
8+
const ScrollArea = React.forwardRef<
9+
React.ElementRef<typeof ScrollAreaPrimitive.Root>,
10+
React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.Root>
11+
>(({ className, children, ...props }, ref) => (
12+
<ScrollAreaPrimitive.Root
13+
ref={ref}
14+
className={cn("relative overflow-hidden", className)}
15+
{...props}
16+
>
17+
<ScrollAreaPrimitive.Viewport className="h-full w-full rounded-[inherit]">
18+
{children}
19+
</ScrollAreaPrimitive.Viewport>
20+
<ScrollBar />
21+
<ScrollAreaPrimitive.Corner />
22+
</ScrollAreaPrimitive.Root>
23+
))
24+
ScrollArea.displayName = ScrollAreaPrimitive.Root.displayName
25+
26+
const ScrollBar = React.forwardRef<
27+
React.ElementRef<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>,
28+
React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>
29+
>(({ className, orientation = "vertical", ...props }, ref) => (
30+
<ScrollAreaPrimitive.ScrollAreaScrollbar
31+
ref={ref}
32+
orientation={orientation}
33+
className={cn(
34+
"flex touch-none select-none transition-colors",
35+
orientation === "vertical" &&
36+
"h-full w-2.5 border-l border-l-transparent p-[1px]",
37+
orientation === "horizontal" &&
38+
"h-2.5 flex-col border-t border-t-transparent p-[1px]",
39+
className
40+
)}
41+
{...props}
42+
>
43+
<ScrollAreaPrimitive.ScrollAreaThumb className="relative flex-1 rounded-full bg-border" />
44+
</ScrollAreaPrimitive.ScrollAreaScrollbar>
45+
))
46+
ScrollBar.displayName = ScrollAreaPrimitive.ScrollAreaScrollbar.displayName
47+
48+
export { ScrollArea, ScrollBar }

0 commit comments

Comments
 (0)