mirror of
https://github.com/Lifeforge-app/lifeforge.git
synced 2026-06-28 14:55:45 +00:00
201 lines
5.0 KiB
TypeScript
201 lines
5.0 KiB
TypeScript
import { createContext, useContext, useEffect } from 'react'
|
|
|
|
import { useAuth } from '@lifeforge/api'
|
|
import { toast } from '@lifeforge/ui'
|
|
import {
|
|
type IBackdropFilters,
|
|
type IDashboardLayout,
|
|
usePersonalization
|
|
} from '@lifeforge/ui'
|
|
|
|
import forgeAPI from '@/forgeAPI'
|
|
|
|
const UserPersonalizationContext = createContext<{
|
|
changeFontFamily: (font: string) => Promise<void>
|
|
changeFontScale: (scale: number) => Promise<void>
|
|
changeTheme: (theme: 'light' | 'dark' | 'system') => Promise<void>
|
|
changeThemeColor: (color: string) => Promise<void>
|
|
changeBgTemp: (color: string) => Promise<void>
|
|
changeBackdropFilters: (filters: IBackdropFilters) => Promise<void>
|
|
changeLanguage: (language: string) => Promise<void>
|
|
changeDashboardLayout: (layout: IDashboardLayout) => Promise<void>
|
|
changeBorderRadiusMultiplier: (multiplier: number) => Promise<void>
|
|
changeBordered: (bordered: boolean) => Promise<void>
|
|
}>({} as any)
|
|
|
|
async function syncUserData(
|
|
data: Record<string, unknown>,
|
|
setUserData: React.Dispatch<React.SetStateAction<any>>
|
|
) {
|
|
try {
|
|
await forgeAPI.user.personalization.updatePersonalization.mutate({
|
|
data
|
|
})
|
|
|
|
if (setUserData) {
|
|
setUserData((oldData: any) => {
|
|
if (!oldData) return oldData
|
|
|
|
return { ...oldData, ...data }
|
|
})
|
|
}
|
|
} catch {
|
|
toast.error('Failed to update personalization settings')
|
|
}
|
|
}
|
|
|
|
function UserPersonalizationProvider({
|
|
children
|
|
}: {
|
|
children: React.ReactNode
|
|
}) {
|
|
const { userData, setUserData } = useAuth()
|
|
|
|
const {
|
|
setFontFamily,
|
|
setTheme,
|
|
setRawThemeColor,
|
|
setBgTemp,
|
|
setBackdropFilters,
|
|
setLanguage,
|
|
setDashboardLayout,
|
|
setFontScale,
|
|
setBgImage,
|
|
setBorderRadiusMultiplier,
|
|
setBordered
|
|
} = usePersonalization()
|
|
|
|
async function changeFontFamily(font: string) {
|
|
await syncUserData({ fontFamily: font }, setUserData)
|
|
}
|
|
|
|
async function changeFontScale(scale: number) {
|
|
await syncUserData({ fontScale: scale }, setUserData)
|
|
}
|
|
|
|
async function changeTheme(theme: 'light' | 'dark' | 'system') {
|
|
await syncUserData({ theme }, setUserData)
|
|
}
|
|
|
|
async function changeThemeColor(color: string) {
|
|
await syncUserData({ color: color.replace('theme-', '') }, setUserData)
|
|
}
|
|
|
|
async function changeBgTemp(color: string) {
|
|
await syncUserData({ bgTemp: color.replace('bg-', '') }, setUserData)
|
|
}
|
|
|
|
async function changeBackdropFilters(filters: IBackdropFilters) {
|
|
await syncUserData({ backdropFilters: filters }, setUserData)
|
|
}
|
|
|
|
async function changeLanguage(language: string) {
|
|
await syncUserData({ language }, setUserData)
|
|
}
|
|
|
|
async function changeDashboardLayout(layout: IDashboardLayout) {
|
|
await syncUserData({ dashboardLayout: layout }, setUserData)
|
|
}
|
|
|
|
async function changeBorderRadiusMultiplier(multiplier: number) {
|
|
await syncUserData({ borderRadiusMultiplier: multiplier }, setUserData)
|
|
}
|
|
|
|
async function changeBordered(bordered: boolean) {
|
|
await syncUserData({ bordered }, setUserData)
|
|
}
|
|
|
|
useEffect(() => {
|
|
if (!userData) return
|
|
|
|
setTheme(userData.theme)
|
|
|
|
if (userData?.color !== '') {
|
|
setRawThemeColor(
|
|
userData.color.startsWith('#')
|
|
? userData.color
|
|
: `theme-${userData.color}`
|
|
)
|
|
}
|
|
|
|
if (userData?.bgTemp !== '') {
|
|
setBgTemp(
|
|
userData.bgTemp.startsWith('#')
|
|
? userData.bgTemp
|
|
: `bg-${userData.bgTemp}`
|
|
)
|
|
}
|
|
|
|
if (userData?.backdropFilters) {
|
|
setBackdropFilters(userData.backdropFilters as IBackdropFilters)
|
|
}
|
|
|
|
if (userData?.bgImage !== '') {
|
|
setBgImage(
|
|
forgeAPI.getMedia({
|
|
collectionId: userData.collectionId,
|
|
recordId: userData.id,
|
|
fieldId: userData.bgImage
|
|
})
|
|
)
|
|
}
|
|
|
|
if (userData?.language !== '') {
|
|
setLanguage(userData.language)
|
|
}
|
|
|
|
if (userData?.dashboardLayout !== '') {
|
|
setDashboardLayout(userData.dashboardLayout as IDashboardLayout)
|
|
}
|
|
|
|
if (userData?.fontFamily !== undefined) {
|
|
setFontFamily(userData.fontFamily)
|
|
}
|
|
|
|
if (userData?.fontScale !== undefined) {
|
|
setFontScale(userData.fontScale)
|
|
}
|
|
|
|
if (userData?.borderRadiusMultiplier !== undefined) {
|
|
setBorderRadiusMultiplier(userData.borderRadiusMultiplier)
|
|
}
|
|
|
|
if (userData?.bordered !== undefined) {
|
|
setBordered(userData.bordered)
|
|
}
|
|
}, [userData])
|
|
|
|
return (
|
|
<UserPersonalizationContext
|
|
value={{
|
|
changeFontFamily,
|
|
changeFontScale,
|
|
changeTheme,
|
|
changeThemeColor,
|
|
changeBgTemp,
|
|
changeBackdropFilters,
|
|
changeLanguage,
|
|
changeDashboardLayout,
|
|
changeBorderRadiusMultiplier,
|
|
changeBordered
|
|
}}
|
|
>
|
|
{children}
|
|
</UserPersonalizationContext>
|
|
)
|
|
}
|
|
|
|
export default UserPersonalizationProvider
|
|
|
|
export function useUserPersonalization() {
|
|
const context = useContext(UserPersonalizationContext)
|
|
|
|
if (!context) {
|
|
throw new Error(
|
|
'useUserPersonalization must be used within a UserPersonalizationProvider'
|
|
)
|
|
}
|
|
|
|
return context
|
|
}
|