Untitled

mail@pastecode.io avatar
unknown
tsx
a year ago
2.6 kB
2
Indexable
Never
import { useState, useEffect } from 'react';
import CryptoJS from 'crypto-js';
import { useRouter } from 'next/router';
import { useRecoilState } from 'recoil';
import { atomLocalStorageBuyCartItemsData } from '@/atoms/global/localStorageBuyCartItemsData';
import { atomLocalStorageUserAuthData } from '@/atoms/global/localStorageUserAuthData';
import { BuyCartItemType } from '@/types/global/buyCartItem.type';
import { UserAuthType } from '@/types/global/userAuth.type';
import { SellCartItemType } from '@/types/global/sellCartItem.type';
import { atomLocalStorageSellCartItemsData } from '@/atoms/global/localStorageSellCartItemsData';

function useLocalStorage<T>(
  key: 'userAuthdata' | 'buyCartItemsData' | 'sellCartItemsData',
  initialValue: any,
): [T, (value: T) => void] {
  // protect-key for encrypt and decrypt local-storage
  const protectKey = 'Z>rp1p+~u';

  // local-storage state status : undefined (loading before set local-storage data), initialValue (initial value and not found key in local storage), data
  const [state, setState] = useRecoilState<
    undefined | any | BuyCartItemType[] | SellCartItemType[] | UserAuthType
  >(
    key === 'userAuthdata'
      ? atomLocalStorageUserAuthData
      : key === 'buyCartItemsData'
      ? atomLocalStorageBuyCartItemsData
      : key === 'sellCartItemsData'
      ? atomLocalStorageSellCartItemsData
      : null,
  );

  // if change route update customHook state
  // if(key in local-storage) ? set-state(decrypted key-value) : set-state(initialValue)
  // if edited local-storage ===> remove key from local storage ===> re-render useEffect [key is dependencies] ===> not found key in local storage and set-state(initialValue)
  const router = useRouter();
  const { pathname } = router;

  useEffect((): void => {
    const item = localStorage.getItem(key);
    if (item) {
      try {
        const decryptState = CryptoJS.AES.decrypt(item, protectKey).toString(
          CryptoJS.enc.Utf8,
        );
        setState(JSON.parse(decryptState));
      } catch {
        localStorage.removeItem(key);
      }
    } else {
      setState(initialValue);
    }
  }, [key, pathname]);

  // encrypt and set-data to local-storage
  const setStateHandler = (value: T) => {
    const encryptedState = CryptoJS.AES.encrypt(
      JSON.stringify(value),
      protectKey,
    );
    localStorage.setItem(key, encryptedState.toString());
    setState(value);
  };

  return [state, setStateHandler];
}

export default useLocalStorage;