2
2

More than 1 year has passed since last update.

#React + fullcalendar + Steinでスプレッドシートをカレンダー化する

Last updated at Posted at 2022-09-09

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形式で表示してください

サンプルコード

CalendarData.jsx
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の値をフロントに反映させることが多いです。

この記事がわかりやすいです。

https://terrblog.com/useeffect%E3%81%AE%E5%9F%BA%E6%9C%AC%E7%9A%84%E3%81%AA%E4%BD%BF%E3%81%84%E6%96%B9%E3%81%A8%E9%9D%9E%E5%90%8C%E6%9C%9F%E5%87%A6%E7%90%86%E3%81%AE%E3%82%84%E3%82%8A%E6%96%B9/

Steinで取得したdatamapreturn以下のようなオブジェクトを持つ配列として返し、eventsのstateにsetEventsでセットしています。

このeventsという配列をこの後のコードで呼び出して、カレンダーに反映していきます。

SteinAPIを読み込んだらカレンダーを表示
    events ?
    <FullCalendar

    /> : 
    <div><h1>読み込み中・・・ちょっと待ってね</h1></div>

CalendarDatareturn以下、長い部分を消すとこのようになります。
三項演算子で配列eventsが存在するときはカレンダーを表示、読み込まれるまではdivタグ内を表示するようにしています。

次はフロントで操作した内容をスプレッドシートに反映する

今回はカレンダーデータを読み込むところまで作成しました。
表示されたカレンダーを操作することはできますが、更新すると戻ってしまいます。

次はフロントの操作を反映させてみます。
もうできているので、あとは記事を書くやる気の問題ですね

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2