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]] ハンドラーにより、認証関連のエンドポイントは自動的に提供される。

🚀 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

Releases

No releases published

Packages

No packages published

Languages