Skip to content

Commit c5d22b3

Browse files
Merge pull request #2 from Shitanshukumar607/create-navbar
Add Navbar and ThemeProvider components with theme toggle functionality
2 parents d77ed40 + 992889c commit c5d22b3

File tree

6 files changed

+131
-89
lines changed

6 files changed

+131
-89
lines changed

app/layout.tsx

Lines changed: 17 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,31 @@
1-
import type { Metadata } from "next";
2-
import { Geist, Geist_Mono } from "next/font/google";
1+
import Navbar from "@/components/NavbarComponents/Navbar";
2+
import { ThemeProvider } from "@/components/NavbarComponents/ThemeProvider";
3+
import { Space_Grotesk } from "next/font/google";
34
import "./globals.css";
45

5-
const geistSans = Geist({
6-
variable: "--font-geist-sans",
6+
const spaceGrotesk = Space_Grotesk({
7+
variable: "--font-space-grotesk",
78
subsets: ["latin"],
9+
weight: ["300", "400", "500", "600", "700"],
810
});
911

10-
const geistMono = Geist_Mono({
11-
variable: "--font-geist-mono",
12-
subsets: ["latin"],
13-
});
14-
15-
export const metadata: Metadata = {
16-
title: "Create Next App",
17-
description: "Generated by create next app",
18-
};
19-
2012
export default function RootLayout({
2113
children,
2214
}: Readonly<{
2315
children: React.ReactNode;
2416
}>) {
2517
return (
26-
<html lang="en">
27-
<body
28-
className={`${geistSans.variable} ${geistMono.variable} antialiased`}
29-
>
30-
{children}
18+
<html lang="en" suppressHydrationWarning>
19+
<body className={`${spaceGrotesk.className} font-sans antialiased`}>
20+
<ThemeProvider
21+
attribute="class"
22+
defaultTheme="system"
23+
enableSystem
24+
disableTransitionOnChange
25+
>
26+
<Navbar />
27+
<main>{children}</main>
28+
</ThemeProvider>
3129
</body>
3230
</html>
3331
);
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
"use client";
2+
3+
import { Home, ImageUp } from "lucide-react";
4+
import Link from "next/link";
5+
import { usePathname } from "next/navigation";
6+
import ThemeToggle from "./ThemeToggle";
7+
8+
export default function Navbar() {
9+
const pathname = usePathname();
10+
11+
const links = [
12+
{ name: "Home", href: "/", icon: Home },
13+
{ name: "Generate", href: "/generate", icon: ImageUp },
14+
];
15+
16+
return (
17+
<nav className="sticky top-0 z-50 w-full border-b border-slate-200 dark:border-neutral-700 bg-white/95 dark:bg-neutral-900/95 backdrop-blur-sm">
18+
<div className="flex h-16 items-center px-4 sm:px-6">
19+
<div className="flex-shrink-0">
20+
<Link
21+
href="/"
22+
className="text-lg font-bold text-slate-800 dark:text-neutral-100"
23+
>
24+
SVG{" "}
25+
<span className="text-emerald-600 dark:text-violet-500">
26+
From Img
27+
</span>
28+
</Link>
29+
</div>
30+
31+
<div className="hidden md:flex items-center justify-center flex-1">
32+
<div className="flex space-x-1">
33+
{links.map((link) => (
34+
<Link
35+
key={link.href}
36+
href={link.href}
37+
className={`flex h-10 items-center px-3 py-2 text-sm font-medium rounded-md
38+
${
39+
pathname === link.href
40+
? "bg-emerald-100 text-emerald-700 dark:bg-violet-700/30 dark:text-violet-300"
41+
: "text-slate-500 hover:text-emerald-600 hover:bg-emerald-50 dark:text-neutral-400 dark:hover:text-violet-400 dark:hover:bg-violet-700/20"
42+
}`}
43+
>
44+
{link.name}
45+
</Link>
46+
))}
47+
</div>
48+
</div>
49+
50+
<div className="flex items-center space-x-2 ml-auto">
51+
<ThemeToggle />
52+
</div>
53+
</div>
54+
</nav>
55+
);
56+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
"use client";
2+
3+
import * as React from "react";
4+
import { ThemeProvider as NextThemesProvider } from "next-themes";
5+
6+
export function ThemeProvider({
7+
children,
8+
...props
9+
}: React.ComponentProps<typeof NextThemesProvider>) {
10+
return <NextThemesProvider {...props}>{children}</NextThemesProvider>;
11+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
"use client";
2+
3+
import { Moon, Sun } from "lucide-react";
4+
import { useTheme } from "next-themes";
5+
import { useEffect } from "react";
6+
7+
export default function ThemeToggle() {
8+
const { theme, setTheme } = useTheme();
9+
10+
useEffect(() => {
11+
const handleKeyPress = (e: KeyboardEvent) => {
12+
if ((e.ctrlKey || e.metaKey) && e.key === "k") {
13+
e.preventDefault();
14+
setTheme(theme === "dark" ? "light" : "dark");
15+
}
16+
};
17+
18+
window.addEventListener("keydown", handleKeyPress);
19+
return () => window.removeEventListener("keydown", handleKeyPress);
20+
}, [theme, setTheme]);
21+
22+
return (
23+
<button
24+
onClick={() => setTheme(theme === "dark" ? "light" : "dark")}
25+
className="shadow-sm cursor-pointer p-2 rounded-full border border-emerald-500 dark:border-purple-500 transition-all duration-300 ease-in-out hover:bg-emerald-100 dark:hover:bg-violet-700/30"
26+
title="Toggle theme (Ctrl+K)"
27+
>
28+
{theme === "dark" ? (
29+
<Sun className="h-5 w-5 text-emerald-600 dark:text-violet-500 ease-in-out" />
30+
) : (
31+
<Moon className="h-5 w-5 text-emerald-600 dark:text-violet-500 ease-in-out" />
32+
)}
33+
</button>
34+
);
35+
}

package-lock.json

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

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
"imagetracerjs": "^1.2.6",
1818
"lucide-react": "^0.544.0",
1919
"next": "15.5.4",
20+
"next-themes": "^0.4.6",
2021
"node-fetch": "^3.3.2",
2122
"pngjs": "^7.0.0",
2223
"react": "19.1.0",

0 commit comments

Comments
 (0)