드디어 기나긴 기획과 디자인의 시간이 끝나고 개발의 시간이 찾아왔다. 우리 디자인의 대부분을 담당해준 뿡빵이님 체고,,, 8월 23일까지 내가 개발만 잘하면 엄청난 결과물을 만날 수 있지 않을까? 내가 맡은 부분은 다음과 같다.
- 공통 컴포넌트
- 버튼
- 헤더
- 모달
- 링크 (Next의 Link를 버튼 형태로 커스텀)
- 페이지
- 메인
- 항공권 검색
담당하는 페이지가 많아 보이지는 않지만 처음 사용해보는 외부 API "아마데우스"와 씨름을 해야 하기 하고, 아무래도 항공권 예약 사이트의 중요 부분을 맡다 보니 부담감이 상당하다,,ㅎㅎ 시간도 많이 소요될 것 같지만 그래도 열심히 해서 최대한 빨리 마무리하고 다른 팀원들을 도와야겠다 💪
- 매일매일 개발일지 작성하기 (오늘이 그 1일차)
- 테스팅 병행하기
앞서 세 번의 크고 작은 프로젝트를 진행해보니 기록이 무엇보다 중요하다는 것을 뼈저리게 느꼈다. 개발 과정에서 어려웠던 점, 내가 스스로 해결한 문제들, 훌륭한 사람들이 남긴 블로그 기록을 통해 배운 점을 그날그날 기록해두면 나중에 돌아봤을 때 큰 자산이 될 수 있다는 것을 깨달았다. 짧은 기간이고 뒤로 갈수록 어려워지겠지만 하루 한 시간이라도 이렇게 기록하는 시간을 가져보려고 한다.
또한 테스트 주도 개발(Test Driven Development)이 현업에서 많이 사용된다는 것을 보고 우리도 한 번도 안 해본 TDD를 시도해보자! 라는 의견이 팀원들과 일치하여 Jest와 React Testing Library를 사용하여 테스팅도 해 보려고 한다. 이에 Next.js 환경에서 테스팅하는 방법들을 공부해 보았는데, DOM element를 체크하는 것부터 mock 데이터를 만들어 비동기 통신을 테스팅하는 것까지 방대한 내용이 있어 개발 과정에서 어떻게 병행하면 좋을까 고민이 깊다.
디자인 시안은 다음과 같다.

여러 페이지 및 컴포넌트에서 공통으로 사용할 수 있는 버튼을 개발하였다. 디자인에 따라 크기별 스타일별로 분류하여 작업을 진행했다. 모바일에서 사용하는 가장 작은 버튼부터 width가 100%인 버튼까지 총 5개의 크기로 분류하였으며, 4가지 스타일을 지정하여 버튼을 사용하는 곳에서 props를 통해 원하는 속성을 결정할 수 있게 하였다.
또한 <button type="submit">Submit 버튼</button>의 경우 Submit 컴포넌트를 생성하여 Button 컴포넌트의 속성을 그대로 사용할 수 있게 작업했다.
import "./Button.scss";
export interface ButtonProps
extends React.ButtonHTMLAttributes<HTMLButtonElement> {
children: React.ReactNode;
type?: "button" | "submit";
size?: "xs" | "sm" | "md" | "lg" | "full";
bgColor?: "primary" | "secondary" | "gray" | "light";
}
const Button: React.FC<ButtonProps> = ({
children,
type = "button",
size = "sm",
bgColor = "primary",
...rest
}) => {
return (
<button type={type} className={`button ${size} ${bgColor}`} {...rest}>
{children}
</button>
);
};
export default Button;
타입스크립트로 개발을 진행하는 만큼 전달받을 props에 대한 타입도 지정하였고, props를 넘겨주지 않았을 경우 default로 사용될 속성도 지정하였다.
Next.js에서 Link를 제공하는데 왜 또 만드냐? 버튼처럼 생긴 Link들이 필요한데 이를 공통으로 사용하기 위함이다. 생김새도 그렇고 버튼과 큰 차이가 없어서 거의 유사한 CSS 스타일을 지정했고, 가장 큰 차이는 Next.js의 Link는 html의 <a> 태그를 기반으로 만들어져서 <a> 태그에 스타일을 주었다는 점이다.
import Link from "next/link";
import "./Anchor.scss";
interface AnchorProps extends React.AnchorHTMLAttributes<HTMLAnchorElement> {
children: React.ReactNode;
href: string;
size?: "xs" | "sm" | "md" | "lg" | "full";
bgColor?: "primary" | "gray";
}
const Anchor: React.FC<AnchorProps> = ({
children,
size = "full",
bgColor = "primary",
href,
}) => {
return (
<Link className={`anchor ${size} ${bgColor}`} href={href}>
{children}
</Link>
);
};
export default Anchor;
Next.js의 Link와 이름이 중복되는 것을 막기 위해 Anchor라는 이름의 컴포넌트로 생성하였다.

