diff --git a/app/layout.tsx b/app/layout.tsx
index f7fa87e..74575cd 100644
--- a/app/layout.tsx
+++ b/app/layout.tsx
@@ -1,33 +1,31 @@
-import type { Metadata } from "next";
-import { Geist, Geist_Mono } from "next/font/google";
+import Navbar from "@/components/NavbarComponents/Navbar";
+import { ThemeProvider } from "@/components/NavbarComponents/ThemeProvider";
+import { Space_Grotesk } from "next/font/google";
import "./globals.css";
-const geistSans = Geist({
- variable: "--font-geist-sans",
+const spaceGrotesk = Space_Grotesk({
+ variable: "--font-space-grotesk",
subsets: ["latin"],
+ weight: ["300", "400", "500", "600", "700"],
});
-const geistMono = Geist_Mono({
- variable: "--font-geist-mono",
- subsets: ["latin"],
-});
-
-export const metadata: Metadata = {
- title: "Create Next App",
- description: "Generated by create next app",
-};
-
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
-
-
- {children}
+
+
+
+
+ {children}
+
);
diff --git a/components/NavbarComponents/Navbar.tsx b/components/NavbarComponents/Navbar.tsx
new file mode 100644
index 0000000..56dd27d
--- /dev/null
+++ b/components/NavbarComponents/Navbar.tsx
@@ -0,0 +1,56 @@
+"use client";
+
+import { Home, ImageUp } from "lucide-react";
+import Link from "next/link";
+import { usePathname } from "next/navigation";
+import ThemeToggle from "./ThemeToggle";
+
+export default function Navbar() {
+ const pathname = usePathname();
+
+ const links = [
+ { name: "Home", href: "/", icon: Home },
+ { name: "Generate", href: "/generate", icon: ImageUp },
+ ];
+
+ return (
+
+ );
+}
diff --git a/components/NavbarComponents/ThemeProvider.tsx b/components/NavbarComponents/ThemeProvider.tsx
new file mode 100644
index 0000000..189a2b1
--- /dev/null
+++ b/components/NavbarComponents/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/NavbarComponents/ThemeToggle.tsx b/components/NavbarComponents/ThemeToggle.tsx
new file mode 100644
index 0000000..eaf48b3
--- /dev/null
+++ b/components/NavbarComponents/ThemeToggle.tsx
@@ -0,0 +1,35 @@
+"use client";
+
+import { Moon, Sun } from "lucide-react";
+import { useTheme } from "next-themes";
+import { useEffect } from "react";
+
+export default function ThemeToggle() {
+ const { theme, setTheme } = useTheme();
+
+ useEffect(() => {
+ const handleKeyPress = (e: KeyboardEvent) => {
+ if ((e.ctrlKey || e.metaKey) && e.key === "k") {
+ e.preventDefault();
+ setTheme(theme === "dark" ? "light" : "dark");
+ }
+ };
+
+ window.addEventListener("keydown", handleKeyPress);
+ return () => window.removeEventListener("keydown", handleKeyPress);
+ }, [theme, setTheme]);
+
+ return (
+
+ );
+}
diff --git a/package-lock.json b/package-lock.json
index a4c0d1d..1134d6c 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -11,10 +11,10 @@
"class-variance-authority": "^0.7.1",
"cloudinary": "^2.7.0",
"clsx": "^2.1.1",
- "formidable": "^3.5.4",
"imagetracerjs": "^1.2.6",
"lucide-react": "^0.544.0",
"next": "15.5.4",
+ "next-themes": "^0.4.6",
"node-fetch": "^3.3.2",
"pngjs": "^7.0.0",
"react": "19.1.0",
@@ -922,18 +922,6 @@
"node": ">= 10"
}
},
- "node_modules/@noble/hashes": {
- "version": "1.8.0",
- "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz",
- "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==",
- "license": "MIT",
- "engines": {
- "node": "^14.21.3 || >=16"
- },
- "funding": {
- "url": "https://paulmillr.com/funding/"
- }
- },
"node_modules/@nodelib/fs.scandir": {
"version": "2.1.5",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
@@ -982,15 +970,6 @@
"node": ">=12.4.0"
}
},
- "node_modules/@paralleldrive/cuid2": {
- "version": "2.2.2",
- "resolved": "https://registry.npmjs.org/@paralleldrive/cuid2/-/cuid2-2.2.2.tgz",
- "integrity": "sha512-ZOBkgDwEdoYVlSeRbYYXs0S9MejQofiVYoTbKzy/6GQa39/q5tQU2IX46+shYnUkpEl3wc+J6wRlar7r2EK2xA==",
- "license": "MIT",
- "dependencies": {
- "@noble/hashes": "^1.1.5"
- }
- },
"node_modules/@rtsao/scc": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz",
@@ -2152,12 +2131,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/asap": {
- "version": "2.0.6",
- "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
- "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==",
- "license": "MIT"
- },
"node_modules/ast-types-flow": {
"version": "0.0.8",
"resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.8.tgz",
@@ -2579,16 +2552,6 @@
"node": ">=8"
}
},
- "node_modules/dezalgo": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.4.tgz",
- "integrity": "sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==",
- "license": "ISC",
- "dependencies": {
- "asap": "^2.0.0",
- "wrappy": "1"
- }
- },
"node_modules/doctrine": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz",
@@ -3430,23 +3393,6 @@
"node": ">=12.20.0"
}
},
- "node_modules/formidable": {
- "version": "3.5.4",
- "resolved": "https://registry.npmjs.org/formidable/-/formidable-3.5.4.tgz",
- "integrity": "sha512-YikH+7CUTOtP44ZTnUhR7Ic2UASBPOqmaRkRKxRbywPTe5VxF7RRCck4af9wutiZ/QKM5nME9Bie2fFaPz5Gug==",
- "license": "MIT",
- "dependencies": {
- "@paralleldrive/cuid2": "^2.2.2",
- "dezalgo": "^1.0.4",
- "once": "^1.4.0"
- },
- "engines": {
- "node": ">=14.0.0"
- },
- "funding": {
- "url": "https://ko-fi.com/tunnckoCore/commissions"
- }
- },
"node_modules/function-bind": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
@@ -4817,6 +4763,16 @@
}
}
},
+ "node_modules/next-themes": {
+ "version": "0.4.6",
+ "resolved": "https://registry.npmjs.org/next-themes/-/next-themes-0.4.6.tgz",
+ "integrity": "sha512-pZvgD5L0IEvX5/9GWyHMf3m8BKiVQwsCMHfoFosXtXBMnaS0ZnIJ9ST4b4NqLVKDEm8QBxoNNGNaBv2JNF6XNA==",
+ "license": "MIT",
+ "peerDependencies": {
+ "react": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc"
+ }
+ },
"node_modules/next/node_modules/postcss": {
"version": "8.4.31",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz",
@@ -5006,15 +4962,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/once": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
- "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
- "license": "ISC",
- "dependencies": {
- "wrappy": "1"
- }
- },
"node_modules/optionator": {
"version": "0.9.4",
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz",
@@ -6333,12 +6280,6 @@
"node": ">=0.10.0"
}
},
- "node_modules/wrappy": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
- "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
- "license": "ISC"
- },
"node_modules/yallist": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz",
diff --git a/package.json b/package.json
index a22808b..449774b 100644
--- a/package.json
+++ b/package.json
@@ -17,6 +17,7 @@
"imagetracerjs": "^1.2.6",
"lucide-react": "^0.544.0",
"next": "15.5.4",
+ "next-themes": "^0.4.6",
"node-fetch": "^3.3.2",
"pngjs": "^7.0.0",
"react": "19.1.0",