# 予定詳細機能

次にカレンダーの一つの予定をクリックした際に、予定詳細のモーダルを表示するようにします。

`feature/schedule-detail`にて作業します。

```bash
git switch -c feature/schedule-detail
```

`organisms`に`ScheduleDetailModal.tsx`を作成しましょう。propsとして、`selectedSchedule`を受け取れるようにし、`selectedSchedule`は`Schedule型`か`null`とします。また`Modal`に必要な`closeModal`を受け取ります。

`Modal`の`isOpen`は`!!selectedSchedule`とすることで、`selectedSchedule`が`null`以外の場合はtrueとなります。

<pre class="language-tsx" data-title="organisms/ScheduleDetailModal.tsx◎"><code class="lang-tsx"><strong>import Modal from "react-modal";
</strong><strong>import { Schedule } from "../../types/calendar";
</strong><strong>
</strong><strong>type PropsType = {
</strong><strong>  selectedSchedule: Schedule | null
</strong><strong>  closeModal: () => void
</strong><strong>};
</strong><strong>
</strong><strong>const customStyles = {
</strong><strong>  content: {
</strong><strong>    top: "50%",
</strong><strong>    left: "50%",
</strong><strong>    width: "30%",
</strong><strong>    transform: "translate(-50%, -50%)",
</strong><strong>  },
</strong><strong>}
</strong><strong>
</strong><strong>export const ScheduleDetailModal = ({
</strong><strong>  selectedSchedule,
</strong><strong>  closeModal,
</strong><strong>}: PropsType) => {
</strong><strong>  return (
</strong><strong>    &#x3C;Modal
</strong><strong>      isOpen={!!selectedSchedule}
</strong><strong>      style={customStyles}
</strong><strong>      onRequestClose={closeModal}
</strong><strong>    >
</strong><strong>    &#x3C;/Modal>
</strong><strong>  )
</strong><strong>}
</strong></code></pre>

表示する内容としては、`selectedSchedule`の内容を表示します。`selectedSchedule`を表示する際に`null`を許容しているので、`{selectedSchedule &&`として`null`チェックをする必要があります。日付に関しては、`format`を使用して表示します。

<pre class="language-tsx" data-title="organisms/ScheduleDetailModal.tsx◎"><code class="lang-tsx">import Modal from "react-modal";
import { Schedule } from "../../types/calendar";
<strong>import { format } from "date-fns";
</strong>
type PropsType = {
  selectedSchedule: Schedule | null;
  closeModal: () => void;
};

const customStyles = {
  content: {
    top: "50%",
    left: "50%",
    width: "30%",
    transform: "translate(-50%, -50%)",
  },
};

export const ScheduleDetailModal = ({ selectedSchedule, closeModal }: PropsType) => {
  return (
    &#x3C;Modal
      isOpen={!!selectedSchedule}
      style={customStyles}
      onRequestClose={closeModal}
    >
<strong>      {selectedSchedule &#x26;&#x26; (
</strong><strong>        &#x3C;div className="flex flex-col gap-8">
</strong><strong>          &#x3C;h3 className="text-center text-3xl text-lime-800 font-bold pb-5">
</strong><strong>            {selectedSchedule.title}
</strong><strong>          &#x3C;/h3>
</strong><strong>          &#x3C;p>{format(selectedSchedule.date, "yyyy年M月d日")}&#x3C;/p>
</strong><strong>          &#x3C;p>{selectedSchedule.description}&#x3C;/p>
</strong><strong>        &#x3C;/div>
</strong><strong>      )}
</strong>    &#x3C;/Modal>
  );
};
</code></pre>

こちらを`CalendarBody.tsx`にて呼び出しましょう。`selectedSchedule`というstateを定義し、`closeModal`という関数も定義し、propsとして渡します。

<pre class="language-tsx" data-title="organisms/CalendarBody.tsx◎"><code class="lang-tsx">import { useState } from "react"
import { getDate } from "date-fns"
import { dateColor } from "../../libs/date"
<strong>import { DateList, Schedule } from "../../types/calendar"
</strong>import { ScheduleBtn } from "../atoms/ScheduleBtn"
<strong>import { ScheduleDetailModal } from "./ScheduleDetailModal"
</strong>
type PropsType = {
  currentDate: Date
  dateList: DateList
};

export const CalendarBody = ({ currentDate, dateList }: PropsType) => {
<strong>  const [selectedSchedule, setSelectedSchedule] = useState&#x3C;Schedule | null>(
</strong><strong>    null
</strong><strong>  )
</strong><strong>  const closeModal = () => setSelectedSchedule(null)
</strong>
  return (
<strong>    &#x3C;>
</strong>      &#x3C;tbody>
        {dateList.map((oneWeek) => (
          &#x3C;tr key={`week-${getDate(oneWeek[0].date)}`} className="mx-10">
            {oneWeek.map((item) => (
              &#x3C;td
                key={`day-${getDate(oneWeek[0].date)}`}
                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.date,
                    currentDate
                  )}`}
                >
                  {getDate(item.date)}
                &#x3C;/span>
                &#x3C;div className="flex flex-col items-center gap-1 pb-2">
                  {item.schedules.map((schedule) => (
                    &#x3C;ScheduleBtn key={schedule.id}>
                      {schedule.title}
                    &#x3C;/ScheduleBtn>
                  ))}
                &#x3C;/div>
              &#x3C;/td>
            ))}
          &#x3C;/tr>
        ))}
      &#x3C;/tbody>
<strong>      &#x3C;ScheduleDetailModal selectedSchedule={selectedSchedule} closeModal={closeModal} />
</strong><strong>    &#x3C;/>
</strong>  )
}
</code></pre>

そして、対象の予定をクリックした際に、`selectedSchedule`に対象の`schedule`を格納するため、`ScheduleBtn`にて`onClick`を受け取れるようにして、関数を渡しましょう。

<pre class="language-tsx" data-title="atoms/ScheduleBtn.tsx◎"><code class="lang-tsx">import { ReactNode } from "react";

type PropsType = {
  children: ReactNode;
<strong>  onClick: () => void
</strong>};

<strong>export const ScheduleBtn = ({ children, onClick }: PropsType) => {
</strong>  return (
<strong>    &#x3C;button className="block bg-lime-800 text-white rounded-sm w-[94%] px-2" onClick={onClick}>
</strong>      {children}
    &#x3C;/button>
  );
};

</code></pre>

<pre class="language-tsx" data-title="organisms/CalendarBody.tsx◎"><code class="lang-tsx">...
                 {item.schedules.map((schedule) => (
<strong>                    &#x3C;ScheduleBtn key={schedule.id} onClick={() => setSelectedSchedule(schedule)}>
</strong>                      {schedule.title}
                    &#x3C;/ScheduleBtn>
                  ))}
...
</code></pre>

これで、予定をクリックした際に予定詳細のモーダルが表示されるようになったかと思います。

<figure><img src="https://1869761657-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FcUBbYqol4PMzZJggiMqV%2Fuploads%2F8RCaFQwZQu2rM8pN4tag%2F10a.png?alt=media&#x26;token=f0a8ef23-225e-4ed8-83dd-e3732ab77807" alt=""><figcaption></figcaption></figure>

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

```bash
git add .
```

```bash
git commit
```

commitメッセージは

```
feat: 予定詳細モーダルを作成
```

としましょう。

では予定詳細機能の実装が完了したので、GitHubにpushしましょう。

```basic
git push origin feature/schedule-detail
```

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

PRのタイトルは

```
feat: 予定詳細モーダルを作成
```

としましょう。

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

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

```bash
git switch main
```

```bash
git pull origin main
```
