Primakov Alexandr Alexandrovich 9cbc5910ef vibe themes
2025-04-24 17:24:07 +03:00

69 lines
2.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { createSlice, PayloadAction } from '@reduxjs/toolkit';
import { ThemeType } from '../../types/theme';
import {
LIGHT_THEME,
DARK_THEME,
PINK_THEME,
BLUE_THEME,
GREEN_THEME,
PURPLE_THEME,
THEMES,
getNextTheme
} from '../../utils/themes';
// Ключ для хранения текущей темы в localStorage
const THEME_STORAGE_KEY = 'journal-pl-theme';
// Получаем сохраненную тему из localStorage или используем светлую тему по умолчанию
const getSavedTheme = (): ThemeType => {
if (typeof window !== 'undefined') {
const savedTheme = localStorage.getItem(THEME_STORAGE_KEY) as ThemeType | null;
if (savedTheme && THEMES.includes(savedTheme as ThemeType)) {
return savedTheme as ThemeType;
}
}
// По умолчанию используем светлую тему
return LIGHT_THEME;
};
interface ThemeState {
currentTheme: ThemeType;
}
const initialState: ThemeState = {
currentTheme: getSavedTheme(),
};
export const themeSlice = createSlice({
name: 'theme',
initialState,
reducers: {
setTheme: (state, action: PayloadAction<ThemeType>) => {
state.currentTheme = action.payload;
// Сохраняем выбранную тему в localStorage
if (typeof window !== 'undefined') {
localStorage.setItem(THEME_STORAGE_KEY, action.payload);
}
},
cycleNextTheme: (state) => {
state.currentTheme = getNextTheme(state.currentTheme);
// Сохраняем выбранную тему в localStorage
if (typeof window !== 'undefined') {
localStorage.setItem(THEME_STORAGE_KEY, state.currentTheme);
}
},
},
});
export const { setTheme, cycleNextTheme } = themeSlice.actions;
// Селекторы для получения информации о текущей теме
export const selectCurrentTheme = (state: { theme: ThemeState }) => state.theme.currentTheme;
export const selectIsLightVariant = (state: { theme: ThemeState }) =>
[LIGHT_THEME, PINK_THEME, BLUE_THEME, GREEN_THEME].includes(state.theme.currentTheme);
export const selectIsDarkVariant = (state: { theme: ThemeState }) =>
[DARK_THEME, PURPLE_THEME].includes(state.theme.currentTheme);
export default themeSlice.reducer;