diff --git a/package-lock.json b/package-lock.json index fa6ef09..a8d255e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -41,6 +41,7 @@ "react-responsive-carousel": "^3.2.23", "sparkpost": "^2.1.4", "swr": "^2.1.2", + "theme-change": "^2.5.0", "zod": "^3.21.4" }, "devDependencies": { @@ -9643,6 +9644,11 @@ "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, + "node_modules/theme-change": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/theme-change/-/theme-change-2.5.0.tgz", + "integrity": "sha512-B/UdsgdHAGhSKHTAQnxg/etN0RaMDpehuJmZIjLMDVJ6DGIliRHGD6pODi1CXLQAN9GV0GSyB3G6yCuK05PkPQ==" + }, "node_modules/thenify": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", @@ -10213,9 +10219,9 @@ } }, "node_modules/vm2": { - "version": "3.9.16", - "resolved": "https://registry.npmjs.org/vm2/-/vm2-3.9.16.tgz", - "integrity": "sha512-3T9LscojNTxdOyG+e8gFeyBXkMlOBYDoF6dqZbj+MPVHi9x10UfiTAJIobuchRCp3QvC+inybTbMJIUrLsig0w==", + "version": "3.9.17", + "resolved": "https://registry.npmjs.org/vm2/-/vm2-3.9.17.tgz", + "integrity": "sha512-AqwtCnZ/ERcX+AVj9vUsphY56YANXxRuqMb7GsDtAr0m0PcQX3u0Aj3KWiXM0YAHy7i6JEeHrwOnwXbGYgRpAw==", "optional": true, "dependencies": { "acorn": "^8.7.0", @@ -17148,6 +17154,11 @@ "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, + "theme-change": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/theme-change/-/theme-change-2.5.0.tgz", + "integrity": "sha512-B/UdsgdHAGhSKHTAQnxg/etN0RaMDpehuJmZIjLMDVJ6DGIliRHGD6pODi1CXLQAN9GV0GSyB3G6yCuK05PkPQ==" + }, "thenify": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", @@ -17582,9 +17593,9 @@ } }, "vm2": { - "version": "3.9.16", - "resolved": "https://registry.npmjs.org/vm2/-/vm2-3.9.16.tgz", - "integrity": "sha512-3T9LscojNTxdOyG+e8gFeyBXkMlOBYDoF6dqZbj+MPVHi9x10UfiTAJIobuchRCp3QvC+inybTbMJIUrLsig0w==", + "version": "3.9.17", + "resolved": "https://registry.npmjs.org/vm2/-/vm2-3.9.17.tgz", + "integrity": "sha512-AqwtCnZ/ERcX+AVj9vUsphY56YANXxRuqMb7GsDtAr0m0PcQX3u0Aj3KWiXM0YAHy7i6JEeHrwOnwXbGYgRpAw==", "optional": true, "requires": { "acorn": "^8.7.0", diff --git a/package.json b/package.json index 2282de2..3386faa 100644 --- a/package.json +++ b/package.json @@ -44,6 +44,7 @@ "react-responsive-carousel": "^3.2.23", "sparkpost": "^2.1.4", "swr": "^2.1.2", + "theme-change": "^2.5.0", "zod": "^3.21.4" }, "devDependencies": { @@ -77,7 +78,7 @@ "tailwindcss-animate": "^1.0.5", "ts-node": "^10.9.1", "typescript": "^5.0.3" - }, + }, "prisma": { "schema": "./src/prisma/schema.prisma" } diff --git a/src/components/ui/Navbar.tsx b/src/components/ui/Navbar.tsx index 2f63e03..0b7bcd3 100644 --- a/src/components/ui/Navbar.tsx +++ b/src/components/ui/Navbar.tsx @@ -1,8 +1,8 @@ import useMediaQuery from '@/hooks/useMediaQuery'; import useNavbar from '@/hooks/useNavbar'; import Link from 'next/link'; -import { FC } from 'react'; - +import { FC, useEffect, useState } from 'react'; +import { MdDarkMode, MdLightMode } from 'react-icons/md'; import { GiHamburgerMenu } from 'react-icons/gi'; const DesktopLinks: FC = () => { @@ -56,9 +56,29 @@ const MobileLinks: FC = () => { ); }; +const useTheme = () => { + const [theme, setTheme] = useState<'light' | 'dark'>('light'); + + const prefersDarkMode = useMediaQuery('(prefers-color-scheme: dark)'); + + useEffect(() => { + const savedTheme = localStorage.getItem('theme'); + if (prefersDarkMode && !savedTheme) { + setTheme('dark'); + localStorage.setItem('theme', 'dark'); + return; + } + setTheme(savedTheme as 'light' | 'dark'); + }, [prefersDarkMode, theme]); + + return { theme, setTheme }; +}; + const Navbar = () => { const isDesktopView = useMediaQuery('(min-width: 1024px)'); + const { theme, setTheme } = useTheme(); + return ( ); }; diff --git a/src/styles/globals.css b/src/styles/globals.css index 4ccbf08..b02a8f5 100644 --- a/src/styles/globals.css +++ b/src/styles/globals.css @@ -3,5 +3,5 @@ @tailwind utilities; .card { - @apply shadow-md card-compact bg-base-300 -} \ No newline at end of file + @apply card-compact bg-base-300; +} diff --git a/tailwind.config.js b/tailwind.config.js index 0d20479..7822c55 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -1,7 +1,7 @@ //themes -const darkTheme = { - default: { +const myThemes = { + dark: { primary: 'hsl(227, 23%, 20%)', secondary: 'hsl(255, 9%, 69%)', error: 'hsl(9, 52%, 57%)', @@ -12,14 +12,11 @@ const darkTheme = { warning: 'hsl(50, 98%, 50%)', 'primary-content': 'hsl(0, 0%, 98%)', 'error-content': 'hsl(0, 0%, 98%)', - 'base-100': 'hsl(190, 4%, 11%)', - 'base-200': 'hsl(190, 4%, 8%)', - 'base-300': 'hsl(190, 4%, 5%)', + 'base-100': 'hsl(227, 20%, 11%)', + 'base-200': 'hsl(227, 20%, 8%)', + 'base-300': 'hsl(227, 20%, 5%)', }, -}; - -const pastelTheme = { - default: { + light: { primary: 'hsl(180, 15%, 60%)', secondary: 'hsl(21, 54%, 83%)', error: 'hsl(4, 87%, 74%)', @@ -30,9 +27,9 @@ const pastelTheme = { warning: 'hsl(40, 76%, 73%)', 'primary-content': 'hsl(0, 0%, 0%)', 'error-content': 'hsl(0, 0%, 0%)', - 'base-100': 'hsl(0, 0%, 94%)', - 'base-200': 'hsl(0, 0%, 90%)', - 'base-300': 'hsl(0, 0%, 85%)', + 'base-100': 'hsl(180, 8%, 94%)', + 'base-200': 'hsl(180, 8%, 92%)', + 'base-300': 'hsl(180, 8%, 88%)', }, }; @@ -50,10 +47,11 @@ module.exports = { require('@headlessui/tailwindcss'), require('daisyui'), require('tailwindcss-animate'), + require('autoprefixer'), ], daisyui: { logs: false, - themes: [darkTheme, pastelTheme], + themes: [myThemes], }, };