Initial Release
This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
|
||||
import React, { createContext, useContext, useState, ReactNode } from "react";
|
||||
import { translations, Language, TranslationKey } from "@/translations";
|
||||
|
||||
type LanguageContextType = {
|
||||
language: Language;
|
||||
setLanguage: (language: Language) => void;
|
||||
t: (key: string) => string;
|
||||
};
|
||||
|
||||
const LanguageContext = createContext<LanguageContextType>({
|
||||
language: "en",
|
||||
setLanguage: () => {},
|
||||
t: () => "",
|
||||
});
|
||||
|
||||
export const useLanguage = () => useContext(LanguageContext);
|
||||
|
||||
export const LanguageProvider = ({ children }: { children: ReactNode }) => {
|
||||
const [language, setLanguage] = useState<Language>("en");
|
||||
|
||||
const t = (key: string) => {
|
||||
return translations[language][key as TranslationKey] || key;
|
||||
};
|
||||
|
||||
return (
|
||||
<LanguageContext.Provider value={{ language, setLanguage, t }}>
|
||||
{children}
|
||||
</LanguageContext.Provider>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,77 @@
|
||||
|
||||
import React, { createContext, useContext, useEffect, useState } from "react";
|
||||
|
||||
type Theme = "dark" | "light";
|
||||
|
||||
interface ThemeContextType {
|
||||
theme: Theme;
|
||||
toggleTheme: () => void;
|
||||
}
|
||||
|
||||
const ThemeContext = createContext<ThemeContextType>({
|
||||
theme: "dark",
|
||||
toggleTheme: () => {},
|
||||
});
|
||||
|
||||
export const ThemeProvider = ({ children }: { children: React.ReactNode }) => {
|
||||
// Initialize theme from localStorage or default to system preference
|
||||
const [theme, setTheme] = useState<Theme>(() => {
|
||||
const savedTheme = localStorage.getItem("theme") as Theme;
|
||||
|
||||
if (savedTheme) {
|
||||
return savedTheme;
|
||||
}
|
||||
|
||||
// Check for system preference
|
||||
if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
|
||||
return "dark";
|
||||
}
|
||||
|
||||
return "light";
|
||||
});
|
||||
|
||||
// Update theme class on document when theme changes
|
||||
useEffect(() => {
|
||||
const root = window.document.documentElement;
|
||||
|
||||
if (theme === "dark") {
|
||||
root.classList.add("dark");
|
||||
root.classList.remove("light");
|
||||
} else {
|
||||
root.classList.add("light");
|
||||
root.classList.remove("dark");
|
||||
}
|
||||
|
||||
// Save theme preference to localStorage
|
||||
localStorage.setItem("theme", theme);
|
||||
}, [theme]);
|
||||
|
||||
// Listen for system theme changes
|
||||
useEffect(() => {
|
||||
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
|
||||
|
||||
const handleChange = (e: MediaQueryListEvent) => {
|
||||
if (!localStorage.getItem("theme")) {
|
||||
setTheme(e.matches ? "dark" : "light");
|
||||
}
|
||||
};
|
||||
|
||||
mediaQuery.addEventListener('change', handleChange);
|
||||
|
||||
return () => {
|
||||
mediaQuery.removeEventListener('change', handleChange);
|
||||
};
|
||||
}, []);
|
||||
|
||||
const toggleTheme = () => {
|
||||
setTheme(prevTheme => prevTheme === "dark" ? "light" : "dark");
|
||||
};
|
||||
|
||||
return (
|
||||
<ThemeContext.Provider value={{ theme, toggleTheme }}>
|
||||
{children}
|
||||
</ThemeContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
export const useTheme = () => useContext(ThemeContext);
|
||||
Reference in New Issue
Block a user