React (3) - TypeScript 오늘 하루 안보기 팝업 만들기

2022. 4. 10. 17:50front-end/React

728x90

React 로 '오늘 하루 안보기' 팝업을 만들었다.

시간을 세션이나, 로컬스토로지에 저장할 수 있는데, 로컬스토로지에 저장하였다.

 

우선 localStorage.setItem("PopUpNotShow", 시간); 으로 시간을 저장 한다.

 

그 다음 사용자가 접속 하였을 때, localStorage 에 저장된 PopUpNotShow을 가져온다.

localStorage.getItem("PopUpNotShow");  <- 코드를 보면 이 부분은  localStorage 에서 PopUpNotShow 값을 가져오는 것을 나타낸다.

 

PopUpNotShow를 현재 시간과 비교하여 현재 시간보다 더 높을 경우에는 

아직 제한 시간이 다 지난 것이 아니기 때문에 팝업을 띄우지 않는다.

 

PopUpNotShow 이 없거나 현재 시간보다 적을 경우에는 제한 시간이 다 지난 것 이기 때문에 팝업을 띄운다.

 

아래 코드를 보면되는데, 작업한 그대로 복사해서 작성한 것이 아니라 css 쪽은 삭제 된 부분이 있어서 확인 후 코드를 수정하기 바랍니다.

import styled from "styled-components";
import { useEffect, useState } from "react";

function Popup() {
 
  const [showPopup, setShowPopup] = useState<boolean>(false); // 팝업은 기본값을 안나오는 것으로 설정한다.
  const [todayCheck, setTodayCheck] = useState<boolean>(false);
  useEffect(() => {
    const PopUpNotShow: string | null = localStorage.getItem("PopUpNotShow");  //localStorage에 PopUpNotShow 값을 가져온다. 
    const currentTime = Math.floor(new Date().getTime());
    
    if (!PopUpNotShow) {   //  PopUpNotShow 없거나 처음 들어온 사람 - 팝업을 띄운다.
      setShowPopup(true);
    }
   
    if (Number(PopUpNotShow) > currentTime) return; // 아닐경우에는 팝업을 안 띄운다.
    if (Number(PopUpNotShow) < currentTime) {  // 제한 시간이 지났으므로 팝업을 다시 띄운다.
      setShowPopup(true);
    }
  }, []);
  const handleClickClose = () => {
    if (todayCheck) {
      const expire = Date.now() + 43200000; //12시간 후에 PopUpNotShow 값이 사라진다.
      const objString = JSON.stringify(expire);
      localStorage.setItem("PopUpNotShow", objString); //localStorage에 "PopUpNotShow" key로 시간(objString)을 저장한다.
    }
    setShowPopup(false);
  };
  return (
    <PopupLayer showPopup={showPopup}>
      <Closebox>
        <Input type="checkbox" id="checkbox" checked={todayCheck} onChange={() => setTodayCheck(!todayCheck)} />
        <CheckBoxLabel htmlFor="checkbox" todayCheck={todayCheck}>
          오늘 하루 안보기
        </CheckBoxLabel>
        <CloseButton onClick={handleClickClose} type="button" title="close">
          X
        </CloseButton>
      </Closebox>
    </PopupLayer>
  );
}

const CloseButton = styled.button`
  background-color: transparent;
  color: inherit;
  border-width: 0;
  padding: 0;
  cursor: pointer;
  position: absolute;
  right: 20px;
  top: 18px;
  display: block;
  width: 24px;
  height: 24px;
  background: url("close 버튼 이미지") no-repeat center; //
  background-size: 16px;
  text-indent: -9999px;
`;
const Input = styled.input`
  display: none;
`;
const CheckBoxLabel = styled.label<{ todayCheck: boolean }>`
  position: relative;
  display: inline-block;
  padding-left: 34px;
  align-items: center;
  color: #aaa;
  cursor: pointer;
  line-height: 24px;
  &:after {
    position: absolute;
    content: "";
    display: block;
    left: 0;
    top: 0;
    margin-right: 10px;
    width: 24px;
    height: 24px;
    border: 1px solid #aaa;
    border-radius: 5px;
    ${({ todayCheck }) => {
      if (todayCheck)
        return `background: url("check 이미지") no-repeat center;
        background-size: 14px`;
    }}
  }
`;
const Closebox = styled.div`
  position: absolute;
  bottom: -30px;
  left: 0;
  width: 100%;
  height: 60px;
  background: #111;
  padding: 18px 20px;
`;

const PopupLayer = styled.div<{ showPopup: boolean }>`
  transition: all 0.3s;
  position: fixed;
  align-items: center;
  background-size: auto 100%;
  z-index: 10002;
  visibility: visible; //transition 효과를 주려면 display 가 아니라 visibility로 제어한다

  ${({ showPopup }) => {
    if (!showPopup) return `opacity:0; visibility:hidden; transition:all 0.3s;`;
  }}
`;

export default Popup;

혹시 틀린 부분이나, 수정하면 좋을 것 같은 부분이 있으면 언제든지 조언 부탁드립니다.

728x90