우리의 헤더는 위와 같이 PC, 모바일에서 공통으로 사용하는 반응형 헤더이다. 또한 이번에 개발하는 헤더의 가장 큰 특징은 페이지 별로 배경색이 white, primary(orange), transparent로 다르다는 것이다. 따라서 우리는 루트 레이아웃에서 헤더를 지정하는 대신 라우팅 그룹 (folder)을 헤더에 따라 지정하는 방식을 택했고, 각각의 라우팅 그룹 내부에 있는 layout에서 헤더에 props로 type을 전달하여 스타일을 구분할 수 있게 개발하였다.
import Link from "next/link";
import "./Header.scss";
interface HeaderProps extends React.HTMLAttributes<HTMLDivElement> {
type?: "default" | "primary" | "transparent";
}
const Header: React.FC<HeaderProps> = ({ type = "default" }) => {
return (
<header className={`header ${type}Type`}>
<div className="layout header-contents">
<div className="header-logo">
<Link href={`/`}>
<img src={`img/logo-${type}.svg`} alt="TriFly" />
<h1 className="hidden">TriFly</h1>
</Link>
</div>
<nav className="header-nav">
<Link href={`/order`}>예약내역</Link>
<Link href={`/footprint`}>발자국</Link>
</nav>
<div className="header-user">
{/* {user ? (
<button type="button">
<img src={`img/icon-logout-${type === "default" ? "black" : "white"}.svg`} alt="로그아웃" />
<i className="hidden">로그아웃</i>
</button>
) : (
<Link href={`/login`}>
<img src={`img/icon-login-${type === "default" ? "black" : "white"}.svg`} alt="로그인" />
<i className="hidden">로그인</i>
</Link>
)} */}
<Link href={`/login`}>
<img
src={`img/icon-login-${type === "default" ? "black" : "white"}.svg`}
alt="로그인"
/>
<i className="hidden">로그인</i>
</Link>
</div>
<div className="corner">
<div className="left"></div>
<div className="right"></div>
</div>
</div>
</header>
);
};
export default Header;
[결과물]
![]() | ![]() | ![]() |
|---|
이번에 헤더를 작업하면서 접근성, 반응형에 대해 우리 팀 전문가 소짱님께 여러모로 배울 수 있었다.

접근성 고려를 위해 우리는 헤더에 있는 페이지 로고에 h1 태그를 사용하고 이를 화면에서는 보이지 않게 숨기기로 했고, 내부 컨텐츠는 h2부터 사용하여 각각 어떤 부분인지 설명하기로 했다. Chrome에서 확인하기 위해서는 HeadingsMap이라는 확장 프로그램을 설치하면 된다.
clamp라는 CSS에서 사용하는 함수를 처음 사용해보았다. clamp(min, value, max) 형태로 생긴 함수로, 반응형에 따라 value의 크기가 줄어들거나 늘어날 때 min 값 이하로는 줄어들지 않고, max 값 이상으로는 늘어나지 않게 하는 역할을 수행한다. 이 함수를 헤더에서 네비게이션 역할을 하는 '예약내역', '발자국' 링크들 사이의 간격을 조절하기 위해 사용했다. (10vw는 viewport width의 10%을 의미한다!)
![]() | ![]() |
|---|
Modal은 아직 작업 중이므로 작업 중인 화면만 공유하고 마무리한다! 내일 개발 일지에서 계속...
캡숑짱이네요~