Basic dark mode implemented
Some checks failed
Deploy Volleyball Dev / deploy (push) Has been cancelled
Some checks failed
Deploy Volleyball Dev / deploy (push) Has been cancelled
This commit is contained in:
parent
50253f20fb
commit
f35bae79bf
@ -3,7 +3,7 @@ import { Button } from "@/components/ui/button";
|
||||
import { Menu, X, Volleyball, ChevronDown, Users } from "lucide-react";
|
||||
import { Link, useNavigate } from "react-router-dom";
|
||||
import { useAuth } from '@/context/AuthContext';
|
||||
import axios from 'axios';
|
||||
import ThemeToggle from './ThemeToggle';
|
||||
|
||||
|
||||
type Team = {
|
||||
@ -93,6 +93,10 @@ const Navbar = () => {
|
||||
</Button>
|
||||
</Link>
|
||||
|
||||
<ThemeToggle />
|
||||
|
||||
{/* Account Menu */}
|
||||
|
||||
<div
|
||||
className="relative ml-4"
|
||||
onMouseEnter={() => {
|
||||
|
||||
22
src/components/ThemeToggle.tsx
Normal file
22
src/components/ThemeToggle.tsx
Normal file
@ -0,0 +1,22 @@
|
||||
import { useTheme } from "@/context/ThemeContext";
|
||||
import { Sun, Moon } from "lucide-react";
|
||||
|
||||
const ThemeToggle = () => {
|
||||
const { theme, toggleTheme } = useTheme();
|
||||
|
||||
return (
|
||||
<button
|
||||
onClick={toggleTheme}
|
||||
className="p-2 rounded-full bg-white dark:bg-gray-800 shadow-md hover:scale-105 transition flex items-center justify-center"
|
||||
aria-label="Toggle Theme"
|
||||
>
|
||||
{theme === "dark" ? (
|
||||
<Sun className="h-5 w-5 text-yellow-400" />
|
||||
) : (
|
||||
<Moon className="h-5 w-5 text-gray-600" />
|
||||
)}
|
||||
</button>
|
||||
);
|
||||
};
|
||||
|
||||
export default ThemeToggle;
|
||||
40
src/context/ThemeContext.tsx
Normal file
40
src/context/ThemeContext.tsx
Normal file
@ -0,0 +1,40 @@
|
||||
import { createContext, useContext, useEffect, useState } from "react";
|
||||
|
||||
type Theme = "light" | "dark";
|
||||
|
||||
interface ThemeContextType {
|
||||
theme: Theme;
|
||||
toggleTheme: () => void;
|
||||
}
|
||||
|
||||
const ThemeContext = createContext<ThemeContextType>({
|
||||
theme: "light",
|
||||
toggleTheme: () => {},
|
||||
});
|
||||
|
||||
export const ThemeProvider = ({ children }: { children: React.ReactNode }) => {
|
||||
const [theme, setTheme] = useState<Theme>("light");
|
||||
|
||||
useEffect(() => {
|
||||
const stored = localStorage.getItem("theme") as Theme | null;
|
||||
const system = window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
|
||||
const initial = stored || system;
|
||||
setTheme(initial);
|
||||
document.documentElement.classList.toggle("dark", initial === "dark");
|
||||
}, []);
|
||||
|
||||
const toggleTheme = () => {
|
||||
const newTheme = theme === "dark" ? "light" : "dark";
|
||||
setTheme(newTheme);
|
||||
localStorage.setItem("theme", newTheme);
|
||||
document.documentElement.classList.toggle("dark", newTheme === "dark");
|
||||
};
|
||||
|
||||
return (
|
||||
<ThemeContext.Provider value={{ theme, toggleTheme }}>
|
||||
{children}
|
||||
</ThemeContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
export const useTheme = () => useContext(ThemeContext);
|
||||
@ -1,12 +1,23 @@
|
||||
import { ReactNode, useEffect } from "react";
|
||||
import Navbar from "@/components/Navbar";
|
||||
import Footer from "@/components/Footer";
|
||||
import { ReactNode } from "react";
|
||||
import AOS from "aos";
|
||||
import "aos/dist/aos.css";
|
||||
|
||||
type LayoutProps = {
|
||||
children: ReactNode;
|
||||
};
|
||||
|
||||
const Layout = ({ children }: LayoutProps) => {
|
||||
useEffect(() => {
|
||||
AOS.init({
|
||||
duration: 800, // Dauer der Animationen
|
||||
once: true, // nur einmal pro Element
|
||||
offset: 100, // wie weit gescrollt werden muss
|
||||
easing: "ease-out-cubic",
|
||||
});
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-white flex flex-col">
|
||||
<Navbar />
|
||||
|
||||
@ -33,10 +33,13 @@ import Impressum from "./pages/Impressum";
|
||||
import Satzung from "./pages/Satzung";
|
||||
import Beitraege from "./pages/Beitraege";
|
||||
|
||||
import { ThemeProvider } from "@/context/ThemeContext";
|
||||
|
||||
|
||||
|
||||
ReactDOM.createRoot(document.getElementById("root")!).render(
|
||||
<React.StrictMode>
|
||||
<ThemeProvider>
|
||||
<BrowserRouter>
|
||||
<AuthProvider>
|
||||
<Routes>
|
||||
@ -89,5 +92,6 @@ ReactDOM.createRoot(document.getElementById("root")!).render(
|
||||
</Routes>
|
||||
</AuthProvider>
|
||||
</BrowserRouter>
|
||||
</ThemeProvider>
|
||||
</React.StrictMode>
|
||||
);
|
||||
Loading…
Reference in New Issue
Block a user