Set persistent theme on cookies
This commit is contained in:
parent
295fc4dadb
commit
581e5704d4
|
@ -0,0 +1,31 @@
|
||||||
|
'use client'
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import { AppProgressBar as ProgressBar } from 'next-nprogress-bar';
|
||||||
|
|
||||||
|
import { LAYOUT_COLORS_PINK, LAYOUT_COLORS_YELLOW } from '@/constants/colors';
|
||||||
|
import { Themes } from '@/meta/settings';
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
theme?: Themes
|
||||||
|
}
|
||||||
|
|
||||||
|
const Body: React.FC<Props & React.PropsWithChildren> = (props) => {
|
||||||
|
|
||||||
|
const { theme, children } = props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<body>
|
||||||
|
<main className="container">{children}</main>
|
||||||
|
<ProgressBar
|
||||||
|
height="4px"
|
||||||
|
color={theme == Themes.dark ? LAYOUT_COLORS_YELLOW : LAYOUT_COLORS_PINK}
|
||||||
|
options={{ showSpinner: false }}
|
||||||
|
shallowRouting
|
||||||
|
/>
|
||||||
|
</body>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Body;
|
|
@ -1,36 +1,26 @@
|
||||||
'use client'
|
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import Head from 'next/head';
|
import Head from 'next/head';
|
||||||
|
|
||||||
import { AppProgressBar as ProgressBar } from 'next-nprogress-bar';
|
|
||||||
|
|
||||||
import { useAppSelector } from '@/store/store';
|
|
||||||
import { LAYOUT_COLORS_PINK, LAYOUT_COLORS_YELLOW } from '@/constants/colors';
|
|
||||||
import { Themes } from '@/meta/settings';
|
import { Themes } from '@/meta/settings';
|
||||||
|
|
||||||
const Content: React.FC<React.PropsWithChildren> = (props) => {
|
import Body from './Body';
|
||||||
|
|
||||||
const { children } = props;
|
interface Props {
|
||||||
|
theme?: Themes
|
||||||
|
}
|
||||||
|
|
||||||
const theme = useAppSelector((state) => state.settings.theme);
|
const Content: React.FC<Props & React.PropsWithChildren> = (props) => {
|
||||||
|
|
||||||
|
const { theme, children } = props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<html data-theme={theme} /*lang={locale}*/>
|
<html data-theme={theme}>
|
||||||
<Head>
|
<Head>
|
||||||
<meta charSet="utf-8" />
|
<meta charSet="utf-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
</Head>
|
</Head>
|
||||||
<body>
|
<Body theme={theme}>{children}</Body>
|
||||||
<main className="container">{children}</main>
|
|
||||||
<ProgressBar
|
|
||||||
height="4px"
|
|
||||||
color={theme == Themes.dark ? LAYOUT_COLORS_YELLOW : LAYOUT_COLORS_PINK}
|
|
||||||
options={{ showSpinner: false }}
|
|
||||||
shallowRouting
|
|
||||||
/>
|
|
||||||
</body>
|
|
||||||
</html>
|
</html>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -3,23 +3,29 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import { TbMoon, TbSun } from 'react-icons/tb';
|
import { TbMoon, TbSun } from 'react-icons/tb';
|
||||||
import { useAppDispatch, useAppSelector } from '@/store/store';
|
import { DEFAULT_THEME, Themes } from '@/meta/settings';
|
||||||
import { Themes } from '@/meta/settings';
|
|
||||||
import { setCurrentTheme } from '@/store/settingsSlice';
|
|
||||||
|
|
||||||
import Icon from '../Icon';
|
import Icon from '../Icon';
|
||||||
|
import { setCookie } from '@/utils/cookies/write';
|
||||||
|
import { useCookies } from 'react-cookie';
|
||||||
|
|
||||||
const Menu: React.FC = () => {
|
const Theme: React.FC = () => {
|
||||||
|
|
||||||
const theme = useAppSelector((state) => state.settings.theme);
|
const [cookies] = useCookies(['theme']);
|
||||||
const dispatch = useAppDispatch();
|
|
||||||
|
const theme = cookies.theme ?? DEFAULT_THEME
|
||||||
|
|
||||||
|
const handleClick = async () => {
|
||||||
|
const newTheme = theme == Themes.dark ? Themes.light : Themes.dark
|
||||||
|
await setCookie('theme', newTheme)
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Icon handleClick={() => dispatch(setCurrentTheme(theme == Themes.dark ? Themes.light : Themes.dark))}>
|
<Icon handleClick={handleClick}>
|
||||||
{theme == Themes.dark && <TbMoon size={24} />}
|
{theme == Themes.dark && <TbMoon size={24} />}
|
||||||
{theme == Themes.light && <TbSun size={24} />}
|
{theme == Themes.light && <TbSun size={24} />}
|
||||||
</Icon>
|
</Icon>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Menu;
|
export default Theme;
|
|
@ -1,15 +1,22 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
|
import { cookies } from 'next/headers'
|
||||||
|
|
||||||
import WithRedux from '@/store/withRedux';
|
import WithRedux from '@/store/withRedux';
|
||||||
import Content from './Content';
|
import Content from './Content';
|
||||||
|
import { DEFAULT_THEME, Themes } from '@/meta/settings';
|
||||||
|
|
||||||
const Layout: React.FC<React.PropsWithChildren> = (props) => {
|
const Layout: React.FC<React.PropsWithChildren> = (props) => {
|
||||||
|
|
||||||
const { children } = props;
|
const { children } = props;
|
||||||
|
|
||||||
|
const cookieStore = cookies()
|
||||||
|
|
||||||
|
const theme = cookieStore.get('theme')
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<WithRedux>
|
<WithRedux>
|
||||||
<Content>
|
<Content theme={theme ? theme?.value as Themes : DEFAULT_THEME}>
|
||||||
{children}
|
{children}
|
||||||
</Content>
|
</Content>
|
||||||
</WithRedux>
|
</WithRedux>
|
||||||
|
|
|
@ -5,9 +5,11 @@ export enum Platforms {
|
||||||
|
|
||||||
export enum Themes {
|
export enum Themes {
|
||||||
light= 'light',
|
light= 'light',
|
||||||
dark= 'dark'
|
dark= 'dark',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const DEFAULT_THEME = Themes.light
|
||||||
|
|
||||||
export interface LangOption {
|
export interface LangOption {
|
||||||
label: string;
|
label: string;
|
||||||
code: string;
|
code: string;
|
||||||
|
|
Loading…
Reference in New Issue