diff --git a/app/constants/session.ts b/app/constants/session.ts new file mode 100644 index 0000000..52b84b1 --- /dev/null +++ b/app/constants/session.ts @@ -0,0 +1 @@ +export const PREFER_DARK_THEME = 'prefer_dark_theme'; diff --git a/app/controllers/apps_controller.ts b/app/controllers/apps_controller.ts index 93ff812..cd98c7c 100644 --- a/app/controllers/apps_controller.ts +++ b/app/controllers/apps_controller.ts @@ -1,7 +1,17 @@ +import { PREFER_DARK_THEME } from '#constants/session'; +import { updateUserThemeValidator } from '#validators/user_theme'; import type { HttpContext } from '@adonisjs/core/http'; export default class AppsController { index({ inertia }: HttpContext) { return inertia.render('home'); } + + async updateUserTheme({ request, session, response }: HttpContext) { + const { preferDarkTheme } = await request.validateUsing( + updateUserThemeValidator + ); + session.put(PREFER_DARK_THEME, preferDarkTheme); + return response.ok('ok'); + } } diff --git a/app/validators/user_theme.ts b/app/validators/user_theme.ts new file mode 100644 index 0000000..9923292 --- /dev/null +++ b/app/validators/user_theme.ts @@ -0,0 +1,7 @@ +import vine from '@vinejs/vine'; + +export const updateUserThemeValidator = vine.compile( + vine.object({ + preferDarkTheme: vine.boolean(), + }) +); diff --git a/config/inertia.ts b/config/inertia.ts index d79782c..1903819 100644 --- a/config/inertia.ts +++ b/config/inertia.ts @@ -1,3 +1,4 @@ +import { PREFER_DARK_THEME } from '#constants/session'; import { defineConfig } from '@adonisjs/inertia'; export default defineConfig({ @@ -11,6 +12,7 @@ export default defineConfig({ */ sharedData: { errors: (ctx) => ctx.session?.flashMessages.get('errors'), + preferDarkTheme: (ctx) => ctx.session.get(PREFER_DARK_THEME, true), auth: async (ctx) => { await ctx.auth?.check(); return { diff --git a/inertia/components/dashboard/link_list/link_controls.tsx b/inertia/components/dashboard/link_list/link_controls.tsx index 2be5887..359bfc1 100644 --- a/inertia/components/dashboard/link_list/link_controls.tsx +++ b/inertia/components/dashboard/link_list/link_controls.tsx @@ -66,7 +66,6 @@ export default function LinkControls({ link }: { link: Link }) { .catch(console.error); }; - console.log(link.favorite, link.favorite ? 'oui' : 'non'); return ( } diff --git a/inertia/contexts/dark_theme_context.tsx b/inertia/contexts/dark_theme_context.tsx index 94e6651..d560f0e 100644 --- a/inertia/contexts/dark_theme_context.tsx +++ b/inertia/contexts/dark_theme_context.tsx @@ -1,4 +1,6 @@ +import { usePage } from '@inertiajs/react'; import { ReactNode, createContext, useEffect, useState } from 'react'; +import { makeRequest } from '~/lib/request'; const LS_KEY = 'dark_theme'; @@ -12,18 +14,18 @@ export default function DarkThemeContextProvider({ }: { children: ReactNode; }) { - const [isDarkTheme, setDarkTheme] = useState(() => { - if (typeof window === 'undefined' || typeof localStorage === 'undefined') - return true; - - const doUserPreferDarkTheme = window?.matchMedia( - '(prefers-color-scheme: dark)' - ).matches; - return ( - localStorage.getItem(LS_KEY) === 'true' ?? doUserPreferDarkTheme ?? true - ); - }); - const toggleDarkTheme = (value: boolean) => setDarkTheme(value); + const { preferDarkTheme } = usePage<{ preferDarkTheme: boolean }>().props; + const [isDarkTheme, setDarkTheme] = useState(preferDarkTheme); + const toggleDarkTheme = (value: boolean) => { + setDarkTheme(value); + makeRequest({ + method: 'POST', + url: '/user/theme', + body: { + preferDarkTheme: value, + }, + }); + }; useEffect(() => { localStorage.setItem(LS_KEY, String(isDarkTheme)); diff --git a/start/routes.ts b/start/routes.ts index 4b741ad..28d1433 100644 --- a/start/routes.ts +++ b/start/routes.ts @@ -10,6 +10,7 @@ const AppsController = () => import('#controllers/apps_controller'); const FaviconsController = () => import('#controllers/favicons_controller'); router.get(PATHS.HOME, [AppsController, 'index']); +router.post('/user/theme', [AppsController, 'updateUserTheme']); router.get(PATHS.AUTH.LOGIN, [UsersController, 'login']); router.get(PATHS.AUTH.GOOGLE, [UsersController, 'google']); router.get('/auth/callback', [UsersController, 'callbackAuth']);