react typescript 팝업

해적왕·2022년 11월 8일
0
post-thumbnail
post-custom-banner

storage.tsx

const storage = {
  getItem: <T,>(key: string, initialValue: T) => {
    const value = localStorage.getItem(key);

    return value === null ? initialValue : JSON.parse(value);
  },
  setItem: <T,>(key: string, value: T) => {
    try {
      localStorage.setItem(key, JSON.stringify(value));
    } catch (error) {
      console.error(error);
    }
  },
  removeItem: (key: string) => {
    localStorage.removeItem(key);
  },
};

export default storage;

Modal.tsx

import styled from "@emotion/styled";
import storage from "./storage";
import { useEffect, useState } from "react";

const Modal = () => {
  const [isOpen, setIsOpen] = useState<boolean>(true);

  useEffect(() => {
    const today = new Date().getTime();
    const popUp = storage.getItem("popup", true);
    if (today > popUp) {
      storage.removeItem("popup");
      setIsOpen(true);
    } else {
      setIsOpen(false);
    }
  }, []);

  const hideModal = () => {
    const today = new Date();
    storage.setItem(
      "popup",
      new Date(today.setDate(today.getDate() + 1)).getTime()
    );
    setIsOpen(false);
  };

  const closeModal = () => {
    setIsOpen(false);
  };

  return (
    <>
      {isOpen ? (
        <Contain>
          <Card>
            <img src="" />
            <BtnWrap>
              <span onClick={hideModal}>하루동안 보지 않기</span>
              <span onClick={closeModal}>창 닫기</span>
            </BtnWrap>
          </Card>
        </Contain>
      ) : null}
    </>
  );
};
export default Modal;

const Contain = styled.div`
  position: fixed;
  width: 100vw;
  height: 100vh;
  background: rgba(0, 0, 0, 0.3);
  top: 0;
  left: 0;
`;

const Card = styled.div`
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 280px;
  height: 350px;
  background: #fff;
  border-radius: 20px;
  overflow: hidden;
  position: relative;

  img {
    width: 100%;
    height: 295px;
    object-fit: cover;
    vertical-align: bottom;
  }
`;

const BtnWrap = styled.div`
  display: grid;
  grid-template-columns: 1fr 1fr;
  height: 55px;

  span {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 100%;
    font-size: 14px;
  }

  span:last-child {
    border-left: 1px solid #eee;
  }

  span:hover {
    background: #eee;
    cursor: pointer;
  }
`;

profile
프론트엔드
post-custom-banner

0개의 댓글