Next.jsサイトでのFullCalendarカスタマイズ
前回インストールしたFullCalendarに、祝日とか表示させたり、
イベント情報を表示させたりします!
祝日の表示
ググると、よくあるのはGoogleカレンダーAPIから祝日データをゲットしよう。
というものだけど、GoogleカレンダーのAPIの取得がよく分からない。
Googleってよく画面とか変更するからなぁ・・・
しばらくこれで悩んでおりましたが、面倒なので辞めました。
ググってる中で、Holidays JP APIというのを発見!
これを利用することにしました。
URL
https://holidays-jp.github.io/api/v1/date.json
見てみますと、
{
"2017-01-01": "元日",
"2017-01-02": "元日 振替休日",
"2017-01-09": "成人の日"
}
こんな感じのJSONデータです。
イベント情報
これは前回ちょっと書きましたが、
microCMSで入力したデータをAPIで持ってきます。
page/cal.js(カレンダー表示ページ)の全コードです。
import Layout from '../components/layout'
import Link from 'next/link'
import FullCalendar from "@fullcalendar/react";
import dayGridPlugin from "@fullcalendar/daygrid";
import '@fullcalendar/common/main.css'
import '@fullcalendar/daygrid/main.css'
export default function Callendar({ events, holidaysData }) {
const allevents = events.map((event) => (
{ title: `${event.title}`, start: `${event.eDateStart}`, end: `${event.eDateEnd}`, url: `/event/${event.id}` }
))
const holidays = Object.keys(holidaysData)
let holidaysDates = []
for (let i = 0; i < holidays.length; i++) {
let holiday = {
title: holidaysData[holidays[i]],
start: holidays[i],
className: "holiday",
holiday: holidays[i],
display: 'background',
color: 'pink',
}
holidaysDates.push(holiday)
}
const wholeEvents = allevents.concat(holidaysDates)
return (
<Layout
title="カレンダー:K1ファクトリー 浜松市西区雄踏町でホームページ制作・チラシ・ポスターデータ制作ほか"
description="fullcalendarをお試し中です。"
>
<div className="text-center">
<h1 className="text-sm z-1 pt-8">カレンダー表示</h1>
</div>
<div className="px-6 pt-20 text-center bg-white">
<section>
<FullCalendar
plugins={[dayGridPlugin]}
locale="ja"
firstDay="1"
businessHours={false}
events={wholeEvents}
dayCellContent={(e) =>
(e.dayNumberText = e.dayNumberText.replace("日", ""));
}
displayEventTime={true}
displayEventEnd={true}
eventTimeFormat={{ day: 'numeric', hour: 'numeric', minute: '2-digit' }}
/>
</section>
<section>
<Link href="/" passHref><button className="bg-blue-700 hover:bg-blue-500 text-white font-bold py-2 px-10 mb-10 rounded text-sm md:text-base xl:text-lg">トップページに戻る</button></Link>
</section>
</div>
<style global jsx>{`
td.fc-day-sun {
background-color:#ffeaea;
}
td.fc-day-sat {
background-color:#eaf4ff;
}
.holiday {
color: red;
}
`}</style>
</Layout >
)
}
export const getStaticProps = async () => {
const key = {
headers: { 'X-API-KEY': process.env.EVENTS_API_KEY },
}
const data = await fetch('https://k1events.microcms.io/api/v1/events?limit=100', key)
.then(res => res.json())
.catch(() => null)
const hdata = await fetch('https://holidays-jp.github.io/api/v1/date.json')
.then(res => res.json())
.catch(() => null)
return {
props: {
events: data.contents,
holidaysData: hdata
},
};
};
まずは、
getStaticPropsを使って、イベント情報と日本の祝日情報のAPIを読み込みます。
export const getStaticProps = async () => {
const key = {
headers: { 'X-API-KEY': process.env.EVENTS_API_KEY },
}
const data = await fetch('https://k1events.microcms.io/api/v1/events?limit=100', key)
.then(res => res.json())
.catch(() => null)
const hdata = await fetch('https://holidays-jp.github.io/api/v1/date.json')
.then(res => res.json())
.catch(() => null)
return {
props: {
events: data.contents,
holidaysData: hdata
},
};
};
headers: { 'X-API-KEY': process.env.EVENTS_API_KEY }
.env .env.development.localファイルで EVENTS_API_KEYを設定しておきます。
※API_KEYはmicroCMSの管理画面で確認してね。
const data = await fetch('https://k1events.microcms.io/api/v1/events?limit=100', key)
.then(res => res.json())
.catch(() => null)
ここで、microCMSからAPIでイベント情報をゲット!
const hdata = await fetch('https://holidays-jp.github.io/api/v1/date.json')
.then(res => res.json())
.catch(() => null)
日本の休日も同じようにゲット!こちらはとくにKEYとかないのです。
returnでAPIで取得したデータを返しています。
そして、ページ表示部分へ
returnされたprops(プロパティ)データがページ表示に使われます。
export default function Callendar({ events, holidaysData }) {
…
}
「allevents」配列定数に、APIでゲットしたイベント情報データを fullcalendar表示に適応・変形したデータを代入。
{ title: "イベント名", start: "イベント開始日時", end: "イベント終了日時", url: "リンク(詳細ページへの)"},
map関数でイベント数分のデータを作っていきます。
const allevents = events.map((event) => (
{ title: `${event.title}`, start: `${event.eDateStart}`, end: `${event.eDateEnd}`, url: `/event/${event.id}` }
))
「holidaysDates」配列変数に、日本の祝日データを適応・変形したデータを代入。
const holidays = Object.keys(holidaysData)
let holidaysDates = []
for (let i = 0; i < holidays.length; i++) {
let holiday = {
title: holidaysData[holidays[i]],
start: holidays[i],
className: "holiday",
holiday: holidays[i],
display: 'background',
color: 'pink',
}
holidaysDates.push(holiday)
}
APIからよみこんだ「holidaysData」をObject.keys関数で変形させて、「holidays」に代入。
「holidays」の1つ1つを「holiday」としてそれらを push関数で合わせて配列「holidaysDates」にします。
「holiday」それぞれのデータには、
className「holiday」をつけて、
display: 'background',
color: 'pink', で、背景にピンク色をつける表示にしています。
最後に、イベント情報の配列「allevents」と、祝日の配列「holidaysDates」を合体!
const wholeEvents = allevents.concat(holidaysDates)
「wholeEvents」というデータが完成!これをFullCalendarで表示してやります。
<FullCalendar
plugins={[dayGridPlugin]}
locale="ja"
firstDay="1"
events={wholeEvents}
dayCellContent={(e) =>
(e.dayNumberText = e.dayNumberText.replace("日", ""));
}
displayEventTime={true}
displayEventEnd={true}
eventTimeFormat={{ day: 'numeric', hour: 'numeric', minute: '2-digit' }}
/>
plugins={[dayGridPlugin]}:月表示
locale="ja":日本語表記
firstDay="1":月曜日から表示
events={wholeEvents}:イベント情報と祝日情報指定(上で作ったデータですね)
dayCellContent={(e) =>
(e.dayNumberText = e.dayNumberText.replace("日", ""))
}:カレンダーの日にちの「日」を削除
displayEventTime={true}
displayEventEnd={true}
eventTimeFormat={{ day: 'numeric', hour: 'numeric', minute: '2-digit' }}
:イベント情報の表示の仕方「何日 xx:xx - 何日 xx:xx」
土日と祝日の文字色は、スタイルシートで変更しています。
<style global jsx>{`
td.fc-day-sun {
background-color:#ffeaea;
}
td.fc-day-sat {
background-color:#eaf4ff;
}
.holiday {
color: red;
}
`}</style>
以上です!
出来上がりのカレンダーページ。
あとは、イベント情報のリンク先(詳細)ページを作ってあげれば完成ですね。