Files
ECS-FullStack/frontend/src/contexts/ThemeContext.js

61 lines
1.9 KiB
JavaScript

import React, { createContext, useState, useMemo, useContext, useEffect } from 'react';
import { ThemeProvider as MuiThemeProvider } from '@mui/material/styles';
import { lightTheme, darkTheme, discordTheme } from '../themes';
import { UserContext } from './UserContext';
import { post } from '../lib/api';
export const ThemeContext = createContext();
export const ThemeProvider = ({ children }) => {
const { user } = useContext(UserContext);
const [themeName, setThemeName] = useState(localStorage.getItem('themeName') || 'discord');
useEffect(() => {
// Prefer an explicit user selection (stored in localStorage) over defaults or server values.
// Behavior:
// - If localStorage has a themeName, use that (user's explicit choice always wins).
// - Else if the authenticated user has a server-side preference, adopt that and persist it locally.
// - Else (first visit, no local choice and no server preference) use default 'discord'.
const storedTheme = localStorage.getItem('themeName');
if (storedTheme) {
setThemeName(storedTheme);
return;
}
if (user && user.theme) {
setThemeName(user.theme);
localStorage.setItem('themeName', user.theme);
return;
}
// First-time visitor: fall back to default
setThemeName('discord');
}, [user]);
const theme = useMemo(() => {
switch (themeName) {
case 'dark':
return darkTheme;
case 'discord':
return discordTheme;
default:
return lightTheme;
}
}, [themeName]);
const changeTheme = (name) => {
if (user) {
post('/api/user/theme', { userId: user.id, theme: name }).catch(() => {});
}
localStorage.setItem('themeName', name);
setThemeName(name);
};
return (
<ThemeContext.Provider value={{ themeName, changeTheme }}>
<MuiThemeProvider theme={theme}>
{children}
</MuiThemeProvider>
</ThemeContext.Provider>
);
};