Glideで予約表作ったら紙以下と言われたので仕方なくReactでつくってます
部内の会議室予約が紙ベースで嫌だったので、電子化することにしました。
あまり時間をかけたくないと考え、ノーコードツールのglideで作ったのですが、操作感がいまいちだったため、紙以下と言われてしまいました
頭にきたのでReact + fullcalendarで一から作ってやろうと言うのが前回記事でした。
スプレッドシートのデータをfullcalendarのフロントに反映させる
glideで作ったアプリはスプレッドシートをデータベースとして利用していた都合上、同じスプレッドシートのデータを読み込んで、Reactで作成したフロントに反映させることを考えました。
今回はSteinを用いて、スプレッドシートをAPI化して、データを反映させていきます。
Stein
ドキュメントが非常にわかりやすいです。
npm install stein-js-client
でインストールしてください。
実行環境
Node.js version 18.1.0
npm version 8.8.0"stein-js-client": "^0.0.2"
React周り
"react": "^18.1.0",
"react-admin": "^4.1.2",
"react-dom": "^18.1.0",
"react-scripts": "5.0.1",
"web-vitals": "^2.1.4"FullCalendar周り
"@fullcalendar/core": "^5.11.0",
"@fullcalendar/daygrid": "^5.11.0",
"@fullcalendar/list": "^5.11.0",
"@fullcalendar/react": "^5.11.1",
"@fullcalendar/timegrid": "^5.11.0",
"@fullcalendar/interaction": "^5.11.0",
前回記事からfullcalendar/interaction
が増えてます
カレンダーへの反映
カレンダー画面サンプル
スプレッドシート上のデータが反映されます
スプレッドシート
スプレッドシートの1行目にcolumn名を入力していきます。
rowIdはGlideのアプリ側で自動的に設定されています。
開始終了の日時はISO 8601形式で表示してください
サンプルコード
import React, { useCallback, useState, useEffect } from "react";
import FullCalendar from "@fullcalendar/react";
import dayGridPlugin from "@fullcalendar/daygrid";
import timeGridPlugin from '@fullcalendar/timegrid';
import listPlugin from '@fullcalendar/list';
import interactionPlugin from "@fullcalendar/interaction";
import jaLocale from "@fullcalendar/core/locales/ja"
const now = new Date();
// steinでgoogle sheetから読み込み
const steinStore = require('stein-js-client')
const store = new steinStore('stein_API_URL')//Steinで生成されたURLを入力
// カレンダーコンポーネントの生成
const CalendarData = (props) => {
const [events, setEvents] = useState();
//SteinAPIを叩く
useEffect(() => {
store.read("シート1", { limit: 200, offset: 0 })
.then((data) => {
console.dir(data);
let eventList = data.map(element => {
return {id: element.rowId, title: element.予約者, start:element.開始, end:element.終了, description:element.用途};
});
setEvents(eventList)
});
},[])
return (
events ?
<FullCalendar
plugins={[
dayGridPlugin,
timeGridPlugin,
listPlugin,
interactionPlugin
]}
headerToolbar={{
left: 'prev,next today',
center: 'title',
right: 'dayGridMonth,timeGridWeek',//timeGridDayで単日表示も可能,listWeekでリスト表示
}}
initialView="timeGridWeek"
initialDate={now.toISOString().split('T')[0]} //初期表示
nowIndicator={true} //現在時刻の表示
locales={[jaLocale]} //todayとかも日本語化される
locale="ja" // 日本語化
selectable={true} //範囲指定が可能になる
eventStartEditable={true} //ドラッグ&ドロップが可能になる
eventDurationEditable={true} //期間変更
events={events}
/> :
<div><h1>読み込み中・・・ちょっと待ってね</h1></div>
);
};
export default CalendarData;
解説が必要そうなところを折りたたみで解説していきます。
SteinAPIを叩く
const [events, setEvents] = useState();
//SteinAPIを叩く
useEffect(() => {
store.read("シート1", { limit: 200, offset: 0 })
.then((data) => {
console.dir(data);
let eventList = data.map(element => {
return {id: element.rowId, title: element.予約者, start:element.開始, end:element.終了, description:element.用途};
});
setEvents(eventList)
});
},[])
ReactはuseEffect()
でAPIを叩いて、setState
することでAPIの値をフロントに反映させることが多いです。
この記事がわかりやすいです。
Steinで取得したdata
をmap
でreturn
以下のようなオブジェクトを持つ配列として返し、events
のstateにsetEvents
でセットしています。
このeventsという配列をこの後のコードで呼び出して、カレンダーに反映していきます。
SteinAPIを読み込んだらカレンダーを表示
events ?
<FullCalendar
/> :
<div><h1>読み込み中・・・ちょっと待ってね</h1></div>
CalendarData
のreturn
以下、長い部分を消すとこのようになります。
三項演算子で配列events
が存在するときはカレンダーを表示、読み込まれるまではdivタグ内を表示するようにしています。
次はフロントで操作した内容をスプレッドシートに反映する
今回はカレンダーデータを読み込むところまで作成しました。
表示されたカレンダーを操作することはできますが、更新すると戻ってしまいます。
次はフロントの操作を反映させてみます。
もうできているので、あとは記事を書くやる気の問題ですね