Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature: useStorage hook to persist data on frontend #83

Open
wants to merge 36 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
1920a34
feat: added useStorage hook to persist data on frontend
AssahBismarkabah Mar 7, 2024
7e7ea0f
fix: reimplement useStorage hook in typescrpt
AssahBismarkabah Mar 8, 2024
370d3bb
#deleted: power-pay-frontend/src/components/useStorage.js
AssahBismarkabah Mar 8, 2024
af59378
feat: Add global context for interacting with localStorage and fix im…
AssahBismarkabah Mar 8, 2024
f1738d5
fix: Add global context for interacting with localStorage and fix imp…
AssahBismarkabah Mar 11, 2024
7b7f933
fix: updated storagecontext
AssahBismarkabah Mar 11, 2024
c04d849
fix: updated storagecontext
AssahBismarkabah Mar 11, 2024
c8c5c73
fix: updated storagecontext
AssahBismarkabah Mar 11, 2024
de3dd35
fix: updated storagecontext
AssahBismarkabah Mar 11, 2024
6ae1246
fix: updated login component
AssahBismarkabah Mar 11, 2024
6e02da0
fix: storagecontext
AssahBismarkabah Mar 11, 2024
1a1782d
fix: modified storageContext
AssahBismarkabah Mar 11, 2024
0e9a795
fix: updated package.json with the corresponding dependecies
AssahBismarkabah Mar 11, 2024
44e30a8
Merge branch 'main' into feature/use-storage-hook
AssahBismarkabah Mar 11, 2024
4f189c2
fix: use a type assertion to ensure compatibility between setItem in …
AssahBismarkabah Mar 11, 2024
2faa9bb
fix: updated storageContext.tsx
AssahBismarkabah Mar 11, 2024
7974f91
updated main.tsx
AssahBismarkabah Mar 12, 2024
48933b5
fix: updated removeValue
AssahBismarkabah Mar 12, 2024
6cc7740
fix: updated usestorage.ts -> hook does not interact with the storage
AssahBismarkabah Mar 12, 2024
562946a
fix: removed duplicate usestorage hook
AssahBismarkabah Mar 12, 2024
4ab0b57
fix: updated storagecontext.tsx
AssahBismarkabah Mar 13, 2024
e1d7d33
fix: added fakeimpl
AssahBismarkabah Mar 13, 2024
f700b50
fix: updated storagecontext.tsx
AssahBismarkabah Mar 13, 2024
d3d1db1
fix: updated main.tsx
AssahBismarkabah Mar 17, 2024
2f66278
fix: updated usestorage
AssahBismarkabah Mar 17, 2024
c6a61e1
fix: updated storagecontext
AssahBismarkabah Mar 17, 2024
e5aff4c
fix: updated main.ts, useStorage.ts
AssahBismarkabah Mar 18, 2024
695395a
fix: updated the logic in the usestorage.ts
AssahBismarkabah Mar 19, 2024
4cac1c5
fix: complete implementation of localstorageservice
AssahBismarkabah Mar 19, 2024
1ccb620
Merge branch 'main' into feature/use-storage-hook
AssahBismarkabah Mar 19, 2024
9c1ec67
fix: updated package.json to previous version
AssahBismarkabah Mar 19, 2024
089b27e
fix: removed updated storagecontext.tsx Removed the unnecessary line …
AssahBismarkabah Mar 20, 2024
e933383
fix: remove if condition before calling storageService.setItem
AssahBismarkabah Mar 20, 2024
cc5f16f
fix: updated useStorage.ts
AssahBismarkabah Mar 20, 2024
f0311de
fix: updated storagecontext.tsx
AssahBismarkabah Mar 20, 2024
2424a9e
fix: updated storagecontext.tsx
AssahBismarkabah Mar 20, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion power-pay-frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

104 changes: 104 additions & 0 deletions power-pay-frontend/src/hooks/StorageContext.tsx
stephane-segning marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import { createContext, PropsWithChildren, useEffect, useState } from 'react';

// Define the StorageContextData interface.
export interface StorageContextData<T> {
item: Record<string, T>;
setItem: (key: string, value: T) => Promise<boolean>;
removeItem: (key: string) => Promise<boolean>;
clear: () => Promise<boolean>;
}

