Skip to content

Commit

Permalink
Merge pull request #140 from AlbertoSSC/Feature/#47_Remember_user_pre…
Browse files Browse the repository at this point in the history
…ferences_dark_light_mode

Feature/#47 remember user preferences dark light mode
  • Loading branch information
brauliodiez authored Jan 23, 2024
2 parents 366d0b6 + bc3ed71 commit 8e26254
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 12 deletions.
1 change: 1 addition & 0 deletions src/common/local-storage/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './local-storage.helpers';
9 changes: 9 additions & 0 deletions src/common/local-storage/local-storage.helpers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export const retrieveValueFromLocalStorage = (key: string) => {
const storedValue = localStorage.getItem(key);
return storedValue ? JSON.parse(storedValue) : null;
};

export const saveValueToLocalStorage = <T>(key: string, value: T): void => {
const serializedValue = JSON.stringify(value);
localStorage.setItem(key, serializedValue);
};
39 changes: 27 additions & 12 deletions src/core/providers/theme-provider/theme-provider.tsx
Original file line number Diff line number Diff line change
@@ -1,33 +1,48 @@
import React from 'react';
import { ThemeContext } from './theme-context';
import { ThemeModel, createInitialTheme } from './theme.model';
import { ThemeModel } from './theme.model';
import {
retrieveThemePreferenceFromLocalStorage,
saveThemePreferenceToLocalStorage,
} from './theme.business';

interface Props {
children: React.ReactNode;
}
export const ThemeProvider: React.FC<Props> = (props) => {

export const ThemeProvider: React.FC<Props> = props => {
const { children } = props;
const [theme, setTheme] = React.useState<ThemeModel>(createInitialTheme());
const [theme, setTheme] = React.useState<ThemeModel>(
retrieveThemePreferenceFromLocalStorage
);

const toggleTheme = () => {
setTheme((prevTheme) => ({
...prevTheme,
themeMode: prevTheme.themeMode === 'light' ? 'dark' : 'light',
}));
setTheme(prevTheme => {
const newTheme = {
...prevTheme,
themeMode: prevTheme.themeMode === 'light' ? 'dark' : 'light',
} as ThemeModel;

saveThemePreferenceToLocalStorage(newTheme.themeMode);

return newTheme;
});
};

return (
<ThemeContext.Provider value={{theme, toggleTheme}}>
<ThemeContext.Provider value={{ theme, toggleTheme }}>
{children}
</ThemeContext.Provider>
)
}
);
};

export const useThemeContext = () => {
const context = React.useContext(ThemeContext);
if (context === null) {
throw new Error('useThemeContext: Ensure you have wrapped your app with ThemeProvider');
throw new Error(
'useThemeContext: Ensure you have wrapped your app with ThemeProvider'
);
}

return context;
};
};
22 changes: 22 additions & 0 deletions src/core/providers/theme-provider/theme.business.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { ThemeModel, createInitialTheme } from './theme.model';
import {
saveValueToLocalStorage,
retrieveValueFromLocalStorage,
} from '@/common/local-storage';

export const saveThemePreferenceToLocalStorage = (themeValue: string) => {
try {
saveValueToLocalStorage<string>('themeMode', themeValue);
} catch (e) {
console.warn('Failed to save in localStorage');
}
};

export const retrieveThemePreferenceFromLocalStorage = (): ThemeModel => {
try {
const themeMode = retrieveValueFromLocalStorage('themeMode');
return themeMode ? { themeMode } : createInitialTheme();
} catch {
return createInitialTheme();
}
};

0 comments on commit 8e26254

Please sign in to comment.