Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | 1x 1x 26x 26x 26x 26x 26x 26x 13x 26x 13x 13x 6x 26x 4x 4x 4x 26x 13x 13x | 'use client';
import { ActionIcon, useMantineColorScheme } from '@mantine/core';
import { useTranslations } from 'next-intl';
import { type FC, useEffect, useState } from 'react';
import { FiMoon, FiSun } from 'react-icons/fi';
import { useAppDispatch } from '@/lib/store';
import { setDarkMode } from '@/lib/store/global';
import { useIsDarkMode } from '@/lib/store/global/selectors';
const ThemeSwitcher: FC = () => {
const translate = useTranslations('common');
const dispatch = useAppDispatch();
const isDarkMode = useIsDarkMode();
const { colorScheme, setColorScheme } = useMantineColorScheme();
const [mounted, setMounted] = useState(false);
useEffect(() => {
setMounted(true);
}, []);
// Sync Mantine color scheme with Redux state on mount and when isDarkMode changes
useEffect(() => {
const targetScheme = isDarkMode ? 'dark' : 'light';
if (colorScheme !== targetScheme) {
setColorScheme(targetScheme);
}
}, [isDarkMode, setColorScheme, colorScheme]);
const handleToggleTheme = () => {
const newDarkMode = !isDarkMode;
dispatch(setDarkMode(newDarkMode));
setColorScheme(newDarkMode ? 'dark' : 'light');
};
if (!mounted) {
return (
<ActionIcon
variant="subtle"
color="gray"
size="lg"
aria-label={translate('toggleTheme')}
data-testid="theme-toggle"
>
<div style={{ width: 20, height: 20 }} />
</ActionIcon>
);
}
return (
<ActionIcon
variant="subtle"
color="gray"
size="lg"
onClick={handleToggleTheme}
aria-label={translate('toggleTheme')}
data-testid="theme-toggle"
title={isDarkMode ? translate('lightMode') : translate('darkMode')}
>
{isDarkMode ? <FiSun size={20} /> : <FiMoon size={20} />}
</ActionIcon>
);
};
export default ThemeSwitcher;
|