원티드 X 코드스테이츠 프리온보딩 프론트엔드 과정 기업과제 7번
담당했던 부분 : 생성한 폼 목록 페이지 / 입력된 데이터 목록 페이지 작성
✨ 주요 기능
별 거 아닌 부분이기는 하지만 이번 프로젝트에서는 버튼을 만들 때 가장 신경을 쓴 것 같다.
pure css이지만... 어쨌든 이번 기회에 이것저것 만져보면서 transform에 대해 조금 이해도를 높인 것 같다.
또 다른 부분은, 타입스크립트를 사용했던 부분이었는데 솔직히 이해는 잘 못 했고 팀원들의 도움을 많이 받아서 코스가 끝나면 혼자서 좀 공부를 해봐야 할 것 같다.
셋팅부터 좀 어려웠던 지점이 있어서 시간이 많이 걸렸다.
import React from "react";
import styled from "styled-components";
import { useRouter } from "next/router";
const Header = () => {
const router = useRouter();
return (
<>
<HeaderWrapper>
<LogoName
onClick={() => {
router.push("/");
}}
>
datable
</LogoName>
<CreateFormBtn
onClick={() => {
router.push("/forms");
}}
/>
</HeaderWrapper>
</>
);
};
const HeaderWrapper = styled.div`
display: flex;
flex-direction: row;
justify-content: space-around;
`;
const LogoName = styled.div`
font-size: 7rem;
font-weight: 700;
padding: 3rem;
width: 50rem;
height: 10rem;
text-align: center;
font-family: "Ubuntu", sans-serif;
cursor: pointer;
`;
const CreateFormBtn = styled.button`
position: relative;
display: inline-flex;
width: 150px;
height: 55px;
margin: 45px 115px 35px 35px;
perspective: none;
font-size: 19px;
letter-spacing: 1px;
transform-style: preserve-3d;
transform: translateZ(-25px);
transition: transform 0.25s;
font-family: "Montserrat", sans-serif;
:before,
:after {
position: absolute;
content: "CREATE FORM";
height: 55px;
width: 180px;
display: flex;
align-items: center;
justify-content: center;
border: 5px solid rgba(46, 124, 240);
box-sizing: border-box;
}
:before {
color: #fff;
background: rgba(46, 124, 240);
transform: rotateY(0deg) translateZ(25px);
}
:after {
color: rgba(46, 124, 240);
transform: rotateX(90deg) translateZ(25px);
}
:hover {
transform: translateZ(-25px) rotateX(-90deg);
}
`;
export default Header;
여기서 가장 고민했던 부분은 Data 스타일드 컴포넌트가 안에 들어간 정보의 양에 따라서 박스가 늘어났다가 줄어들었다 해야 하는 거였다.
분명 DataListWrapper가 display:flex로 설정이 되어 있고 그 위의 컴포넌트들 역시 모두 그렇게 설정되어 있었는데도 Data에 flex-grow:1을 주어도 아무 변화가 나타나지 않아서 인터넷을 뒤지고 자료를 찾아보고 그랬다.
그런데 어이없게도... min-height와 height가 설정되어 있어서 이 값을 먼저 받으니까 크기가 변하지 않았던 거여서 DataListWrapper에 있는 height 설정을 모두 지워주었더니 원하는대로 작동하게 되었다.
정말... 다 내가 잘못하는 거지 코드는 정직하구나...^^
import type { NextPage } from "next";
import { useRouter } from "next/router";
import styled from "styled-components";
import { FcTodoList } from "react-icons/fc";
import { useAppSelector, selectForm } from "redux/slice";
import Header from "components/Header";
import { Fragment, ReactElement } from "react";
const DataList: NextPage = () => {
const router = useRouter();
const { id } = router.query;
const i = Number(router.query["i"]);
const selectedForm = useAppSelector(selectForm).data.find((v) => v.id === id);
const showForms = () => {
const result = selectedForm!.dataList[i];
return Object.keys(result).map((v) => {
let value: ReactElement;
if (result[v].type === "agreement") {
value = (
<InputValue>{result[v].value ? "동의함" : "동의안함"}</InputValue>
);
} else if (result[v].type === "file") {
value = <Image src={result[v].value as string} alt="image" />;
} else {
value = <InputValue>{result[v].value}</InputValue>;
}
return (
<Fragment key={result[v].type}>
<TitleValue>
<FcTodoList size="2.5rem" style={{ marginRight: "15px" }} />
{v}
</TitleValue>
{value}
</Fragment>
);
});
};
const goPrev = () => {
if (i === 0) {
alert("첫 페이지입니다.");
return;
}
router.push(`/dataList/${id}/${i - 1}`);
};
const goNext = () => {
if (i === selectedForm!.dataList.length - 1) {
alert("마지막 페이지입니다.");
return;
}
router.push(`/dataList/${id}/${i + 1}`);
};
return (
<>
<DataListWrapper>
<Header />
<Data>
{showForms()}
<PrevBtn onClick={goPrev} />
<NextBtn onClick={goNext} />
</Data>
</DataListWrapper>
</>
);
};
const DataListWrapper = styled.main`
min-width: 50rem;
max-width: 80rem;
border: solid 1px rgba(0, 0, 0, 0.2);
margin: 0 auto;
box-shadow: rgba(0, 0, 0, 0.35) 0px 5px 15px;
display: flex;
flex-direction: column;
`;
const Data = styled.div`
box-shadow: rgba(67, 71, 85, 0.27) 0px 0px 0.25em,
rgba(90, 125, 188, 0.05) 0px 0.25em 1em;
border-radius: 10px;
width: 80%;
margin: 4rem 0rem 2rem 0rem;
background-color: #f5f5f5;
position: relative;
left: 50%;
transform: translateX(-50%);
padding: 5% 10% 0% 10%;
flex-grow: 1;
overflow: scroll;
`;
const TitleValue = styled.div`
font-size: 2.5rem;
font-weight: 700;
margin: 0 0 2rem 3rem;
`;
const InputValue = styled.div`
background-color: white;
font-size: 2rem;
margin: 1rem 0 2rem 0;
min-height: 5rem;
border-radius: 0.5rem;
border: 1px solid gray;
padding: 0.2rem 0.2rem 0.2rem 3rem;
line-height: 5rem;
overflow: auto;
`;
const Image = styled.img`
width: 100%;
height: 100%;
object-fit: cover;
`;
const PrevBtn = styled.button`
position: relative;
display: inline-flex;
width: 150px;
height: 55px;
margin: 45px 35px 35px 35px;
perspective: none;
font-size: 19px;
letter-spacing: 1px;
transform-style: preserve-3d;
transform: translateZ(-25px);
transition: transform 0.25s;
font-family: "Montserrat", sans-serif;
:before,
:after {
position: absolute;
content: "PREV";
height: 55px;
width: 180px;
display: flex;
align-items: center;
justify-content: center;
border: 5px solid rgba(46, 124, 240);
box-sizing: border-box;
}
:before {
color: #fff;
background: rgba(46, 124, 240);
transform: rotateY(0deg) translateZ(25px);
}
:after {
color: rgba(46, 124, 240);
transform: rotateX(90deg) translateZ(25px);
}
:hover {
transform: translateZ(-25px) rotateX(-90deg);
}
`;
const NextBtn = styled(PrevBtn)`
:before,
:after {
content: "NEXT";
}
`;
export default DataList;