Skip to content

Commit ea8ba50

Browse files
authored
feat: 🎸 Add Navbar component and integrate the theme toggle button (#16)
1 parent f5f123a commit ea8ba50

File tree

5 files changed

+389
-12
lines changed

5 files changed

+389
-12
lines changed

Diff for: app/page.tsx

+2-9
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,12 @@ import { ThemeToggle } from "@/components/theme-toggle"
99
import { BookOpen, CheckCircle, Github } from 'lucide-react'
1010
import { SocialLinks } from "@/components/socials"
1111
import { Highlight } from "@/components/ui/hero-hihglight";
12+
import Navbar from '@/components/header'
1213

1314
export default function LandingPage() {
1415
return (
1516
<div className="flex flex-col min-h-screen bg-background">
16-
<header className="px-4 lg:px-6 h-16 flex items-center sticky top-0 w-full bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60 z-50 border-b">
17-
<Link className="flex items-center justify-center" href="#">
18-
<BookOpen className="h-6 w-6 mr-2 text-primary" />
19-
<span className="font-bold text-lg">LeetCode Journal</span>
20-
</Link>
21-
<nav className="ml-auto flex gap-4 sm:gap-6">
22-
<ThemeToggle />
23-
</nav>
24-
</header>
17+
<Navbar/>
2518
<main className="flex-1">
2619
<section className="w-full py-12 md:py-24 lg:py-32 bg-secondary overflow-hidden">
2720
<div className="container px-4 md:px-6 relative z-10">

Diff for: components/header.tsx

+96
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
'use client'
2+
import { FC, useState } from "react";
3+
import Link from "next/link";
4+
import { Button } from "@/components/ui/button";
5+
import { ThemeToggle } from "@/components/theme-toggle";
6+
7+
const Navbar: FC = () => {
8+
const [isMenuOpen, setIsMenuOpen] = useState(false);
9+
10+
return (
11+
<header>
12+
13+
<nav className="flex justify-between items-center px-6 py-4 bg-gray-900 text-white dark:bg-gray-800">
14+
<div className="flex items-center space-x-2">
15+
<span className="text-2xl font-bold">📓</span>
16+
<span className="text-xl font-semibold">LeetCodeJournal</span>
17+
</div>
18+
<div className="hidden lg:flex space-x-6">
19+
<Link href="#" className="hover:text-purple-400 ">
20+
Home
21+
</Link>
22+
<Link href="#" className="hover:text-purple-400 ">
23+
Features
24+
</Link>
25+
<Link href="#" className="hover:text-purple-400 ">
26+
How it Works
27+
</Link>
28+
<Link href="#" className="hover:text-purple-400 ">
29+
FAQs
30+
</Link>
31+
<Link href="#" className="hover:text-purple-400 ">
32+
Blog
33+
</Link>
34+
</div>
35+
<div className="hidden lg:flex items-center space-x-4">
36+
<Link href="#" className="hover:text-gray-400">
37+
Log in
38+
</Link>
39+
<Button className="bg-purple-500 hover:bg-purple-600">Sign up</Button>
40+
<ThemeToggle />
41+
</div>
42+
<button
43+
onClick={() => setIsMenuOpen(!isMenuOpen)}
44+
className="lg:hidden focus:outline-none"
45+
>
46+
{isMenuOpen ? "✖️" : "☰"}
47+
</button>
48+
</nav>
49+
50+
51+
{isMenuOpen && (
52+
<div className="fixed inset-x-0 top-[65px] z-50 border-b bg-background p-6 lg:hidden">
53+
<nav className="flex flex-col space-y-4">
54+
<Link
55+
href="#"
56+
className="text-sm font-medium transition-colors hover:text-primary"
57+
onClick={() => setIsMenuOpen(false)}
58+
>
59+
Home
60+
</Link>
61+
<Link
62+
href="#"
63+
className="text-sm font-medium transition-colors hover:text-primary"
64+
onClick={() => setIsMenuOpen(false)}
65+
>
66+
Features
67+
</Link>
68+
<Link
69+
href="#"
70+
className="text-sm font-medium transition-colors hover:text-primary"
71+
onClick={() => setIsMenuOpen(false)}
72+
>
73+
How it Works
74+
</Link>
75+
<Link
76+
href="#"
77+
className="text-sm font-medium transition-colors hover:text-primary"
78+
onClick={() => setIsMenuOpen(false)}
79+
>
80+
FAQs
81+
</Link>
82+
<Link
83+
href="#"
84+
className="text-sm font-medium transition-colors hover:text-primary"
85+
onClick={() => setIsMenuOpen(false)}
86+
>
87+
Blog
88+
</Link>
89+
</nav>
90+
</div>
91+
)}
92+
</header>
93+
);
94+
};
95+
96+
export default Navbar;

Diff for: components/ui/sheet.tsx

+140
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
"use client"
2+
3+
import * as React from "react"
4+
import * as SheetPrimitive from "@radix-ui/react-dialog"
5+
import { cva, type VariantProps } from "class-variance-authority"
6+
import { X } from "lucide-react"
7+
8+
import { cn } from "@/lib/utils"
9+
10+
const Sheet = SheetPrimitive.Root
11+
12+
const SheetTrigger = SheetPrimitive.Trigger
13+
14+
const SheetClose = SheetPrimitive.Close
15+
16+
const SheetPortal = SheetPrimitive.Portal
17+
18+
const SheetOverlay = React.forwardRef<
19+
React.ElementRef<typeof SheetPrimitive.Overlay>,
20+
React.ComponentPropsWithoutRef<typeof SheetPrimitive.Overlay>
21+
>(({ className, ...props }, ref) => (
22+
<SheetPrimitive.Overlay
23+
className={cn(
24+
"fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
25+
className
26+
)}
27+
{...props}
28+
ref={ref}
29+
/>
30+
))
31+
SheetOverlay.displayName = SheetPrimitive.Overlay.displayName
32+
33+
const sheetVariants = cva(
34+
"fixed z-50 gap-4 bg-background p-6 shadow-lg transition ease-in-out data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:duration-300 data-[state=open]:duration-500",
35+
{
36+
variants: {
37+
side: {
38+
top: "inset-x-0 top-0 border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top",
39+
bottom:
40+
"inset-x-0 bottom-0 border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom",
41+
left: "inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm",
42+
right:
43+
"inset-y-0 right-0 h-full w-3/4 border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm",
44+
},
45+
},
46+
defaultVariants: {
47+
side: "right",
48+
},
49+
}
50+
)
51+
52+
interface SheetContentProps
53+
extends React.ComponentPropsWithoutRef<typeof SheetPrimitive.Content>,
54+
VariantProps<typeof sheetVariants> {}
55+
56+
const SheetContent = React.forwardRef<
57+
React.ElementRef<typeof SheetPrimitive.Content>,
58+
SheetContentProps
59+
>(({ side = "right", className, children, ...props }, ref) => (
60+
<SheetPortal>
61+
<SheetOverlay />
62+
<SheetPrimitive.Content
63+
ref={ref}
64+
className={cn(sheetVariants({ side }), className)}
65+
{...props}
66+
>
67+
{children}
68+
<SheetPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-secondary">
69+
<X className="h-4 w-4" />
70+
<span className="sr-only">Close</span>
71+
</SheetPrimitive.Close>
72+
</SheetPrimitive.Content>
73+
</SheetPortal>
74+
))
75+
SheetContent.displayName = SheetPrimitive.Content.displayName
76+
77+
const SheetHeader = ({
78+
className,
79+
...props
80+
}: React.HTMLAttributes<HTMLDivElement>) => (
81+
<div
82+
className={cn(
83+
"flex flex-col space-y-2 text-center sm:text-left",
84+
className
85+
)}
86+
{...props}
87+
/>
88+
)
89+
SheetHeader.displayName = "SheetHeader"
90+
91+
const SheetFooter = ({
92+
className,
93+
...props
94+
}: React.HTMLAttributes<HTMLDivElement>) => (
95+
<div
96+
className={cn(
97+
"flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",
98+
className
99+
)}
100+
{...props}
101+
/>
102+
)
103+
SheetFooter.displayName = "SheetFooter"
104+
105+
const SheetTitle = React.forwardRef<
106+
React.ElementRef<typeof SheetPrimitive.Title>,
107+
React.ComponentPropsWithoutRef<typeof SheetPrimitive.Title>
108+
>(({ className, ...props }, ref) => (
109+
<SheetPrimitive.Title
110+
ref={ref}
111+
className={cn("text-lg font-semibold text-foreground", className)}
112+
{...props}
113+
/>
114+
))
115+
SheetTitle.displayName = SheetPrimitive.Title.displayName
116+
117+
const SheetDescription = React.forwardRef<
118+
React.ElementRef<typeof SheetPrimitive.Description>,
119+
React.ComponentPropsWithoutRef<typeof SheetPrimitive.Description>
120+
>(({ className, ...props }, ref) => (
121+
<SheetPrimitive.Description
122+
ref={ref}
123+
className={cn("text-sm text-muted-foreground", className)}
124+
{...props}
125+
/>
126+
))
127+
SheetDescription.displayName = SheetPrimitive.Description.displayName
128+
129+
export {
130+
Sheet,
131+
SheetPortal,
132+
SheetOverlay,
133+
SheetTrigger,
134+
SheetClose,
135+
SheetContent,
136+
SheetHeader,
137+
SheetFooter,
138+
SheetTitle,
139+
SheetDescription,
140+
}

0 commit comments

Comments
 (0)