Typescript

Mbti input radio로 선택지 주고싶을때

hovinee 2022. 11. 28. 16:29

나중에는 더 간결하게..ㅠ

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

import { newUserMbti } from "../../../redux/features/userSlice";
import { useAppDispatch } from "../../../redux/hook";

const SelectMbti = () => {
  const dispatch = useAppDispatch();
  const [eClick, setEClick] = useState<boolean>(false);
  const [iClick, setIClick] = useState<boolean>(false);
  const [sClick, setSClick] = useState<boolean>(false);
  const [nClick, setNClick] = useState<boolean>(false);
  const [fClick, setFClick] = useState<boolean>(false);
  const [tClick, setTClick] = useState<boolean>(false);
  const [jClick, setJClick] = useState<boolean>(false);
  const [pClick, setPClick] = useState<boolean>(false);

  const [mbti, setMbti] = useState<{
    ei?: string;
    sn?: string;
    ft?: string;
    jp?: string;
  }>({ ei: "", sn: "", ft: "", jp: "" });

  const handleClick = (e: React.MouseEvent<HTMLInputElement>) => {
    const m = e.currentTarget.value;
    if (m === "E" || m === "I") {
      setMbti({ ...mbti, ei: m });
    } else if (m === "S" || m === "N") {
      setMbti({ ...mbti, sn: m });
    } else if (m === "F" || m === "T") {
      setMbti({ ...mbti, ft: m });
    } else {
      setMbti({ ...mbti, jp: m });
    }

    //EI
    if (m === "E") {
      setEClick((prev) => !prev);
      setIClick(false);
    } else if (m === "I") {
      setIClick((prev) => !prev);
      setEClick(false);
    } else if (m === "S") {
      setSClick((prev) => !prev);
      setNClick(false);
    } else if (m === "N") {
      setNClick((prev) => !prev);
      setSClick(false);
    } else if (m === "F") {
      setFClick((prev) => !prev);
      setTClick(false);
    } else if (m === "T") {
      setTClick((prev) => !prev);
      setFClick(false);
    } else if (m === "J") {
      setJClick((prev) => !prev);
      setPClick(false);
    } else if (m === "P") {
      setPClick((prev) => !prev);
      setJClick(false);
    }
  };

  useEffect(() => {
    if (
      (eClick || (iClick && mbti.ei !== "")) &&
      (sClick || (nClick && mbti.sn !== "")) &&
      (fClick || (tClick && mbti.ft !== "")) &&
      (jClick || (pClick && mbti.jp !== ""))
    ) {
      dispatch(newUserMbti([mbti.ei!, mbti.sn!, mbti.ft!, mbti.jp!]));
    }
  }, [mbti]);

  return (
    <Fieldset>
      <OptionContainer>
        <div className="mbti__select__wrapper">
          <div className="select__wrapper">
            <label>
              <input
                type="radio"
                id="E"
                name="EI"
                value="E"
                checked={eClick}
                onClick={handleClick}
              />
              <div className="select box">E</div>
            </label>
            <label>
              <input
                type="radio"
                id="I"
                name="EI"
                value="I"
                checked={iClick}
                onClick={handleClick}
              />
              <div className="select box">I</div>
            </label>
          </div>
          <div className="select__wrapper">
            <label>
              <input
                type="radio"
                id="S"
                name="SN"
                value="S"
                checked={sClick}
                onClick={handleClick}
              />
              <div className="select box">S</div>
            </label>
            <label>
              <input
                type="radio"
                id="N"
                name="SN"
                value="N"
                checked={nClick}
                onClick={handleClick}
              />
              <div className="select box">N</div>
            </label>
          </div>
          <div className="select__wrapper">
            <label>
              <input
                type="radio"
                id="F"
                name="FT"
                value="F"
                checked={fClick}
                onClick={handleClick}
              />
              <div className="select box">F</div>
            </label>

            <label>
              <input
                type="radio"
                id="T"
                name="FT"
                value="T"
                checked={tClick}
                onClick={handleClick}
              />
              <div className="select box">T</div>
            </label>
          </div>
          <div className="select__wrapper">
            <label>
              <input
                type="radio"
                id="J"
                name="JP"
                value="J"
                checked={jClick}
                onClick={handleClick}
              />
              <div className="select box">J</div>
            </label>
            <label>
              <input
                type="radio"
                id="P"
                name="JP"
                value="P"
                checked={pClick}
                onClick={handleClick}
              />
              <div className="select box">P</div>
            </label>
          </div>
        </div>
      </OptionContainer>
    </Fieldset>
  );
};

export default SelectMbti;

const Fieldset = styled.div`
  display: flex;
  align-items: center;
  @media screen and (max-width: 480px) {
  }
`;

const OptionContainer = styled.div`
  display: grid;
  justify-content: center;
  justify-items: center;
  width: 30rem;
  padding: 0 0.5rem;
  li {
    width: 100%;
  }
  input {
    width: inherit;
    border: solid 1px #9b9a9a;
    font-size: 1.1rem;
    text-align: center;
    padding: 0.8rem 0;
    &:hover {
      cursor: pointer;
      transition: 0.3s;
    }
    @media screen and (max-width: 480px) {
      font-size: 1rem;
    }
  }
  .active,
  &:focus {
    border: solid 1px #000;
  }

  @media screen and (max-width: 480px) {
    gap: 0.5rem;
    width: 22rem;
  }
  .mbti__select__wrapper {
    display: flex;
    flex-direction: column;
  }

  .select__wrapper {
    display: flex;
    align-items: center;
    justify-content: space-around;
    width: 290px;
    height: 50px;
    background: rgba(255, 255, 255, 0.3);
    box-shadow: 0px 0px 6px 1px rgba(0, 0, 0, 0.25);
    border-radius: 30px;
    margin-top: 1.2rem;
    input[type="radio"] {
      display: none;
      &:checked {
        + .box {
          background: #000000;
          border-radius: 30px;
          color: #ffffff;
        }
      }
    }
    .select {
      width: 125px;
      height: 40px;
      cursor: pointer;
      transition: 0.3s;
      display: flex;
      text-align: center;
      justify-content: center;
      align-items: center;
    }
  }
`;