diff --git a/src/components/Navbar.jsx b/src/components/Navbar.jsx index 8ef775d0..dc5a6eab 100644 --- a/src/components/Navbar.jsx +++ b/src/components/Navbar.jsx @@ -1,23 +1,27 @@ import { useState } from "react"; import { Link } from "react-router-dom"; -import logo from "../assets/logo_light_160.png"; +import logo_light from "../assets/logo_light_160.png"; +import logo_dark from "../assets/logo_dark_160.png"; import { SideSheet } from "@douyinfe/semi-ui"; import { IconMenu } from "@douyinfe/semi-icons"; import { socials } from "../data/socials"; +import ThemeToggle from "./ThemeToggle"; +import { useTheme } from "../context/ThemeContext"; export default function Navbar() { const [openMenu, setOpenMenu] = useState(false); + const { theme } = useTheme(); return ( <> -
+
- logo + logo
document .getElementById("features") @@ -28,24 +32,25 @@ export default function Navbar() { Editor Templates Docs
-
+
+ + logo } visible={openMenu} onCancel={() => setOpenMenu(false)} width={window.innerWidth} > +
+ Theme + +
+
{ document .getElementById("features") @@ -105,21 +115,21 @@ export default function Navbar() {
Editor
Templates
Docs diff --git a/src/components/ThemeToggle.jsx b/src/components/ThemeToggle.jsx new file mode 100644 index 00000000..132bd314 --- /dev/null +++ b/src/components/ThemeToggle.jsx @@ -0,0 +1,23 @@ +import { useTheme } from "../context/ThemeContext"; + +export default function ThemeToggle() { + const { theme, toggleTheme } = useTheme(); + + return ( + + ); +} \ No newline at end of file diff --git a/src/context/ThemeContext.jsx b/src/context/ThemeContext.jsx new file mode 100644 index 00000000..dec8f56c --- /dev/null +++ b/src/context/ThemeContext.jsx @@ -0,0 +1,37 @@ +import { createContext, useContext, useEffect, useState } from "react"; + +const ThemeContext = createContext(); + +export const useTheme = () => { + const context = useContext(ThemeContext); + if (!context) { + throw new Error("useTheme must be used within a ThemeProvider"); + } + return context; +}; + +export const ThemeProvider = ({ children }) => { + const [theme, setTheme] = useState("light"); + + useEffect(() => { + const savedTheme = localStorage.getItem("theme"); + const systemTheme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light"; + const initialTheme = savedTheme || systemTheme; + + setTheme(initialTheme); + document.documentElement.classList.toggle("dark", initialTheme === "dark"); + }, []); + + const toggleTheme = () => { + const newTheme = theme === "light" ? "dark" : "light"; + setTheme(newTheme); + localStorage.setItem("theme", newTheme); + document.documentElement.classList.toggle("dark", newTheme === "dark"); + }; + + return ( + + {children} + + ); +}; \ No newline at end of file diff --git a/src/index.css b/src/index.css index 44dabcd0..314778a6 100644 --- a/src/index.css +++ b/src/index.css @@ -162,6 +162,11 @@ background-size: 20px 20px; } +.dark .bg-dots { + background-color: rgb(31, 41, 55); + background-image: radial-gradient(rgb(118, 118, 209) 1px, rgb(31, 41, 55) 1px); +} + .sliding-vertical span { animation: top-to-bottom 9s linear infinite 0s; -ms-animation: top-to-bottom 9s linear infinite 0s; diff --git a/src/pages/LandingPage.jsx b/src/pages/LandingPage.jsx index 2638d733..aba9ec0e 100644 --- a/src/pages/LandingPage.jsx +++ b/src/pages/LandingPage.jsx @@ -18,6 +18,7 @@ import axios from "axios"; import { languages } from "../i18n/i18n"; import { Tweet } from "react-tweet"; import { socials } from "../data/socials"; +import { ThemeProvider } from "../context/ThemeContext"; function shortenNumber(number) { if (number < 1000) return number; @@ -36,7 +37,6 @@ export default function LandingPage() { .then((res) => setStats(res.data)); }; - document.body.setAttribute("theme-mode", "light"); document.title = "drawDB | Online database diagram editor and SQL generator"; @@ -44,8 +44,9 @@ export default function LandingPage() { }, []); return ( -
-
+ +
+
@@ -53,27 +54,27 @@ export default function LandingPage() { {/* Hero section */} -
+
-
+
-

+

Draw, Copy, and Paste

-
+
Free and open source, simple, and intuitive database design editor, data-modeler, and SQL generator.{" "} - + No sign up - + Free of charge - + Quick and easy
@@ -81,7 +82,7 @@ export default function LandingPage() {