概要
顧客向け予約フォームと管理者向けダッシュボードを備えた予約管理システム。予約受付から管理・ステータス更新までを一元管理できる。
対象ユーザー・想定利用シーン
- クリニック・歯科医院
- 美容院・サロン
- コンサルティング・士業
- スクール・教室
- 各種予約受付が必要な事業者
Demo / GitHub
🔗 Demo を試す | GitHub
スクリーンショット
トップページ — サービス紹介・主な機能
ステップ1 — 日付・時間選択
ステップ2 — 予約情報入力フォーム
ステップ3 — 予約内容の確認
管理画面 — 予約一覧・ステータス管理
開発背景
予約システムは多くの業務で利用されるため、実案件を想定したデモとして開発。顧客側の予約フローだけでなく、管理者の運用まで含めて設計・実装し、実際の予約業務を一通り再現した。
解決した課題
- 顧客がWebから24時間予約できる
- 電話・メールでの予約受付を削減
- 管理者が予約状況を一元管理
- 予約ステータスを可視化(待確認→確認済→完了/キャンセル)
- 空き枠を柔軟に管理
主な機能
- 日付選択 → 空き枠表示 → 予約フォーム → 確認 → 完了(ステップ形式)
- 管理者ログイン
- 予約一覧・ステータス別フィルタ
- 予約ステータス更新(待確認/確認済/完了/キャンセル)
- 空き枠管理(日付ごとに時間枠を作成・削除)
- キャンセル時の空き枠自動復活
- 2週間分の平日カレンダー自動生成
使用技術
- フロントエンド: React / TypeScript / Vite
- バックエンド: Firebase Cloud Functions v2(Cloud Run)
- DB: Firestore
- 認証: Firebase Authentication
- デプロイ: Firebase Hosting
設計上の工夫
- ステップ形式のUI: 日付選択→時間選択→情報入力→確認→完了を段階的に進行させ、入力途中の離脱を防止
- 空き枠のリアルタイム制御: 管理者が日付ごとに予約可能な時間枠を作成・削除でき、柔軟な運用が可能
- ステータスワークフロー: 待確認→確認済→完了/キャンセルの遷移で、予約のライフサイクルを管理。キャンセル時は空き枠を自動復活
- 認証の分離: 顧客APIは認証不要、管理APIはIDトークン検証で保護し、利便性とセキュリティを両立
- バッチ書き込み: 予約作成と枠の更新をFirestore Batchで同時実行し、データの整合性を確保
アーキテクチャ
[顧客] [管理者] ↓ 日付選択・予約 ↓ ログイン(Firebase Auth) ↓ ↓ React SPA (Vite) React SPA (同一アプリ内) ↓ fetch ↓ fetch + IDトークン ↓ ↓ Firebase Cloud Functions v2 (Cloud Run) ├─ getAvailableSlots (認証不要) ├─ createBooking (認証不要) ├─ getBookings (管理者のみ) ├─ updateBookingStatus (管理者のみ) └─ manageSlots (管理者のみ) ↓ Firestore ├─ bookings コレクション └─ slots コレクション
開発周期
1週間
担当範囲
設計 → フロントエンド → バックエンド → DB設計 → デプロイ(全工程を一人で担当)
成果・実現したこと
- 電話・メールでのやり取りを不要にし、予約業務をオンラインで完結
- 顧客向け画面と管理画面を分離し、それぞれの利用者に最適化した操作性を実現
- 顧客が空き状況をリアルタイムで確認でき、ダブルブッキングを防止
- 管理者がステータス別に予約を管理でき、対応漏れを防止
- Firebase無料枠内で運用可能なコスト効率の高い構成
開発で直面した課題と解決方法
- 顧客と管理者のAPI分離: 予約作成は認証不要にしたいが管理APIは保護したい → Firebase Auth IDトークン検証で管理APIのみ認証を要求する設計に
- 空き枠の柔軟性: 固定の時間枠だと運用しづらい → 管理者が日付ごとに時間枠を自由に作成・削除できる仕組みを実装
- キャンセル時のデータ整合性: 予約キャンセル時に空き枠が復活しないと再予約できない → キャンセル処理時に自動で空き枠をavailableに戻す設計
このプロジェクトで学んだこと
- 予約システムは顧客フローと管理フローの両方を設計しないと実用に耐えないこと
- サーバーレス構成を採用することで、小規模な業務システムを低コストで運用できること
- ステップ形式のUIは入力完了率の向上に効果的であること