🍣

初心者がWebアプリを作ってみた(1)

に公開

はじめに

Webアプリの開発・作り方といった記事はたくさんあって、
「React初心者」や「Node.js初心者」とかのサイトを見て勉強して、何となくわかった気になったけど、実際に何か作ろうとすると手が止まっちゃうんですよね。
ネットのページを見て基本がだいたい分かって来たら、何か作ってみようと思うけど、
何か動くものを作るという視点で、ネット上の情報を見ると、
急に認証がどうだとか、データベースがどうだとか、難しくなって、
まずは簡単な動くものを、と思っても全体が大きすぎて結局理解し難いと感じてました。

まずは、簡単なものを作って、そこに機能を足していく、
分かんない機能は、その時に、そのことだけに絞って勉強していく

というスタンスで、Webアプリを作成しました。
作るのは、実用的なものがよかったので、社内での会議室の予約アプリとしました。
現状では、カレンダーの書かれた紙に、予約する人が記入していましたが、私は違うフロアで作業する事が多く、予約や確認の為に、移動するのが面倒だったんです。
自分的にも欲しかったし、使った人から感謝された方がモチベーションになりますよね。

対象読者

初心者向けのサイトを読み漁ったけど、次どうればいいのって人

開発環境

サーバ(ubuntu)にVSCodeのSSHで接続して作業を実施しました。

cat /etc/os-release 
PRETTY_NAME="Ubuntu 24.04.2 LTS"
VERSION_ID="24.04"
VERSION="24.04.2 LTS (Noble Numbat)"

WindowsでもjavaScriptが動く環境があれば、同じようにできると思います。

まずは見た目です

Reactを使います

まずは、カレンダーを表示して、カレンダーをクリックするとダイアログ表示して、必要な情報を書き込む事で、カレンダー上に予約状況を表示できるものを作りました。

予約したい場所は、会議室と応接室の2つあります。これらは色で分けて分かりやすく表示することにしました。時間も業務時間の9:00~17:30までの表示としています。提示後の予約は考慮しない事にしました。

使用者がブラウザで操作する画面の作成なので、「React」というライブラリを使用しています。
コマンド一発でいろいろと下準備してくれるので、非常に便利ですよね。

npx create-react-app meeting-room

何もしない状態でも、

npm start

でブラウザに表示が出ます。とりあえず動作確認しといた方が良いですね。

カレンダーを表示させます

カレンダーは、
検索すればいくらでも情報が出てきますが、「fullCalendar」というもの使います。
まずはインストールですね

 npm install --save \
  @fullcalendar/core \
  @fullcalendar/daygrid \
  @fullcalendar/timegrid \
  @fullcalendar/interaction \
  @fullcalendar/list

コードとしては、
「/src/app.js」ファイルを変更してカレンダーを作っていきます
先頭に「インストールしたカレンダーを使用するよ」といった宣言を記載します

import FullCalendar from '@fullcalendar/react'
import timeGridPlugin from '@fullcalendar/timegrid'
import interactionPlugin from '@fullcalendar/interaction';

次にfunction Appの中身を書き換えます。
この記述がブラウザに表示される内容となっています。

