# 1ヶ月カレンダーの作成3

次に、カレンダーページをリファクタします。

まずカレンダーの曜日部分を切り出しましょう。

`organisms`配下に`CalendarHeader.tsx`を作成しましょう。

その中にtheadタグの要素を移行しましょう。

<pre class="language-tsx" data-title="organisms/CalendarHeader.tsx◎"><code class="lang-tsx"><strong>import { DAYS_LIST } from "../../constants/calendar";
</strong><strong>
</strong><strong>export const CalendarHeader = () => {
</strong><strong>  return (
</strong><strong>    &#x3C;thead>
</strong><strong>      &#x3C;tr className="bg-lime-800 text-white rounded-tl-lg rounded-tr-lg py-10">
</strong><strong>        {DAYS_LIST.map((day) => (
</strong><strong>          &#x3C;th key={day} className="text-center text-xl py-3">
</strong><strong>            {day}
</strong><strong>          &#x3C;/th>
</strong><strong>        ))}
</strong><strong>      &#x3C;/tr>
</strong><strong>    &#x3C;/thead>
</strong><strong>  );
</strong><strong>}
</strong></code></pre>

次に日付部分を切り出しましょう。

`organisms`配下に`CalendarBody.tsx`を作成しましょう。

その中にtbodyタグの要素を移行しましょう。propsとして、`currentDate`と`dateList`を受け取れるようにしましょう。

<pre class="language-tsx" data-title="organisms/CalendarBody.tsx◎"><code class="lang-tsx"><strong>import { getDate, isSameMonth, isToday } from "date-fns";
</strong><strong>
</strong><strong>type PropsType = {
</strong><strong>  currentDate: Date
</strong><strong>  dateList: Date[][]
</strong><strong>}
</strong><strong>
</strong><strong>export const CalendarBody = ({ currentDate, dateList }: PropsType) => {
</strong><strong>  const dateColor = (targetDate: Date, currentDate: Date): string => {
</strong><strong>    if (isToday(targetDate)) return "bg-lime-800 text-white rounded-full";
</strong><strong>    return isSameMonth(targetDate, currentDate)
</strong><strong>      ? "text-black"
</strong><strong>      : "text-gray-300";
</strong><strong>  };
</strong><strong>  
</strong><strong>  return (
</strong><strong>    &#x3C;tbody>
</strong><strong>      {dateList.map((oneWeek) => (
</strong><strong>        &#x3C;tr key={`week-${getDate(oneWeek[0])}`} className="mx-10">
</strong><strong>          {oneWeek.map((item) => (
</strong><strong>            &#x3C;td
</strong><strong>              key={`day-${getDate(oneWeek[0])}`}
</strong><strong>              className="bg-white h-[10vh] border-2 border-solid border-lime-800"
</strong><strong>            >
</strong><strong>              &#x3C;span
</strong><strong>                className={`inline-block w-[20px] leading-[20px] text-center ${dateColor(
</strong><strong>                  item,
</strong><strong>                  currentDate
</strong><strong>                )}`}
</strong><strong>              >
</strong><strong>                {getDate(item)}
</strong><strong>              &#x3C;/span>
</strong><strong>            &#x3C;/td>
</strong><strong>          ))}
</strong><strong>        &#x3C;/tr>
</strong><strong>      ))}
</strong><strong>    &#x3C;/tbody>
</strong><strong>  );
</strong><strong>}
</strong></code></pre>

また、`dateColor`の関数に関しても切り出します。

`src`配下に`libs`ディレクトリを作成し、その中に`date.ts`を作成しましょう。

{% code title="src/libs/date.ts◎" %}

```typescript
import { isSameMonth, isToday } from "date-fns"

export const dateColor = (targetDate: Date, currentDate: Date): string => {
  if (isToday(targetDate)) return "bg-lime-800 text-white rounded-full"
  return isSameMonth(targetDate, currentDate) ? "text-black" : "text-gray-300"
}
```

{% endcode %}

こちらを`CalendarBody.tsx`にて呼び出します。

<pre class="language-tsx" data-title="organisms/CalendarBody.tsx◎"><code class="lang-tsx">import { getDate } from "date-fns"
<strong>import { dateColor } from "../../libs/date"
</strong>
type PropsType = {
  currentDate: Date
  dateList: Date[][]
}

export const CalendarBody = ({ currentDate, dateList }: PropsType) => {
  return (
    &#x3C;tbody>
      {dateList.map((oneWeek) => (
        &#x3C;tr key={`week-${getDate(oneWeek[0])}`} className="mx-10">
          {oneWeek.map((item) => (
            &#x3C;td
              key={`day-${getDate(oneWeek[0])}`}
              className="bg-white h-[10vh] border-2 border-solid border-lime-800"
            >
              &#x3C;span
                className={`inline-block w-[20px] leading-[20px] text-center ${dateColor(
                  item,
                  currentDate
                )}`}
              >
                {getDate(item)}
              &#x3C;/span>
            &#x3C;/td>
          ))}
        &#x3C;/tr>
      ))}
    &#x3C;/tbody>
  )
}

</code></pre>

では、CalendarHeader.tsxとCalendarBody.tsxをCalendarPage.tsxにて呼び出しましょう。

<pre class="language-tsx" data-title="pages/CalendarPage.tsx◎"><code class="lang-tsx">import { eachDayOfInterval, eachWeekOfInterval, endOfMonth, endOfWeek, getMonth, startOfMonth } from "date-fns";
import { useEffect, useState } from "react";
<strong>import { CalendarHeader } from "../organisms/CalendarHeader";
</strong><strong>import { CalendarBody } from "../organisms/CalendarBody";
</strong>
export const CalendarPage = () => {
  const today = new Date()
  const [dateList, setDateList] = useState&#x3C;Date[][]>([]);

  useEffect(() => {
    const monthOfSundayList = eachWeekOfInterval({
      start: startOfMonth(today),
      end: endOfMonth(today),
    })
    const newDateList: Date[][] = monthOfSundayList.map((date) => {
      return eachDayOfInterval({
        start: date,
        end: endOfWeek(date),
      })
    })
    setDateList(newDateList)
  }, [])

  return (
    &#x3C;>
      &#x3C;h1 className=" font-bold text-3xl mb-5">{`${getMonth(today) + 1}月`}&#x3C;/h1>
      &#x3C;table className="w-[80%] border-collapse border-2 border-solid border-lime-800 table-fixed">
<strong>        &#x3C;CalendarHeader />
</strong><strong>        &#x3C;CalendarBody currentDate={today} dateList={dateList} />
</strong>      &#x3C;/table>
    &#x3C;/>
  );
}

</code></pre>

ここまでの作業をcommitしましょう。

```bash
git add .
```

```bash
git commit
```

commitメッセージは

```
refactor: カレンダーページをheaderとbodyのcomponentに切り出した
```

としましょう。

では1ヶ月カレンダーの実装が完了したので、GitHubにpushしましょう。

```basic
git push origin feature/calendar-page
```

これでGitHubのリポジトリのページにいき、main <- feature/calendar-pageのPRを作成しましょう。

PRのタイトルは

```
feat: カレンダーページを作成
```

としましょう。

作成したら自身で`Merge pull request`を押してmergeしましょう。

mergeが完了したらWarpに戻り、mainをpullしましょう。

```bash
git switch main
```

```bash
git pull origin main
```
