diff --git a/.github/workflows/ci-cd-pipeline.yml b/.github/workflows/ci-cd-pipeline.yml index cbb38ba..ccd7f24 100644 --- a/.github/workflows/ci-cd-pipeline.yml +++ b/.github/workflows/ci-cd-pipeline.yml @@ -321,6 +321,9 @@ jobs: node-version: ${{ env.NODE_VERSION }} cache: 'npm' + - name: Install dependencies + run: npm ci --prefer-offline + - name: Install Vercel CLI run: npm install --global vercel@latest diff --git a/app/globals.css b/app/globals.css index be6abd4..8fc4d04 100644 --- a/app/globals.css +++ b/app/globals.css @@ -2,20 +2,6 @@ @tailwind components; @tailwind utilities; -:root { - --foreground-rgb: 0, 0, 0; - --background-start-rgb: 214, 219, 220; - --background-end-rgb: 255, 255, 255; -} - -@media (prefers-color-scheme: dark) { - :root { - --foreground-rgb: 255, 255, 255; - --background-start-rgb: 0, 0, 0; - --background-end-rgb: 0, 0, 0; - } -} - @layer base { :root { --background: 0 0% 100%; @@ -44,6 +30,7 @@ --chart-5: 27 87% 67%; --radius: 0.5rem; } + .dark { --background: 0 0% 3.9%; --foreground: 0 0% 98%; @@ -108,7 +95,7 @@ } .prose pre { - background-color: rgb(var(--muted)); + background-color: hsl(var(--muted)); padding: 1rem; border-radius: 0.5rem; } @@ -120,12 +107,12 @@ .prose th, .prose td { - border: 1px solid rgb(var(--border)); + border: 1px solid hsl(var(--border)); padding: 0.5rem; } .prose blockquote { - border-left: 4px solid rgb(var(--primary)); + border-left: 4px solid hsl(var(--primary)); padding-left: 1rem; font-style: italic; } diff --git a/app/layout.tsx b/app/layout.tsx index 8ac0352..20d2ff3 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -3,6 +3,7 @@ import type { Metadata } from "next"; import { Inter } from "next/font/google"; import { SiteHeader } from "@/components/site-header"; import { SiteFooter } from "@/components/site-footer"; +import { ThemeProvider } from "next-themes"; const inter = Inter({ subsets: ["latin"] }); @@ -18,13 +19,21 @@ export default function RootLayout({ children: React.ReactNode; }) { return ( - + -
- -
{children}
- -
+ +
+ +
{children}
+ +
+
); diff --git a/app/page.tsx b/app/page.tsx index 501fe63..a67f9fb 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -75,7 +75,7 @@ export default function Home() { - + diff --git a/components/site-footer.tsx b/components/site-footer.tsx index 002e46a..81c9464 100644 --- a/components/site-footer.tsx +++ b/components/site-footer.tsx @@ -13,7 +13,7 @@ export function SiteFooter() { . The source code is available on{" "} @@ -23,7 +23,7 @@ export function SiteFooter() {

- + diff --git a/components/site-header.tsx b/components/site-header.tsx index 7650900..42018fa 100644 --- a/components/site-header.tsx +++ b/components/site-header.tsx @@ -5,6 +5,7 @@ import { usePathname } from "next/navigation"; import { cn } from "@/lib/utils"; import { Button } from "@/components/ui/button"; import { Wrench, Github } from "lucide-react"; +import { ThemeToggle } from "./theme-toggle"; const navigation = [ { name: "Home", href: "/" }, @@ -40,8 +41,9 @@ export function SiteHeader() {
+ diff --git a/components/theme-toggle.tsx b/components/theme-toggle.tsx new file mode 100644 index 0000000..378b162 --- /dev/null +++ b/components/theme-toggle.tsx @@ -0,0 +1,30 @@ +"use client"; + +import * as React from "react"; +import { Moon, Sun } from "lucide-react"; +import { useTheme } from "next-themes"; + +export function ThemeToggle() { + const [mounted, setMounted] = React.useState(false); + const { resolvedTheme, setTheme } = useTheme(); // Changed: use resolvedTheme + + React.useEffect(() => { + setMounted(true); + }, []); + + if (!mounted) { + return null; + } + + return ( + + ); +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 044ad32..f5835d6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -55,7 +55,6 @@ "eslint": "8.49.0", "eslint-config-next": "13.5.1", "input-otp": "^1.2.4", - "lru-cache": "^10.0.0", "lucide-react": "^0.446.0", "mongodb": "^6.18.0", "mongoose": "^8.17.0", @@ -81,9 +80,6 @@ }, "devDependencies": { "@types/jest": "^29.5.0", - "@types/node": "^20.0.0", - "@types/react": "^18.2.22", - "@types/react-dom": "^18.2.7", "jest": "^29.5.0", "jest-environment-node": "^29.5.0" } @@ -3170,8 +3166,7 @@ "node_modules/@types/node": { "version": "20.6.2", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.6.2.tgz", - "integrity": "sha512-Y+/1vGBHV/cYk6OI1Na/LHzwnlNCAfU3ZNGrc1LdRe/LAIbdDPTTv/HU3M7yXN448aTVDq3eKRm2cg7iKLb8gw==", - "dev": true + "integrity": "sha512-Y+/1vGBHV/cYk6OI1Na/LHzwnlNCAfU3ZNGrc1LdRe/LAIbdDPTTv/HU3M7yXN448aTVDq3eKRm2cg7iKLb8gw==" }, "node_modules/@types/prop-types": { "version": "15.7.13", @@ -3192,7 +3187,6 @@ "version": "18.2.7", "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.7.tgz", "integrity": "sha512-GRaAEriuT4zp9N4p1i8BDBYmEyfo+xQ3yHjJU4eiK5NDa1RmUZG+unZABUTK4/Ox/M+GaHwb6Ow8rUITrtjszA==", - "devOptional": true, "dependencies": { "@types/react": "*" } @@ -8075,6 +8069,7 @@ "version": "0.446.0", "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.446.0.tgz", "integrity": "sha512-BU7gy8MfBMqvEdDPH79VhOXSEgyG8TSPOKWaExWGCQVqnGH7wGgDngPbofu+KdtVjPQBWbEmnfMTq90CTiiDRg==", + "license": "ISC", "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0-rc" } @@ -9177,6 +9172,7 @@ "version": "0.3.0", "resolved": "https://registry.npmjs.org/next-themes/-/next-themes-0.3.0.tgz", "integrity": "sha512-/QHIrsYpd6Kfk7xakK4svpDI5mmXP0gfvCoJdGpZQ2TOrQZmsW0QxjaiLn8wbIKjtm4BTSqLoix4lxYYOnLJ/w==", + "license": "MIT", "peerDependencies": { "react": "^16.8 || ^17 || ^18", "react-dom": "^16.8 || ^17 || ^18" @@ -10589,9 +10585,10 @@ } }, "node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "license": "ISC", "bin": { "semver": "bin/semver.js" }, @@ -11330,9 +11327,10 @@ } }, "node_modules/tslib": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", - "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==" + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" }, "node_modules/type-check": { "version": "0.4.0", diff --git a/package.json b/package.json index 21e34ed..d49afa8 100644 --- a/package.json +++ b/package.json @@ -48,6 +48,8 @@ "@types/node": "20.6.2", "@types/react": "18.2.22", "@types/react-dom": "18.2.7", + "@upstash/ratelimit": "^1.0.0", + "@upstash/redis": "^1.25.1", "autoprefixer": "10.4.15", "class-variance-authority": "^0.7.0", "clsx": "^2.1.1", @@ -78,9 +80,7 @@ "tailwindcss-animate": "^1.0.7", "typescript": "5.2.2", "vaul": "^0.9.9", - "zod": "^3.23.8", - "@upstash/ratelimit": "^1.0.0", - "@upstash/redis": "^1.25.1" + "zod": "^3.23.8" }, "devDependencies": { "@types/jest": "^29.5.0",