function App() {
  return (
    <div className="App">
      <FullCalendar
        plugins={[timeGridPlugin]}
        initialView="timeGridWeek"
        headerToolbar={{
          left: 'prev,next today',
          center: 'title',
          right: 'dayGridMonth,timeGridWeek,timeGridDay'
        }}
      />
    </div>
  );

月毎の日表示ではなくて、予約なので一週間毎の時間毎の表示にしたいので、
fullCalendarタブの中に設定があって、「initialView」に記載されている「timeGridWeek」で指定しています。

とりあえずそれっぽい表示にはなりましたね。でもいくつか不満点があるので、それらを修正していきましょう。

設定見直して表示を調整します

まずは、月日の表示を日本語にしたいですね。これは以下の設定を追記で行います。

locale="ja"

次に日の表示と、時間の表示の間に「all-day」といった行があるのは消したいですね。

allDaySlot={false} // all-day の表示を非表示にする。

土曜日と日曜日は、会社営業してないので、予約もないので消しましょう。
日曜日を0として、非表示にしたい曜日を選択するみたいです。

hiddenDays={[0, 6]} // 日曜日と土曜日を非表示

右上のボタンでが「week」と「day」の2択になっています。今回はdayの選択はしないと思うので、weekのみの表示でいいです。なので、この2択のボタン自体が不要なので、消しましょう。

headerToolbar={{
    right: ''

rightの設定自体を消すと、左上にある、左右矢印が表示されちゃいますので、何も表示しないって意味で''を明示的に書く必要があるみたいです。

そういえば、日本語にしたのに左上の「today」は英語のままですね。ボタン内のテキストを変更するには別の設定が必要みたいです。

buttonText={{today: '今日'}}

時間も営業時間に絞って表示したいです。

slotMinTime="09:00:00"
slotMaxTime="17:30:00"

カレンダーにイベントを表示してみよう

なんかイベントをカレンダに表示してみましょう。
App.jsと同じフォルダ内に「events.js」ファイル作成してください。
ここにイベントを記述して、これを読み込んでカレンダに表示とします。
events.js

const events = [
    {
      title: '会議',
      start: '2025-03-15T10:00:00',
      end: '2025-03-15T12:00:00',
    },
    {
      title: 'ランチ',
      start: '2025-03-15T12:00:00',
      end: '2025-03-15T13:00:00',
    },
    {
      title: '開発',
      start: '2025-03-15T13:00:00',
      end: '2025-03-15T17:00:00',
    },
    {
      title: 'イベント',
      start: '2025-03-18T10:00:00',
      end: '2025-03-18T16:00:00',
    },
    {
      title: 'イベント2',
      start: '2025-03-20T10:00:00',
      end: '2025-03-20T16:00:00',
    },
  ];
  
  export default events;

App.js側に、events.jsファイルを読み込ませる処理を書きます。
App.js

import events from './events.js';

カレンダの設定に以下を追加してください

events={events}

カレンダにて、events.jsファイルに記述した日付を確認すると、イベントが表示されるはずです。

ここまでのApp.jsコードです。

//import logo from './logo.svg';
import './App.css';

import React from 'react';
import FullCalendar from '@fullcalendar/react';
import timeGridPlugin from '@fullcalendar/timegrid';
import dayGridPlugin from '@fullcalendar/daygrid';
import { Calendar } from '@fullcalendar/core';
import interactionPlugin from '@fullcalendar/interaction';
import events from './events.js';

function App() {
  const eventClickHandler = (info) => {
    alert('Clicked ' + info.event.title);
  }
  const dateClickHandler = (info) => {
    alert('Clicked on ' + info.dateStr);
  }
  return (
    <div className="App">
      <FullCalendar
        plugins={[timeGridPlugin,interactionPlugin ]}
        initialView="timeGridWeek" // 初期表示のモードを設定する
        headerToolbar={{
          left: 'prev,next today',
          center: 'title',
          right: ''
        }}
        locale="ja"
        allDaySlot={false} // all-day の表示を非表示にする
        //hiddenDays={[0, 6]} // 日曜日と土曜日を非表示
        buttonText={{today: '今日'}}
        slotMinTime="09:00:00"
        slotMaxTime="17:30:00"
        eventClick={(info) => {
          alert('Clicked eventClick ' + info.event.title);
        }}
        dateclick={(info) => {
          alert('Clicked dateClick ' + info.dateStr);
        }}
        select={(info) => {
          alert('Clicked select ' + info.startStr + ' to ' + info.endStr);
        }}
        selectable={true}
        events={events}
      />
    </div>
  );
}
export default App;

次の実装

とりえずブラウザ上にカレンダー表示はできましたね。予約したい時間の選択もできそうですが、次に予約内容を保持する仕組みが必要ですよね。この予約状況は保存されて欲しいので、ブラウザ側の実装ではできそうに無いですよね。
サーバー側で、予約状況を保持して、必要な時にクライアント側では読み出したり、登録したりする仕組みが必要ですので、次回はその辺の実装を行います。

(2)も記述しました。続きも見てください。
https://t.co/RcBBRmkfNv

Discussion