Skip to content

oumelab/demo-react-event-calendar

Repository files navigation

React Road お題チャレンジ - イベント掲載アプリ -

connpass のようなイベントの掲載・申し込みができるアプリ
React Router によるクライアントサイドルーティングを実践し、SPA の実装を学ぶ。

React の実践型学習プラットフォーム React Road のお題 イベント掲載アプリに挑戦させていただいた学習プロジェクトです。

課題の実装の他、個人的な学習目的で私が行った変更や追加機能が含まれています。

Note

このリポジトリは、個人的な学習およびデモンストレーションの目的のみに使用されます。
This repository is for personal learning and demonstration purposes only.

🌐 デモサイト・スクリーンショット

👀 View Demo site

匿名ログイン(アカウント登録不要)で気軽に申し込み・キャンセル機能を試用可能です。


トップページ

トップページ

イベント一覧ページ

イベント一覧ページ

イベント詳細ページ

イベント詳細ページ

イベント作成フォーム

イベント作成フォーム

申し込み履歴ページ

イベント申し込み履歴ページ

本アカウント登録ダイアログ

Anonymous→本アカウント登録ダイアログ

✨ 主な機能

基本機能(React Road お題)

  1. イベント一覧ページ: サイトアクセス時に、イベント一覧を表示
  2. イベント詳細ページ: イベント詳細情報を表示
  3. イベント申し込みページ: イベントに申し込むためのメールフォーム(フロントエンドのみ)
  4. 申し込み完了ページ: 申し込み完了メッセージを表示

追加実装済み機能

  • 認証システム - ユーザー登録・ログイン・ログアウト機能 #3
  • イベント管理 - CRUD 操作でイベントの作成・編集・削除 #4, #17
  • データベース連携 - イベントと参加者情報をデータベースに保存 #1
  • 定員管理 - 参加者が満員の場合、参加できないよう制御
  • 型安全性 - フロントエンドとバックエンドで型定義を共有
  • モダンフォーム - React Hook Form + Zod #16
  • 状態管理 - Zustand による効率的な状態管理 #29
  • ルーティング - React Router v6 → v7 へのアップデート
  • イベント申し込み・キャンセル機能 - 参加申し込みとキャンセル機能 #5
  • Anonymous 認証 - 登録なしでゲストとしてイベント申し込みが可能、本アカウントへデータ移行も可能 #43
  • バンドルサイズ分析・最適化 - rollup -plugin-visualizer導入、チャンク分割・動的インポートによるバンドルサイズ削減・最適化 #45
  • イベント作成履歴 - イベント作成履歴の表示 #40
  • 画像アップロード - イベント画像のアップロード機能 #19

実装予定機能

  • ユーザー情報編集機能 - ユーザープロフィールページ・ユーザー情報の編集機能実装 #18
  • イベント終了日時 - イベントの終了日時を設定 #42
  • Google カレンダーに追加 - イベントを Google カレンダーに追加
  • ページネーション - イベント一覧のページネーション
  • イベント検索機能 - イベント検索機能
  • メール通知 - メール通知システム実装 #28

🛠️ 使用技術

カテゴリ 技術スタック
フロントエンド Vite, React, React Router v7, TailwindCSS, shadcn/ui
状態管理・フォーム TanStack Query, Zustand, React Hook Form
バリデーション Zod(フロントエンド・バックエンド共通スキーマ)
バックエンド Cloudflare Pages Functions
データベース Turso(libSQL)
認証 Better Auth
デプロイ Cloudflare Pages
開発ツール TypeScript, Bun, rollup-plugin-visualizer

📊 プロジェクト構成図

🏗️ システムアーキテクチャ

システムアーキテクチャ
Mermaid
--- config: theme: neo --- graph TB subgraph "クライアント(ブラウザ)" React[React App<br/>Vite + TypeScript] Zustand[Zustand<br/>状態管理] TanStack[TanStack Query<br/>サーバー状態] ReactRouter[React Router v7<br/>ルーティング] end subgraph "Cloudflare Pages" StaticFiles[静的ファイル配信] Functions[Pages Functions<br/>API endpoints] end subgraph "データベース" Turso[(Turso libSQL)] end subgraph "認証" BetterAuth[Better Auth<br/>セッション管理] end React --> StaticFiles TanStack --> Functions Zustand -.-> TanStack Functions --> Turso Functions --> BetterAuth BetterAuth --> Turso 
Loading

🗄️ データベース構成(ER 図)

