143 lines
4.0 KiB
TypeScript
143 lines
4.0 KiB
TypeScript
import React, { ReactNode, useContext, useEffect, useState } from "react"
|
|
|
|
const BANK_ACCOUNT_NUMBER_KEY = 'bank_account_number';
|
|
const BANK_ACCOUNT_HOLDER_KEY = 'bank_account_holder_name';
|
|
const HIDE_SOUPS_KEY = 'hide_soups';
|
|
const THEME_KEY = 'theme_preference';
|
|
|
|
export type ThemePreference = 'system' | 'light' | 'dark';
|
|
|
|
export type SettingsContextProps = {
|
|
bankAccount?: string,
|
|
holderName?: string,
|
|
hideSoups?: boolean,
|
|
themePreference: ThemePreference,
|
|
setBankAccountNumber: (accountNumber?: string) => void,
|
|
setBankAccountHolderName: (holderName?: string) => void,
|
|
setHideSoupsOption: (hideSoups?: boolean) => void,
|
|
setThemePreference: (theme: ThemePreference) => void,
|
|
}
|
|
|
|
type ContextProps = {
|
|
children: ReactNode
|
|
}
|
|
|
|
const settingsContext = React.createContext<SettingsContextProps | null>(null);
|
|
|
|
export function ProvideSettings(props: Readonly<ContextProps>) {
|
|
const settings = useProvideSettings();
|
|
return <settingsContext.Provider value={settings}>{props.children}</settingsContext.Provider>
|
|
}
|
|
|
|
export const useSettings = () => {
|
|
return useContext(settingsContext);
|
|
}
|
|
|
|
function getInitialTheme(): ThemePreference {
|
|
try {
|
|
const saved = localStorage.getItem(THEME_KEY) as ThemePreference | null;
|
|
if (saved && ['system', 'light', 'dark'].includes(saved)) {
|
|
return saved;
|
|
}
|
|
} catch (e) {
|
|
// localStorage nedostupný
|
|
}
|
|
return 'system';
|
|
}
|
|
|
|
function useProvideSettings(): SettingsContextProps {
|
|
const [bankAccount, setBankAccount] = useState<string | undefined>();
|
|
const [holderName, setHolderName] = useState<string | undefined>();
|
|
const [hideSoups, setHideSoups] = useState<boolean | undefined>();
|
|
const [themePreference, setTheme] = useState<ThemePreference>(getInitialTheme);
|
|
|
|
useEffect(() => {
|
|
const accountNumber = localStorage.getItem(BANK_ACCOUNT_NUMBER_KEY);
|
|
if (accountNumber) {
|
|
setBankAccount(accountNumber);
|
|
}
|
|
const holderName = localStorage.getItem(BANK_ACCOUNT_HOLDER_KEY);
|
|
if (holderName) {
|
|
setHolderName(holderName);
|
|
}
|
|
const hideSoups = localStorage.getItem(HIDE_SOUPS_KEY);
|
|
if (hideSoups !== null) {
|
|
setHideSoups(hideSoups === 'true');
|
|
}
|
|
}, [])
|
|
|
|
useEffect(() => {
|
|
if (bankAccount) {
|
|
localStorage.setItem(BANK_ACCOUNT_NUMBER_KEY, bankAccount)
|
|
} else {
|
|
localStorage.removeItem(BANK_ACCOUNT_NUMBER_KEY);
|
|
}
|
|
}, [bankAccount]);
|
|
|
|
useEffect(() => {
|
|
if (holderName) {
|
|
localStorage.setItem(BANK_ACCOUNT_HOLDER_KEY, holderName);
|
|
} else {
|
|
localStorage.removeItem(BANK_ACCOUNT_HOLDER_KEY);
|
|
}
|
|
}, [holderName]);
|
|
|
|
useEffect(() => {
|
|
if (hideSoups) {
|
|
localStorage.setItem(HIDE_SOUPS_KEY, hideSoups ? 'true' : 'false');
|
|
} else {
|
|
localStorage.removeItem(HIDE_SOUPS_KEY);
|
|
}
|
|
}, [hideSoups]);
|
|
|
|
useEffect(() => {
|
|
localStorage.setItem(THEME_KEY, themePreference);
|
|
}, [themePreference]);
|
|
|
|
useEffect(() => {
|
|
const applyTheme = (theme: 'light' | 'dark') => {
|
|
document.documentElement.setAttribute('data-bs-theme', theme);
|
|
};
|
|
|
|
if (themePreference === 'system') {
|
|
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
|
|
applyTheme(mediaQuery.matches ? 'dark' : 'light');
|
|
|
|
const handler = (e: MediaQueryListEvent) => {
|
|
applyTheme(e.matches ? 'dark' : 'light');
|
|
};
|
|
mediaQuery.addEventListener('change', handler);
|
|
return () => mediaQuery.removeEventListener('change', handler);
|
|
} else {
|
|
applyTheme(themePreference);
|
|
}
|
|
}, [themePreference]);
|
|
|
|
function setBankAccountNumber(bankAccount?: string) {
|
|
setBankAccount(bankAccount);
|
|
}
|
|
|
|
function setBankAccountHolderName(holderName?: string) {
|
|
setHolderName(holderName);
|
|
}
|
|
|
|
function setHideSoupsOption(hideSoups?: boolean) {
|
|
setHideSoups(hideSoups);
|
|
}
|
|
|
|
function setThemePreference(theme: ThemePreference) {
|
|
setTheme(theme);
|
|
}
|
|
|
|
return {
|
|
bankAccount,
|
|
holderName,
|
|
hideSoups,
|
|
themePreference,
|
|
setBankAccountNumber,
|
|
setBankAccountHolderName,
|
|
setHideSoupsOption,
|
|
setThemePreference,
|
|
}
|
|
}
|