開発コンポーネント
Exploreページコンポーネント
公開作品の閲覧・検索ページを構成するコンポーネント群
Exploreページコンポーネント
公開された作品を閲覧・検索するためのページを構成するコンポーネント群です。
ExploreSearchControls
Exploreページのヘッダーと検索・フィルタリング機能を提供する統合コンポーネントです。
- 責務:
- 統一されたページヘッダー: Bookshelfページと同じデザインパターンを採用し、一貫したユーザー体験を提供する。
- アイコン付きのページタイトル(
Storeアイコン) - 中央配置の検索バー
- 右側のアクションボタン(Clearボタン)
- アイコン付きのページタイトル(
- レスポンシブデザイン: モバイルとデスクトップで異なるレイアウトを提供。
- モバイル: 2行レイアウト(タイトル + 検索バー)
- デスクトップ: 3カラムレイアウト(タイトル + 検索バー + アクションボタン)
- 検索機能: タイトルやあらすじでの作品検索(デバウンス処理付き)
- タグフィルタリング:
- 横スクロール可能なタグストリップ: 画面の縦幅を占有せず、大量のタグにも対応
- 検索付きPopoverメニュー: タグが多い場合でも、キーワード検索で瞬時に目的のタグを見つけられる
- 視覚的フィードバック: アクティブなタグを強調表示し、選択状態を明確に示す
- フィルターのクリア: ワンクリックですべてのフィルター(検索クエリ + タグ)をクリア
- 統一されたページヘッダー: Bookshelfページと同じデザインパターンを採用し、一貫したユーザー体験を提供する。
- 主要なProps:
popularTags: 人気タグのリスト(タグ名と使用回数を含む)
- 使用している主要なUIコンポーネント:
Input: 検索バーButton: アクションボタンScrollArea: 横スクロール可能なタグストリップPopover: タグフィルタリングメニューのコンテナCommand: 検索付きのタグリスト(CommandInput,CommandList,CommandItemなど)
- デザイントークン:
- アイコン:
Store(Exploreページ) - カラー:
primary/10(アイコン背景)、primary(アクティブタグ)、secondary(非アクティブタグ) - シャドウ:
shadow-sm(検索バー)、shadow-lg(アクティブタグ)
- アイコン:
- スケーラビリティ:
- タグが100個以上になっても、横スクロールとPopover検索により快適に操作可能
- グラデーションマスク(フェード効果)でスクロール可能性を視覚的に示唆
ExplorePageClient
公開作品のグリッド表示とインラインエクスパンダー(詳細パネル)を管理するクライアントコンポーネントです。
- 責務:
- 作品カードのグリッド表示: レスポンシブなグリッドレイアウトで作品を一覧表示
- インラインエクスパンダー: 作品カードをクリックすると、グリッド内に詳細パネルを展開
- カバーアート、タイトル、あらすじ、タグ、アクションボタンを表示
- 選択中のカードを視覚的に強調表示(リング + インジケーター)
- 展開時に自動スクロールし、詳細パネルを画面中央に配置
- アニメーション: Framer Motionを使用した滑らかな展開・収縮アニメーション
- 主要なProps:
projects: 表示する公開作品のリスト
- 関連Atoms: なし(プロップスベースのコンポーネント)
- UI統合:
ProjectCardコンポーネントを使用して各作品を表示ProjectCardにoriginalLanguageプロパティを渡し、作品のオリジナル言語をバッジとして表示OriginalLanguageBadgeコンポーネントを活用して多言語対応を強化
MetadataEditModal
公開済み作品のメタデータ(タイトル、見出し、あらすじ、タグ、カバー画像)を編集するためのモーダルコンポーネントです。
- 責務:
- メタデータ編集フォーム: 公開作品の基本情報を編集
- タイトル(必須)
- 見出し(Headline)
- あらすじ(Synopsis)
- タグ(最大10個、各20文字以内)
- カバー画像管理:
- 画像アップロード: ドラッグ&ドロップまたはファイル選択
- 画像クロッピング:
react-image-cropを使用した1:1.6アスペクト比のクロップ - 画像圧縮: WebP形式への自動変換と圧縮(共有ユーティリティ使用)
- 画像削除: 既存のカバー画像を削除可能
- プレビュー: 選択/クロップした画像のリアルタイムプレビュー
- Supabase Storage連携:
- ファイル命名規則:
${user.id}/${project.id}.webp upsert: trueで既存ファイルを上書き- RLS ポリシー準拠(
user_idベースのアクセス制御)
- ファイル命名規則:
- バリデーション: Zod スキーマによる入力検証
- メタデータ編集フォーム: 公開作品の基本情報を編集
- 主要なProps:
isOpen: モーダルの開閉状態onOpenChange: モーダルの開閉を制御するコールバックproject: 編集対象の公開プロジェクト情報onSave: 保存時のコールバック(メタデータとカバー画像URLを受け取る)
- 使用している主要なUIコンポーネント:
Dialog: モーダルコンテナInput: テキスト入力フィールドTextarea: あらすじ入力エリアTagInput: タグ入力コンポーネントReactCrop: 画像クロッピングUIButton: アクションボタン
- 技術的な特徴:
- React Hook Form: フォーム状態管理とバリデーション
- Zod: スキーマベースのバリデーション
- 画像処理: 共有ユーティリティ(
cropAndCompressImage,compressImage)を使用 - ドラッグ&ドロップ: ネイティブHTML5 Drag and Drop API
- 関連API:
PATCH /api/projects/[id]/metadata: メタデータ更新エンドポイント- Supabase Storage (
coversバケット): カバー画像保存
- ファイルパス:
next-app/src/components/MetadataEditModal.tsx