> For the complete documentation index, see [llms.txt](https://frontend-developer.quantit.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://frontend-developer.quantit.io/readme.md).

# Frontend Developer 과제

{% hint style="danger" %}
본 과제는 (주)퀀팃의 저작권 보호를 받습니다. 이 과제는 오직 퀀팃의 채용 목적으로만 사용해야 합니다.\
과제의 전체 또는 일부를 공개, 게시, 배포하거나 제3자에게 제공하는 행위는 저작권법에 의해 금지되며, 민형사상 책임이 따를 수 있습니다. 여기에는 과제의 문구를 변형하여 내용을 유추할 수 있게 하는 경우도 포함됩니다.
{% endhint %}

***

## 과제전 사전 설정

### 과제 파일 다운로드

아래 과제 파일을 클릭해서 다운로드 해주세요

{% file src="/files/GzTb6pxY3Dyh5FQIQCxJ" %}
과제 파일
{% endfile %}

### Github 원격 저장소 만들기

1. <https://github.com/new> 에 접속해서, 아래 설명에 따라 Repository를 만들어 주세요.

   1. 레포지토리 이름:`quantit-fe-assignment`
   2. 공개 설정 여부: `Private`

   <figure><img src="https://1440826789-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fk31xTwUXxKiJCx9Y6v1c%2Fuploads%2FuwYraKZCyuIgHgK9wej1%2F%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202024-08-01%20%E1%84%8B%E1%85%A9%E1%84%8C%E1%85%A5%E1%86%AB%202.44.58.png?alt=media&amp;token=f75801ba-b87b-48cf-88c8-9c386cbe1c32" alt=""><figcaption><p>레포지토리 생성 예시</p></figcaption></figure>
2. \[Settings] > \[Collaborators]로 페이지를 이동하고, 중앙의 \[Add people] 를 클릭해 주세요.

   1. Collaborator 추가 페이지로 이동합니다.

   <figure><img src="https://1440826789-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fk31xTwUXxKiJCx9Y6v1c%2Fuploads%2F6vdoByMcaBsEzTHLNLAE%2F%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202024-08-01%20%E1%84%8B%E1%85%A9%E1%84%8C%E1%85%A5%E1%86%AB%202.58.26.png?alt=media&amp;token=9b78d627-bfa3-413f-9b89-41ac0360303b" alt=""><figcaption><p>collaborater 추가 페이지 이동 및 버튼 클릭</p></figcaption></figure>
3. 검색창에 `quantit-tech`을 입력하고, collaborater로 추가해주세요.

   1. 초대가 반드시 되어야 합니다. 초대가 되지 않으면 과제 검토를 할 수 없어 제출하지 않은것으로 간주 됩니다

   <figure><img src="https://1440826789-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fk31xTwUXxKiJCx9Y6v1c%2Fuploads%2Fgit-blob-7220091cad12813f4b4bbb983feb923bb6789bdf%2Fadd_collaborator.png?alt=media" alt=""><figcaption><p>collaborater 추가 검색 및 선택</p></figcaption></figure>
4. 이어서 레포지토리 화면에서 \[Settings] > \[Actions] > \[General] 로 이동합니다.\
   \[Workflow permissions] > \[Read and Write permissions] 를 선택한 뒤, \[Save] 버튼으로 저장해주세요.

   1. CI 동작을 위해서 필요한 권한이고, CI는 과제 검토를 위해 필수적으로 동작해야 합니다.

   <figure><img src="https://1440826789-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fk31xTwUXxKiJCx9Y6v1c%2Fuploads%2Fgit-blob-619f43c21bf3184f2cb0e90c85fc007a2a0abeff%2Fworkflow_permissions.png?alt=media" alt=""><figcaption><p>CI 권한 설정</p></figcaption></figure>
5. 다운로드한 zip파일을 압축해제 한 뒤 GitHub 저장소로 최초 커밋을 남겨서 origin에 push해주세요.

   1. 먼저 작업할 디렉토리로 이동한 뒤, 아래 명령어를 차례로 실행해주세요.

   ```
   git init
   git remote add origin <GitHub Repository URL>
   git branch -M main
   git add .
   git commit -m 'initial commit'
   git push -u origin main
   ```
6. 과제물은 `assignment` 브랜치에서 작업한 뒤 Pull Request를 생성해서 과제를 제출해주세요.

   1. [제출 방법](#제출-방법)을 참고해주세요.

   ```
   git switch main && git switch -c assignment
   ```

### 로컬에서 실행하기

1. 필요한 패키지를 설치합니다.

   ```
   yarn install
   ```
2. 로컬 서버 실행을 해주세요.

   ```
   yarn start
   ```
3. 브라우저에서 `http://localhost:3000`으로 접속하면 결과물을 확인할 수 있습니다.

***

## 과제 시작전에 주의사항

과제를 시작하기 전에 아래 사항을 반드시 확인해주세요.

* **과제는 시작하신 후 4시간 안에 Pull Request를 제출해 주셔야 합니다.**
  * 마감 시간 이후에 제출된 Pull Request는 부정행위로 간주하고, 자동으로 과제 검토 프로세스가 진행되지 않습니다.
* **마감 시간 이후에 추가 git commit을 남기지 않도록 주의가 필요합니다.**
  * 과제를 제출하신 후 **추가 커밋이 있는 경우에는 부정행위로 간주합니다**. 이러한 경우 자동으로 과제 검토 프로세스가 진행되지 않습니다.
* **마감시간 까지 과제를 완성하지 못해도, 그 시점까지 작성된 내용을 Pull Request로 제출합니다.**
  * 제한된 시간 안에 과제를 완성하는 것은 매우 어려운 일임을 알고 있습니다. 또한 제한 시간이 있는 환경에서는 평소만큼 실력 발휘를 못 하셨을 수 있음을 충분히 이해하고 있습니다. 따라서, 마감 시간까지 작성된 내용을 제출해주시면 됩니다.
* **테스트 코드로 기본적인 과제의 요구조건들을 테스트합니다.**
  * 테스트 코드는 `yarn test`로 실행할 수 있습니다.
  * 테스트를 통과하지 못한 경우, 테스트를 통과할 수 있도록 코드를 수정하시면 됩니다.
  * 추가 설치한 라이브러리로 인해 기존 테스트코드가 동작하지 않는 경우는 테스트 환경 설정을 수정해서 테스트가 원할하게 작동할 수 있도록 해주시면 됩니다.
  * 개별 테스트케이스는 **절대** 수정하지 마십시오.

### FAQ

<details>

<summary>Q. 과제를 제출하면 어떻게 검토가 진행되나요?</summary>

과제는 자동으로 검토가 진행됩니다. 과제의 검토는 아래의 순서로 진행됩니다.

1. 과제 제출 시, 자동으로 CI가 동작합니다.
2. CI가 성공하면, 과제는 자동으로 검토가 진행됩니다.

</details>

<details>

<summary>Q. 과제를 제출하면 어떻게 결과를 확인할 수 있나요?</summary>

과제의 결과는 GitHub의 Pull Request 페이지에서 확인할 수 있습니다.

</details>

<details>

<summary>Q. 대응해야하는 브라우저 범위는 어떻게 해야하나요?</summary>

최신 버전의 크롬 브라우저에서 정상적으로 동작하면 됩니다.

</details>

<details>

<summary>Q. UI 구현을 위한 정보(ex CSS)는 어디서 확인 할 수 있나요?</summary>

기능 구현에 초점을 맞춰서 작업을 진행 하시면 됩니다.\
디자인은 src/components, src/container 안에 있는 컴포넌트들을 활용하시면 됩니다.\
현 과제에서는 디자인에 대한 검토는 따로 하지 않으며, 구현하신 UI가 캡쳐화면이랑 조금 어긋나는 것은 평가에 영향을 주지 않습니다.

</details>

<details>

<summary>Q. 반응형으로 구현해야 하나요?</summary>

모바일 사이즈 기준으로만 대응해서 구현하시면 됩니다.

</details>

<details>

<summary>Q. 추가 라이브러리 설치해서 사용 가능한가요?</summary>

네 가능합니다. 다만 라이브러리를 사용해서 테스터 케이스가 실패하는 경우, \*.spec.tx안의 테스트 코드를 수정하진 마시고 그냥 테스트가 실패하는 것으로 제출해주세요. 그리고 해당 내용을 PR에 기재해주세요. (wrapper, hooks, utils 등의 코드는 수정 가능합니다.)

</details>

{% hint style="info" %}
제공받은 과제의 코드에서 오류를 발견했을시, 수정해서 해결할 수 있는 오류라면 직접 수정하신 후 Pull Reqeust에 내용을 기재주십시오.

그 외 문의 사항은 퀀팃 개발(<dev@quantit.io>)으로 이메일을 보내주세요.
{% endhint %}

***

## 과제 문제

이 과제의 목표는 모의 연금 투자기능을 구현하는 것입니다.\
아래 세부 요구사항들을 만족하는 프로젝트를 구현해주세요.

### 목표1. 홈 화면을 구현해 주세요.

#### 1-1. 투자 요약 API 호출 결과를 화면에 보여주세요.

{% tabs %}
{% tab title="요구사항" %}

* API 호출은 **`src/pages/api.ts`** 의 **`getInvestSummary()`** 함수를 활용해면 됩니다.
  {% endtab %}

{% tab title="예시 화면" %}

<figure><img src="https://1440826789-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fk31xTwUXxKiJCx9Y6v1c%2Fuploads%2Fgit-blob-d6d48d1654e515f6584b06fb8378df90ec09bb12%2F1-1.png?alt=media" alt="" width="375"><figcaption><p>투자 성과 요약 예시 화면</p></figcaption></figure>
{% endtab %}
{% endtabs %}

#### 1-2. 투자 계약 리스트 API 호출 결과를 화면에 보여주세요.

{% tabs %}
{% tab title="요구사항" %}

* API 호출은 **`src/pages/api.ts`** 의 **`getContractList()`** 함수를 활용해면 됩니다.
* 투자 상태가 \*\*`STOP`\*\*인 경우는 화면에 보여주지 않습니다.
* 리스트 영역 하단에 **`모의투자(연금) 계좌 추가하기`** 버튼을 만들어주세요.
  * 버튼 클릭 시, **`/product-select`** 페이지로 이동합니다.
  * router는 **`hooks/router.ts`** 의 **`useInternalRouter`** 함수를 활용해주세요.

{% hint style="danger" %}
이 API는 간헐적으로 HTTP Status 500 에러가 발생할 수 있습니다. 에러는 자유롭게 처리해 주세요.
{% endhint %}
{% endtab %}

{% tab title="예시 화면" %}

<figure><img src="https://1440826789-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fk31xTwUXxKiJCx9Y6v1c%2Fuploads%2Fgit-blob-7b21aa3c31f7bd7ad9f5971cd65cbc2b9f33c1a7%2F1-2.png?alt=media" alt="" width="375"><figcaption><p>투자 계좌 리스트 예시 화면</p></figcaption></figure>
{% endtab %}
{% endtabs %}

### 목표2. 투자 모델을 선택하는 화면을 구현해주세요.

#### 2-1. 투자 가능한 모델 리스트를 화면에 보여주세요.

{% tabs %}
{% tab title="요구사항" %}

* API 호출은 **`src/pages/api.ts`** 의 **`getInvestableProducts()`** 함수를 활용해면 됩니다.
* 투자가 불가능한 상품은 버튼을 비활성화 시켜주세요.
* 모델 Row는 **`InvestableProductCard`** 컴포넌트를 활용해주세요.
  {% endtab %}

{% tab title="예시 화면" %}

<figure><img src="https://1440826789-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fk31xTwUXxKiJCx9Y6v1c%2Fuploads%2Fgit-blob-16e5c0d70a9b7c3424e1555a7c3272bab5e29e6a%2F2-1.png?alt=media" alt="" width="375"><figcaption><p>투자 모델 선택 화면 예시</p></figcaption></figure>
{% endtab %}
{% endtabs %}

#### 2-2. 투자 모델을 선택하면 다음 버튼이 활성화 되게 해주세요.

{% tabs %}
{% tab title="요구사항" %}

* 투자 가능한 상품이 선택되면 다음 버튼이 활성화 됩니다.
  * 다음 버튼이 활성화 되지 않은 경우, 클릭해도 아무런 동작을 하지 않아야 합니다.
* 투자 불가능한 상품은 비활성화 되어 선택해도 아무런 동작을 하지 않아야 합니다.
* 다음 버튼을 클릭하면 **`/account-form`** 페이지로 이동합니다.
  * router는 **`hooks/router.ts`** 의 **`useInternalRouter`** 함수를 활용해주세요.
    {% endtab %}

{% tab title="예시 화면" %}

<figure><img src="https://1440826789-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fk31xTwUXxKiJCx9Y6v1c%2Fuploads%2Fgit-blob-b7323decc9326c67e47be45f3a5d1d99793b95a5%2F2-2.png?alt=media" alt="" width="375"><figcaption><p>투자 모델 선택시 화면 예시</p></figcaption></figure>
{% endtab %}
{% endtabs %}

### 목표3. 연금저축계좌의 연 납입한도와 계약기간을 지정해주세요.

#### 3-1. 연금저축계좌의 연 납입한도를 조회해서 화면에 보여주세요.

{% tabs %}
{% tab title="요구사항" %}

* 연금저축계좌의 연 납입한도는 **`src/pages/api.ts`** 의 **`getLimitAmount()`** 함수를 활용해주세요.
  {% endtab %}

{% tab title="예시 화면" %}

<figure><img src="https://1440826789-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fk31xTwUXxKiJCx9Y6v1c%2Fuploads%2Fgit-blob-a2b0bf2e6c748335beb6e97833113869e93a30eb%2F3-1.png?alt=media" alt="" width="375"><figcaption><p>연금저축계좌 연 납입한도 조회 화면 예시</p></figcaption></figure>
{% endtab %}
{% endtabs %}

#### 3-2. 연금저축계좌의 연 납입한도를 입력받아주세요.

{% tabs %}
{% tab title="요구사항" %}

* 연금저축계좌의 연 납입한도를 입력받아주세요.
* 금액은 0이상 연 납입한도 이내의 금액만 입력 가능합니다.
  * 입력한 금액은 3자리마다 콤마(,)를 붙여주세요.
  * 0을 입력한 경우 빈 문자열로 처리해주세요.
* 입력한 금액이 연 납입한도를 초과하면 **`연 납입 한도를 초과하였습니다.`** 라는 경고 메시지를 보여주세요.
  {% endtab %}

{% tab title="예시 화면" %}

<figure><img src="https://1440826789-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fk31xTwUXxKiJCx9Y6v1c%2Fuploads%2Fgit-blob-c8944c938d0934c62d79fbfc66e79a2a2c0e0d47%2F3-2-ok.png?alt=media" alt="" width="375"><figcaption><p>연금저축계좌 연 납입한도 입력 화면 예시</p></figcaption></figure>
{% endtab %}

{% tab title="에러 예시 화면" %}

<figure><img src="https://1440826789-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fk31xTwUXxKiJCx9Y6v1c%2Fuploads%2Fgit-blob-55c2226fd66d2b4df9163d2e99f9658451872867%2F3-2-error.png?alt=media" alt="" width="375"><figcaption><p>연금저축계좌 연 납입한도 입력 에러 예시</p></figcaption></figure>
{% endtab %}
{% endtabs %}

#### 3-3. 연금저축계좌의 계약기간을 입력받아주세요.

{% tabs %}
{% tab title="요구사항" %}

* 연금저축계좌의 계약기간을 입력받아주세요.
  * 계약기간은 60개월 이상 110개월 이하만 입력 가능합니다.
* 입력한 계약기간이 범위를 벗어나면 **`최소 60개월부터 최대 110개월까지 입력할 수 있어요.`** 라는 경고 메시지를 보여주세요.
  {% endtab %}

{% tab title="예시 화면" %}

<figure><img src="https://1440826789-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fk31xTwUXxKiJCx9Y6v1c%2Fuploads%2Fgit-blob-d5966ac9e34d79f0414c125546573fa9e09f55b3%2F3-3-ok.png?alt=media" alt="" width="375"><figcaption><p>연금저축계좌 계약기간 입력 화면 예시</p></figcaption></figure>
{% endtab %}

{% tab title="에러 예시 화면" %}

<figure><img src="https://1440826789-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fk31xTwUXxKiJCx9Y6v1c%2Fuploads%2Fgit-blob-e7c397e9e13eea1518a90584ca1b68f8c2319882%2F3-3-error.png?alt=media" alt="" width="375"><figcaption><p>연금저축계좌 계약기간 입력 에러 예시</p></figcaption></figure>
{% endtab %}
{% endtabs %}

#### 3-4. 모든 값을 입력하고 하단 체크박스를 체크하면 다음 버튼이 활성화 되게 해주세요.

{% tabs %}
{% tab title="요구사항" %}

* 연금저축계좌의 연 납입한도와 계약기간을 모두 입력하고, 하단 체크박스를 체크하면 다음 버튼이 활성화 됩니다.
  * 체크박스를 체크하지 않으면 다음 버튼이 활성화 되지 않습니다.
  * 입력 값중 하나라고 입력되어 있지 않거나, 에러가 발생한 경우 다음 버튼이 활성화 되지 않습니다.
* 다음 버튼을 클릭하면 **`/contract-confirm`** 페이지로 이동합니다.
  * router는 **`hooks/router.ts`** 의 **`useInternalRouter`** 함수를 활용해주세요.
    {% endtab %}

{% tab title="예시 화면" %}

<figure><img src="https://1440826789-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fk31xTwUXxKiJCx9Y6v1c%2Fuploads%2Fgit-blob-603c74dde649c4f0ca76f9d88714128d856685c8%2F3-4.png?alt=media" alt="" width="375"><figcaption><p>연금저축계좌 입력값 확인 화면 예시</p></figcaption></figure>
{% endtab %}
{% endtabs %}

### 목표4. 연금저축계좌의 계약을 확인하는 화면을 구현해주세요.

#### 4-1. 입력한 연금저축계좌의 정보를 화면에 보여주세요.

{% tabs %}
{% tab title="요구사항" %}

* 입력한 연금저축계좌의 정보를 화면에 보여주세요.
  {% endtab %}

{% tab title="예시 화면" %}

<figure><img src="https://1440826789-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fk31xTwUXxKiJCx9Y6v1c%2Fuploads%2Fgit-blob-8e79b246398e49cce60d99016354336a8d8a8d91%2F4-1.png?alt=media" alt="" width="375"><figcaption><p>연금저축계좌 계약 확인 화면 예시</p></figcaption></figure>
{% endtab %}
{% endtabs %}

#### 4-2. 하단 체크박스를 체크하면 다음 버튼이 활성화 되게 해주세요.

{% tabs %}
{% tab title="요구사항" %}

* 하단 체크박스를 체크하면 다음 버튼이 활성화 됩니다.
  * 체크박스를 체크하지 않으면 다음 버튼이 활성화 되지 않습니다.
    {% endtab %}

{% tab title="예시 화면" %}

<figure><img src="https://1440826789-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fk31xTwUXxKiJCx9Y6v1c%2Fuploads%2Fgit-blob-68b05f65cfc2f70549c1f05cf9bbb231036e6237%2F4-2.png?alt=media" alt="" width="375"><figcaption><p>연금저축계좌 계약 확인 화면 예시</p></figcaption></figure>
{% endtab %}
{% endtabs %}

#### 4-3. 다음 버튼을 클릭하면 계약이 완료되었다는 dialog를 보여주세요.

{% tabs %}
{% tab title="요구사항" %}

* 활성화된 다음 버튼을 클릭하면 계약이 완료되었다는 dialog를 보여주세요.
* dialog의 확인 버튼을 클릭하면 **`/`** 페이지로 이동합니다.
  * router는 **`hooks/router.ts`** 의 **`useInternalRouter`** 함수를 활용해주세요.
    {% endtab %}

{% tab title="예시 화면" %}

<figure><img src="https://1440826789-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fk31xTwUXxKiJCx9Y6v1c%2Fuploads%2Fgit-blob-8614f0796f6298cb2cd079811e375293b346d0be%2F4-3.png?alt=media" alt="" width="375"><figcaption><p>연금저축계좌 계약 완료 화면 예시</p></figcaption></figure>
{% endtab %}
{% endtabs %}

***

## 테스트 가이드

### 테스트 실행 방법

```
# 모든 테스트 실행
yarn test

# 특정 파일 테스트 실행
yarn test <파일명>

# 파일 변경 감지 모드로 테스트 실행
yarn test --watch

# 특정 테스트 실행하기
yarn test -t <테스트명>
```

***

## 제출 방법

{% hint style="info" %}
제한시간 안에 브랜치를 원격 저장소에 Push 해주세요.
{% endhint %}

1. 과제를 완료하신 후, **`assignment`** 브랜치에서 작업한 내용을 원격 저장소에 Push 해주세요.
2. GitHub 저장소에서 Pull Request를 생성해주세요. 저장소에 들어가면 아래와 같은 초록석 버튼이 보일 것입니다.

   <figure><img src="https://1440826789-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fk31xTwUXxKiJCx9Y6v1c%2Fuploads%2Fgit-blob-14bae123db3c931928031a47dbe34f655041904b%2Fpr_message.png?alt=media" alt=""><figcaption><p>Pull Request 생성 메세지</p></figcaption></figure>
3. **`[Compare & Pull Request]`** 버튼을 누르고 Pull Request를 생성해주세요. Pull Request의 제목이나 내용은 자유롭게 작성해주세요.

   1. 꼭 \*\*`quantit-tech`\*\*을 리뷰어로 지정해주세요.

   <figure><img src="https://1440826789-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fk31xTwUXxKiJCx9Y6v1c%2Fuploads%2Fgit-blob-71a924bf0d5d0dade3a74ba0819b60141a40e63e%2Fpr_request.png?alt=media" alt=""><figcaption></figcaption></figure>
4. Pull Request가 생성되면, **`Github Action`** 을 활용해 자동으로 과제 검토가 진행됩니다.
