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",