employee-fr/src/@core/context/settingsContext.tsx
rizal.productzilla 0e91646c75 first commit
2024-04-16 16:48:48 +07:00

156 lines
4.4 KiB
TypeScript

// ** React Imports
import { createContext, useState, ReactNode, useEffect } from 'react'
// ** MUI Imports
import { Direction } from '@mui/material'
// ** ThemeConfig Import
import themeConfig from '../../configs/themeConfig'
// ** Types Import
import { Skin, Mode, AppBar, Footer, ThemeColor, ContentWidth, VerticalNavToggle } from '../../@core/layouts/types'
export type Settings = {
skin: Skin
mode: Mode
appBar?: AppBar
footer?: Footer
navHidden?: boolean // navigation menu
appBarBlur: boolean
direction: Direction
navCollapsed: boolean
themeColor: ThemeColor
contentWidth: ContentWidth
layout?: 'vertical' | 'horizontal'
lastLayout?: 'vertical' | 'horizontal'
verticalNavToggleType: VerticalNavToggle
toastPosition?: 'top-left' | 'top-center' | 'top-right' | 'bottom-left' | 'bottom-center' | 'bottom-right'
}
export type PageSpecificSettings = {
skin?: Skin
mode?: Mode
appBar?: AppBar
footer?: Footer
navHidden?: boolean // navigation menu
appBarBlur?: boolean
direction?: Direction
navCollapsed?: boolean
themeColor?: ThemeColor
contentWidth?: ContentWidth
layout?: 'vertical' | 'horizontal'
lastLayout?: 'vertical' | 'horizontal'
verticalNavToggleType?: VerticalNavToggle
toastPosition?: 'top-left' | 'top-center' | 'top-right' | 'bottom-left' | 'bottom-center' | 'bottom-right'
}
export type SettingsContextValue = {
settings: Settings
saveSettings: (updatedSettings: Settings) => void
}
interface SettingsProviderProps {
children: ReactNode
pageSettings?: PageSpecificSettings | void
}
const initialSettings: Settings = {
themeColor: 'primary',
mode: themeConfig.mode,
skin: themeConfig.skin,
footer: themeConfig.footer,
layout: themeConfig.layout,
lastLayout: themeConfig.layout,
direction: themeConfig.direction,
navHidden: themeConfig.navHidden,
appBarBlur: themeConfig.appBarBlur,
navCollapsed: themeConfig.navCollapsed,
contentWidth: themeConfig.contentWidth,
toastPosition: themeConfig.toastPosition,
verticalNavToggleType: themeConfig.verticalNavToggleType,
appBar: themeConfig.layout === 'horizontal' && themeConfig.appBar === 'hidden' ? 'fixed' : themeConfig.appBar
}
const staticSettings = {
appBar: initialSettings.appBar,
footer: initialSettings.footer,
layout: initialSettings.layout,
navHidden: initialSettings.navHidden,
lastLayout: initialSettings.lastLayout,
toastPosition: initialSettings.toastPosition
}
const restoreSettings = (): Settings | null => {
let settings = null
try {
const storedData: string | null = window.localStorage.getItem('settings')
if (storedData) {
settings = { ...JSON.parse(storedData), ...staticSettings }
} else {
settings = initialSettings
}
} catch (err) {
console.error(err)
}
return settings
}
// set settings in localStorage
const storeSettings = (settings: Settings) => {
const initSettings = Object.assign({}, settings)
delete initSettings.appBar
delete initSettings.footer
delete initSettings.layout
delete initSettings.navHidden
delete initSettings.lastLayout
delete initSettings.toastPosition
window.localStorage.setItem('settings', JSON.stringify(initSettings))
}
// ** Create Context
export const SettingsContext = createContext<SettingsContextValue>({
saveSettings: () => null,
settings: initialSettings
})
export const SettingsProvider = ({ children, pageSettings }: SettingsProviderProps) => {
// ** State
const [settings, setSettings] = useState<Settings>({ ...initialSettings })
useEffect(() => {
const restoredSettings = restoreSettings()
if (restoredSettings) {
setSettings({ ...restoredSettings })
}
if (pageSettings) {
setSettings({ ...settings, ...pageSettings })
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [pageSettings])
useEffect(() => {
if (settings.layout === 'horizontal' && settings.mode === 'semi-dark') {
saveSettings({ ...settings, mode: 'light' })
}
if (settings.layout === 'horizontal' && settings.appBar === 'hidden') {
saveSettings({ ...settings, appBar: 'fixed' })
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [settings.layout])
const saveSettings = (updatedSettings: Settings) => {
storeSettings(updatedSettings)
setSettings(updatedSettings)
}
return <SettingsContext.Provider value={{ settings, saveSettings }}>{children}</SettingsContext.Provider>
}
export const SettingsConsumer = SettingsContext.Consumer