connpass のようなイベントの掲載・申し込みができるアプリ
React Router によるクライアントサイドルーティングを実践し、SPA の実装を学ぶ。
React の実践型学習プラットフォーム React Road のお題 イベント掲載アプリに挑戦させていただいた学習プロジェクトです。
課題の実装の他、個人的な学習目的で私が行った変更や追加機能が含まれています。
Note
このリポジトリは、個人的な学習およびデモンストレーションの目的のみに使用されます。
This repository is for personal learning and demonstration purposes only.
匿名ログイン(アカウント登録不要)で気軽に申し込み・キャンセル機能を試用可能です。
トップページ | イベント一覧ページ |
イベント詳細ページ | イベント作成フォーム |
イベント申し込み履歴ページ | Anonymous→本アカウント登録ダイアログ |
- イベント一覧ページ: サイトアクセス時に、イベント一覧を表示
- イベント詳細ページ: イベント詳細情報を表示
- イベント申し込みページ: イベントに申し込むためのメールフォーム(フロントエンドのみ)
- 申し込み完了ページ: 申し込み完了メッセージを表示
- 認証システム - ユーザー登録・ログイン・ログアウト機能 #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
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
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更新 | エンドポイント | メソッド | 認証 | 説明 |
|---|---|---|---|
/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 | ✅ | ユーザー画像一覧取得 |
- 登録なしで即体験: 面倒な会員登録なしでイベントの閲覧・申し込みが可能
- 一時的なデータ保存: 申し込み履歴は匿名ユーザー 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 - ✅ イベント申し込み履歴
- ✅ ユーザー設定・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