import * as React from "react" ; import { getStorage , IProductStorage , setStorage } from "@/utils/storage" ; type StorageContextType = { cartStorage : Array < IProductStorage > | null ; savedStorage : Array < IProductStorage > | null ; } ; type StorageUpdateContextType = { addCartValue : ( value : IProductStorage ) => void ; clearCart : ( ) => void ; removeCartValue : ( event : React . MouseEvent < HTMLButtonElement > ) => void ; setCartStorage : React . Dispatch < React . SetStateAction < IProductStorage [ ] | null > > ; toggleSavedValue : ( key : string , value : IProductStorage ) => void ; updateItemsQuantities : ( cartQuantities : number [ ] ) => void ; } ; const StorageContext = React . createContext < StorageContextType | undefined > ( undefined ) ; const StorageDispatchContext = React . createContext < StorageUpdateContextType | undefined > ( undefined ) ; export const useStore = ( ) : StorageContextType | undefined => React . useContext ( StorageContext ) ; export const useStoreUpdate = ( ) : StorageUpdateContextType | undefined => React . useContext ( StorageDispatchContext ) ; const useStorage = ( key ) => { const CART_KEY = "cart-products" ; const SAVED_KEY = "saved-products" ; const [ cartStorage , setCartStorage ] = React . useState ( getStorage ( CART_KEY ) ) ; const [ savedStorage , setSavedStorage ] = React . useState ( getStorage ( SAVED_KEY ) ) ; const toggleSavedValue = ( key , value ) => { const items = getStorage ( key ) ; let stateItems ; if ( ! items ) { setStorage ( key , [ value ] ) ; } if ( Array . isArray ( items ) ) { const filterDuplicateItems = items . filter ( item => item . id !== value . id ) ; if ( filterDuplicateItems . length < items . length ) { stateItems = [ ... filterDuplicateItems ] ; setStorage ( key , stateItems ) ; } else { const addNewItems = [ ... items , value ] ; stateItems = addNewItems ; setStorage ( key , stateItems ) ; } } setSavedStorage ( stateItems ?? null ) ; } ; const addCartValue = ( value ) => { const items = getStorage ( key ) ; if ( ! items ) { setStorage ( key , [ value ] ) ; } else { const isItemDuplicate = items . some ( item => item . id === value . id ) ; if ( ! isItemDuplicate ) { items . push ( value ) ; setStorage ( key , items ) ; } else { return ; } } setCartStorage ( items ) ; } ; const updateItemsQuantities = ( quantities ) => { const items = getStorage ( key ) ! ; let updatedItems = items ; if ( items ) { updatedItems = items . flatMap ( ( item , index ) => { if ( quantities [ index ] < 1 ) { return [ ] ; } return { ... item , quantity : quantities [ index ] } ; } ) ; setStorage ( key , updatedItems ) ; } setCartStorage ( updatedItems ) ; } ; const clearCart = ( ) => { setStorage ( CART_KEY , [ ] ) ; setCartStorage ( [ ] ) ; } ; const removeCartValue = ( event ) => { const items = getStorage ( key ) ! ; const productElementId = ( event . target as HTMLElement ) . closest ( "li" ) ?. id ; const newStorage = items ?. filter ( item => item . id !== productElementId ) ; setStorage ( key , newStorage ) ; setCartStorage ( newStorage ) ; } ; return { addCartValue , cartStorage , clearCart , removeCartValue , savedStorage , setCartStorage , toggleSavedValue , updateItemsQuantities } ; } ; const StorageProvider = ( { children } ) : React . ReactElement => { const { cartStorage , addCartValue , clearCart , removeCartValue , updateItemsQuantities } = useStorage ( "cart-products" ) ; const { savedStorage , toggleSavedValue , setCartStorage } = useStorage ( "saved-products" ) ; return ( < StorageContext . Provider value = { { cartStorage , savedStorage } } > < StorageDispatchContext . Provider value = { { addCartValue , clearCart , removeCartValue , setCartStorage , toggleSavedValue , updateItemsQuantities } } > { children } < /StorageDispatchContext.Provider> < /StorageContext.Provider>); } ; export default StorageProvider ;