データベース構成
Mermaid
--- config: theme: redux-color --- erDiagram users { text id PK text email boolean emailVerified text name text image boolean isAnonymous integer createdAt integer updatedAt } events { text id PK text title text date text location text description text image_url integer capacity text creator_id FK integer created_at } attendees { text id PK text event_id FK text email text user_id FK integer created_at } sessions { text id PK text userId FK text token integer expiresAt text ipAddress text userAgent integer createdAt integer updatedAt } accounts { text id PK text accountId text providerId text userId FK text accessToken text refreshToken text idToken text password integer createdAt integer updatedAt } verifications { text id PK text identifier text value integer expiresAt integer createdAt integer updatedAt } users ||--o{ events : creates users ||--o{ attendees : registers users ||--o{ sessions : has users ||--o{ accounts : has events ||--o{ attendees : has 
Loading

🔄 状態管理フロー

状態管理フロー
Mermaid
--- config: theme: redux-color --- sequenceDiagram participant U as User participant C as Component participant Z as Zustand Store participant T as TanStack Query participant A as Better Auth API participant D as Database U->>C: ログインボタンクリック C->>T: authClient.signIn.email() T->>A: Better Auth認証 A->>D: ユーザー認証・セッション作成 D-->>A: 認証結果 A-->>T: レスポンス返却 T->>Z: ユーザー情報を更新 Z-->>C: 状態変更通知 C-->>U: UI更新 
Loading

🌐 API エンドポイント構成

🗓️ イベント管理

エンドポイント メソッド 認証 説明
/api/events GET - イベント一覧取得
/api/events/[id] GET - イベント詳細取得
/api/events/create POST イベント作成
/api/events/[id]/update PUT イベント更新
/api/events/[id]/delete DELETE イベント削除

📝 イベント参加

エンドポイント メソッド 認証 説明
/api/events/[id]/apply POST イベント申し込み
/api/events/[id]/cancel DELETE イベント申し込みキャンセル
/api/user/registrations GET ユーザー申し込み履歴取得
/api/user/created-events GET ユーザーイベント作成履歴取得

🔐 認証システム

Better Auth による統一認証エンドポイント(Email and Password)

エンドポイント メソッド 認証 説明
/api/auth/sign-in/email POST - ユーザーログイン
/api/auth/sign-up/email POST - ユーザー新規登録
/api/auth/sign-out POST ユーザーログアウト
/api/auth/get-session GET - セッション情報取得

Note: Better Auth の [[catchall]] ハンドラーにより、認証関連のエンドポイントは自動的に提供される。

📷 画像アップロード

エンドポイント メソッド 認証 説明
/api/upload/image POST 汎用画像アップロード
/api/upload/image DELETE 画像削除
/api/upload/image GET ユーザー画像一覧取得

🚀 Anonymous 認証の特徴

ゲストユーザー体験

  • 登録なしで即体験: 面倒な会員登録なしでイベントの閲覧・申し込みが可能
  • 一時的なデータ保存: 申し込み履歴は匿名ユーザー ID で一時保存
  • スムーズなアップグレード: ワンクリックで正規ユーザーに移行

データ移行システム

状態管理フロー
Mermaid
graph LR A[ゲストユーザー] --> B[イベント申し込み] B --> C[一時データ保存] C --> D[アカウント作成] D --> E[データ自動移行] E --> F[正規ユーザー] style A fill:#e1f5fe style F fill:#e8f5e8 style E fill:#fff3e0 
Loading

移行されるデータ

  • ✅ イベント申し込み履歴
  • ✅ ユーザー設定・preferences
  • ✅ セッション情報

🔧 開発環境

必要なツール

  • Node.js: 22.16.0 (.nvmrc で指定)
  • パッケージマネージャー: bun
  • TypeScript: ^5.7.2

開発サーバー起動

# フロントエンド (Vite) bun run dev # バックエンド (Wrangler + Vite) bunx wrangler pages dev -- bun run dev

ビルド・プレビュー

# ビルド bun run build # プレビュー bun run preview

📊 パフォーマンス最適化

バンドル分析・最適化

  • rollup-plugin-visualizer によるバンドルサイズ分析
  • チャンク分割: React、Router、Form ライブラリを個別バンドル化
  • 遅延読み込み: React.lazy() によるイベント作成画面の動的インポート
  • 成果: 初期バンドルサイズ 29%削減(647KB → 460KB)
# バンドル分析実行 bun run build:analyze