diff --git a/app/user/constants/theme.ts b/app/user/constants/theme.ts index f7809d1..f3c82a5 100644 --- a/app/user/constants/theme.ts +++ b/app/user/constants/theme.ts @@ -1,2 +1,3 @@ -export const PREFER_DARK_THEME = 'prefer_dark_theme'; -export const DARK_THEME_DEFAULT_VALUE = true; +export const KEY_USER_THEME = 'user_theme'; +export const THEMES = ['dark', 'light'] as const; +export const DEFAULT_USER_THEME = THEMES.at(0); diff --git a/app/user/controllers/theme_controller.ts b/app/user/controllers/theme_controller.ts index 2da56b3..0f4d7cd 100644 --- a/app/user/controllers/theme_controller.ts +++ b/app/user/controllers/theme_controller.ts @@ -1,12 +1,11 @@ -import { PREFER_DARK_THEME } from '#user/constants/theme'; +import { KEY_USER_THEME } from '#user/constants/theme'; import { updateThemeValidator } from '#user/validators/update_theme_validator'; import type { HttpContext } from '@adonisjs/core/http'; export default class ThemeController { async index({ request, session, response }: HttpContext) { - const { preferDarkTheme } = - await request.validateUsing(updateThemeValidator); - session.put(PREFER_DARK_THEME, preferDarkTheme); + const { theme } = await request.validateUsing(updateThemeValidator); + session.put(KEY_USER_THEME, theme); return response.ok({ message: 'ok' }); } } diff --git a/app/user/validators/update_theme_validator.ts b/app/user/validators/update_theme_validator.ts index 4ef1d84..0cfe2d3 100644 --- a/app/user/validators/update_theme_validator.ts +++ b/app/user/validators/update_theme_validator.ts @@ -1,7 +1,8 @@ +import { THEMES } from '#user/constants/theme'; import vine from '@vinejs/vine'; export const updateThemeValidator = vine.compile( vine.object({ - preferDarkTheme: vine.boolean(), + theme: vine.enum(THEMES), }) ); diff --git a/config/inertia.ts b/config/inertia.ts index ccd2ace..239570c 100644 --- a/config/inertia.ts +++ b/config/inertia.ts @@ -1,8 +1,5 @@ import { isSSREnableForPage } from '#config/ssr'; -import { - DARK_THEME_DEFAULT_VALUE, - PREFER_DARK_THEME, -} from '#user/constants/theme'; +import { DEFAULT_USER_THEME, KEY_USER_THEME } from '#user/constants/theme'; import logger from '@adonisjs/core/services/logger'; import { defineConfig } from '@adonisjs/inertia'; @@ -17,8 +14,9 @@ export default defineConfig({ */ sharedData: { errors: (ctx) => ctx.session?.flashMessages.get('errors'), - preferDarkTheme: (ctx) => - ctx.session?.get(PREFER_DARK_THEME, DARK_THEME_DEFAULT_VALUE), + user: (ctx) => ({ + theme: ctx.session?.get(KEY_USER_THEME, DEFAULT_USER_THEME), + }), auth: async (ctx) => { await ctx.auth?.check(); return { diff --git a/inertia/components/common/theme_switcher.tsx b/inertia/components/common/theme_switcher.tsx index 654c8c5..5e515a1 100644 --- a/inertia/components/common/theme_switcher.tsx +++ b/inertia/components/common/theme_switcher.tsx @@ -1,13 +1,22 @@ import { ActionIcon, useMantineColorScheme } from '@mantine/core'; import { TbMoonStars, TbSun } from 'react-icons/tb'; +import { makeRequest } from '~/lib/request'; export function MantineThemeSwitcher() { const { colorScheme, toggleColorScheme } = useMantineColorScheme(); + const handleThemeChange = () => { + toggleColorScheme(); + makeRequest({ + url: '/user/theme', + method: 'POST', + body: { theme: colorScheme === 'dark' ? 'light' : 'dark' }, + }); + }; return ( toggleColorScheme()} + onClick={handleThemeChange} size="lg" > {colorScheme === 'dark' ? : }