✨(frontend) add hook to sync user preferences
Implement new hook that synchronizes user language and timezone preferences from frontend to backend. Ensures consistent localization across and notifications. Note: Current implementation works but auth code requires future refactoring.
This commit is contained in:
committed by
aleb_the_flash
parent
7f0e866eac
commit
ec114808b2
@@ -3,12 +3,14 @@ import { useConfig } from '@/api/useConfig'
|
||||
import { useAnalytics } from '@/features/analytics/hooks/useAnalytics'
|
||||
import { useSupport } from '@/features/support/hooks/useSupport'
|
||||
import { useLocation } from 'wouter'
|
||||
import { useSyncUserPreferencesWithBackend } from '@/features/auth'
|
||||
|
||||
const SDK_BASE_ROUTE = '/sdk'
|
||||
|
||||
export const AppInitialization = () => {
|
||||
const { data } = useConfig()
|
||||
const [location] = useLocation()
|
||||
useSyncUserPreferencesWithBackend()
|
||||
|
||||
const {
|
||||
analytics = {},
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
import { BackendLanguage } from '@/utils/languages'
|
||||
|
||||
export type ApiUser = {
|
||||
id: string
|
||||
email: string
|
||||
full_name: string
|
||||
last_name: string
|
||||
language: BackendLanguage
|
||||
timezone: string
|
||||
}
|
||||
|
||||
15
src/frontend/src/features/auth/api/updateUserPreferences.ts
Normal file
15
src/frontend/src/features/auth/api/updateUserPreferences.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import { type ApiUser } from './ApiUser'
|
||||
import { fetchApi } from '@/api/fetchApi'
|
||||
|
||||
export type ApiUserPreferences = Pick<ApiUser, 'id' | 'timezone' | 'language'>
|
||||
|
||||
export const updateUserPreferences = async ({
|
||||
user,
|
||||
}: {
|
||||
user: ApiUserPreferences
|
||||
}): Promise<ApiUser> => {
|
||||
return await fetchApi(`/users/${user.id}/`, {
|
||||
method: 'PUT',
|
||||
body: JSON.stringify({ timezone: user.timezone, language: user.language }),
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
import { useMutation } from '@tanstack/react-query'
|
||||
import { keys } from '@/api/queryKeys'
|
||||
import { useEffect } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { queryClient } from '@/api/queryClient'
|
||||
import { updateUserPreferences } from './updateUserPreferences'
|
||||
import { convertToBackendLanguage } from '@/utils/languages'
|
||||
import { useUser } from './useUser'
|
||||
|
||||
/**
|
||||
* Hook that synchronizes user browser preferences (language, timezone) with backend user settings.
|
||||
* Automatically updates backend when browser settings change for logged-in users.
|
||||
*/
|
||||
export const useSyncUserPreferencesWithBackend = () => {
|
||||
const { i18n } = useTranslation()
|
||||
const { user, isLoggedIn } = useUser()
|
||||
|
||||
const { mutateAsync } = useMutation({
|
||||
mutationFn: updateUserPreferences,
|
||||
onSuccess: (updatedUser) => {
|
||||
queryClient.setQueryData([keys.user], updatedUser)
|
||||
},
|
||||
})
|
||||
|
||||
useEffect(() => {
|
||||
if (!user || !isLoggedIn) return
|
||||
|
||||
const syncBrowserPreferencesToBackend = async () => {
|
||||
const currentTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone
|
||||
const currentLanguage = convertToBackendLanguage(i18n.language)
|
||||
if (
|
||||
currentLanguage !== user.language ||
|
||||
currentTimezone !== user.timezone
|
||||
) {
|
||||
await mutateAsync({
|
||||
user: {
|
||||
id: user.id,
|
||||
timezone: currentTimezone,
|
||||
language: currentLanguage,
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
syncBrowserPreferencesToBackend()
|
||||
}, [i18n.language, isLoggedIn, user, mutateAsync])
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
export { useUser } from './api/useUser'
|
||||
export { useSyncUserPreferencesWithBackend } from './api/useSyncUserPreferencesWithBackend'
|
||||
export { authUrl } from './utils/authUrl'
|
||||
export { UserAware } from './components/UserAware'
|
||||
|
||||
16
src/frontend/src/utils/languages.ts
Normal file
16
src/frontend/src/utils/languages.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
// Map frontend language codes to backend language codes
|
||||
|
||||
export type BackendLanguage = 'en-us' | 'fr-fr' | 'nl-nl'
|
||||
export type FrontendLanguage = 'en' | 'fr' | 'nl'
|
||||
|
||||
const frontendToBackendMap: Record<FrontendLanguage, BackendLanguage> = {
|
||||
en: 'en-us',
|
||||
fr: 'fr-fr',
|
||||
nl: 'nl-nl',
|
||||
}
|
||||
|
||||
export const convertToBackendLanguage = (
|
||||
frontendLang: string = 'fr'
|
||||
): BackendLanguage => {
|
||||
return frontendToBackendMap[frontendLang as FrontendLanguage]
|
||||
}
|
||||
Reference in New Issue
Block a user