diff options
| author | srdusr <trevorgray@srdusr.com> | 2025-09-26 13:39:28 +0200 |
|---|---|---|
| committer | srdusr <trevorgray@srdusr.com> | 2025-09-26 13:39:28 +0200 |
| commit | 8d60c7f93407988ee0232ea90980028f299cb0f3 (patch) | |
| tree | b343b691d1bce64fb3bc9b40324857486f2be244 /web/src/contexts | |
| parent | 76f0d0e902e6ed164704572bd81faa5e5e560cf3 (diff) | |
| download | typerpunk-8d60c7f93407988ee0232ea90980028f299cb0f3.tar.gz typerpunk-8d60c7f93407988ee0232ea90980028f299cb0f3.zip | |
Initial Commit
Diffstat (limited to 'web/src/contexts')
| -rw-r--r-- | web/src/contexts/ThemeContext.tsx | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/web/src/contexts/ThemeContext.tsx b/web/src/contexts/ThemeContext.tsx new file mode 100644 index 0000000..f876269 --- /dev/null +++ b/web/src/contexts/ThemeContext.tsx @@ -0,0 +1,63 @@ +import React, { createContext, useContext, useState, useEffect } from 'react'; +import { Theme, ThemeColors } from '../types'; + +interface ThemeContextType { + theme: Theme; + colors: ThemeColors; + toggleTheme: () => void; +} + +const lightColors: ThemeColors = { + primary: '#00ff9d', + secondary: '#00cc8f', + background: '#ffffff', + text: '#333333', + error: '#ca4754', + success: '#2ecc71' +}; + +const darkColors: ThemeColors = { + primary: '#00ff9d', + secondary: '#00cc8f', + background: '#000000', + text: '#646669', + error: '#ef5350', + success: '#66bb6a' +}; + +const ThemeContext = createContext<ThemeContextType | undefined>(undefined); + +export const ThemeProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => { + const [theme, setTheme] = useState<Theme>(() => { + const savedTheme = localStorage.getItem('theme'); + return (savedTheme as Theme) || Theme.Dark; + }); + + const colors = theme === Theme.Light ? lightColors : darkColors; + + useEffect(() => { + localStorage.setItem('theme', theme); + document.documentElement.setAttribute('data-theme', theme.toLowerCase()); + if (!window.location.pathname.includes('typing-game')) { + document.body.style.backgroundColor = theme === Theme.Light ? '#ffffff' : '#000000'; + } + }, [theme]); + + const toggleTheme = () => { + setTheme(prevTheme => prevTheme === Theme.Light ? Theme.Dark : Theme.Light); + }; + + return ( + <ThemeContext.Provider value={{ theme, colors, toggleTheme }}> + {children} + </ThemeContext.Provider> + ); +}; + +export const useTheme = () => { + const context = useContext(ThemeContext); + if (context === undefined) { + throw new Error('useTheme must be used within a ThemeProvider'); + } + return context; +};
\ No newline at end of file |
