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;
}
}
`;