// Define the StorageService interface.
interface StorageService {
stephane-segning marked this conversation as resolved.
Show resolved Hide resolved
getItem: <T>(key: string) => Promise<T | undefined>;
setItem: <T>(key: string, value: T) => Promise<boolean>;
removeItem: (key: string) => Promise<boolean>;
clear: () => Promise<boolean>;
}

// Define the LocalStorageService class implementing the StorageService interface.
export class LocalStorageService implements StorageService {
async getItem<T>(key: string): Promise<T | undefined> {
const found = localStorage.getItem(key);
if (!found) return undefined;
return JSON.parse(found) as T;
}

async setItem<T>(key: string, value: T): Promise<boolean> {
localStorage.setItem(key, JSON.stringify(value));
return true;
}

async removeItem(key: string): Promise<boolean> {
localStorage.removeItem(key);
return true;
}

async clear(): Promise<boolean> {
localStorage.clear();
return true;
}
}

// Define a global constant for the key.
const STORAGE_KEY = 'new_key';

// Create the StorageContext with default functions for getItem and setItem.
const StorageContext = createContext<StorageContextData<unknown> | undefined>(undefined);

// Define the StorageProvider component.
export function StorageProvider<T>({ children, storageService }: PropsWithChildren<{ storageService: StorageService }>) {
const [storedValue, setStoredValue] = useState<Record<string, T>>({});

// Initialize the state with the value from the local storage if it exists.
useEffect(() => {
storageService
.getItem<Record<string, T>>(STORAGE_KEY)
.then((item) => {
if (item) {
setStoredValue(item);
}
});
}, [storageService]);

// Updates the local storage whenever the state changes.
useEffect(() => {
storageService.setItem(STORAGE_KEY, storedValue);
}, [storageService, storedValue]);

// Remove the item from local storage and set the stored value to undefined
const clearItem = async (key: string): Promise<boolean> => {
localStorage.removeItem(key);
Christiantyemele marked this conversation as resolved.
Show resolved Hide resolved
setStoredValue((prevState) => {
const newState = { ...prevState };
delete newState[key];
return newState;
});
return true;
};

// Define the context value.
const contextValue: StorageContextData<T> = {
item: storedValue,
setItem: async (key, value) => {
setStoredValue((prevState) => ({
...prevState,
[key]: value,
}));
return true;
},
removeItem: async (key) => clearItem(key),
clear: async () => {
setStoredValue({});
return true;
},
};

return (
<StorageContext.Provider value={contextValue}>
{children}
</StorageContext.Provider>
);
}

export default StorageContext;
31 changes: 31 additions & 0 deletions power-pay-frontend/src/hooks/useStorage.ts
stephane-segning marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { useContext, useEffect, useState } from 'react';
import StorageContext, { StorageContextData } from './StorageContext';

// UseStorageProps<T>: An interface defining the props for the useStorage hook
interface UseStorageProps<T> {
key: string; // the key to use for storing and retrieving the value from local storage
initialValue?: T; // the initial value to use for the state variable
}

// useStorage<T = string>: A generic function that accepts a UseStorageProps<T> object.
export function useStorage<T = string>({ key, initialValue }: UseStorageProps<T>): [T | undefined, React.Dispatch<React.SetStateAction<T | undefined>>, () => void] {
const { item, setItem, removeItem } = useContext(StorageContext) as StorageContextData<T>;

// Initialize the state variable with the value from the context or the initial value
const [storedValue, setStoredValue] = useState<T | undefined>(() => {
return item[key] ?? initialValue;
});
Comment on lines +15 to +17
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove this and use item[key] directly instead of 'storedValue'


// Update the context when the storedValue changes
useEffect(() => {
setItem(key, storedValue as T);
}, [key, storedValue, setItem]);

// Clear the item from local storage and reset the stored value
const clearItem = () => {
removeItem(key);
setStoredValue(initialValue); // Reset stored value to initial value
};

return [storedValue, setStoredValue, clearItem];
}
9 changes: 7 additions & 2 deletions power-pay-frontend/src/main.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@

import React from 'react'
import ReactDOM from 'react-dom/client'
import { LocalStorageService, StorageProvider } from './hooks/StorageContext';
import App from './App.tsx'
import './index.css'

const storageService = new LocalStorageService();

ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode>
<App />
<StorageProvider storageService={storageService}>
<App />
</StorageProvider>
</React.StrictMode>,
)
)
Loading