開発コンポーネント
作品詳細ページコンポーネント
作品詳細ページを構成するコンポーネント群の設計
作品詳細ページコンポーネント
このドキュメントは、作品詳細ページ(/explore/details/[id])を構成するコンポーネント群について記述します。
概要
作品詳細ページは、ユーザーが作品を深く知り、読む決意を固めるための専用ページです。Exploreページでの「発見」と、Readerページでの「読書」の間に位置する重要な「玄関」の役割を果たします。
このページは、Exploreでの「発見」とReaderでの「読書」の間に位置する重要な「玄関」の役割を果たします。以下のコンポーネントで構成されています:
- [ActionButtons]: Open Book、Libraryボタン
ページ構成
- ルート:
/explore/details/[id] - 実装: Next.js App Routerのサーバーコンポーネント
- レイアウト: 2カラム(左: メインコンテンツ、右: サイドバー)
コンポーネント一覧
ProjectDetailsPage
作品詳細ページのメインコンポーネント(サーバーコンポーネント)です。
- ファイル:
src/app/explore/details/[id]/page.tsx - 責務:
- Supabaseから作品メタデータと著者情報を取得
- Supabase Storageからコンテンツ(プロット、原稿)を取得
- ライブラリステータスの確認
- 2カラムレイアウトの構築
- データ取得:
published_projectsテーブル(JOINでprofilesも取得)contentsバケットからコンテンツJSONlibrary_itemsテーブルでブックマーク状態を確認
- レイアウト:
- モバイル: 1カラム(縦並び)
- デスクトップ: 2カラム(
lg:grid-cols-3で左2列、右1列)
HeroSection
作品の第一印象を形成するヒーローセクションコンポーネントです。
- ファイル:
src/components/details/HeroSection.tsx - 責務:
- カバー画像の大きな表示(
aspect-video md:aspect-[2/1]) - 作品タイトル(
h1タグ) - ヘッドライン/キャッチコピー(左ボーダー付き)
- 著者情報(アバター + 名前)
- カバー画像の大きな表示(
- 主要なProps:
title: 作品タイトル(string)headline: ヘッドライン(string | null)coverImageUrl: カバー画像URL(string | null)author: 著者情報({ username, avatar_url }| null)
- スタイル特性:
- カバー画像にホバー時のズーム効果(
hover:scale-105) - 画像がない場合はプレースホルダー表示
- レスポンシブなタイポグラフィ(
text-3xl md:text-4xl lg:text-5xl)
- カバー画像にホバー時のズーム効果(
ActionButtons
読者の次のアクションを促すボタン群を提供するコンポーネントです。
- ファイル:
src/components/details/ActionButtons.tsx - 責務:
- Open in Readerボタン: 最初の話へ遷移(
/read/[projectId]/[firstStoryId]) - Libraryボタン: ライブラリへの追加/削除(Optimistic UI実装)
- 将来の機能用プレースホルダー(Like, Share)
- Open in Readerボタン: 最初の話へ遷移(
- 主要なProps:
projectId: プロジェクトID(string)firstStoryId: 最初の話のID(string | null)initialInLibrary: 初期のライブラリ状態(boolean)
- API連携:
POST /api/library: ライブラリに追加DELETE /api/library: ライブラリから削除
- UX特性:
- 楽観的UI更新で即座にフィードバック
- エラー時は自動的にロールバック
- トースト通知で操作結果を表示
Synopsis
作品のあらすじを表示するコンポーネントです。
- ファイル:
src/components/details/Synopsis.tsx - 責務:
- あらすじテキストの表示
- 長文の場合の折りたたみ機能(300文字を閾値)
- 「Read More / Show Less」トグル
- 主要なProps:
synopsis: あらすじテキスト(string | null)
- 使用しているUIコンポーネント:
Collapsible,CollapsibleContent,CollapsibleTrigger(shadcn/ui)Button(variant="ghost")
- スタイル特性:
- 折りたたみ時にグラデーションフェード効果(
bg-gradient-to-t from-background) whitespace-pre-wrapで改行を保持
- 折りたたみ時にグラデーションフェード効果(
TableOfContents
作品の階層的な目次を表示するコンポーネントです。
- ファイル:
src/components/details/TableOfContents.tsx - 責務:
Part > Arc > Chapter > Storyの階層構造を表示- 各話のタイトルをReaderページへのリンクとして提供
- アコーディオン形式で階層を開閉可能
- 旧構造(
chapters直接)への後方互換性
- 主要なProps:
structuredPlot: プロット構造(StructuredPlot型)projectId: プロジェクトID(string)
- 使用しているUIコンポーネント:
Accordion,AccordionItem,AccordionTrigger,AccordionContent(shadcn/ui)
- リンク生成:
- 各話:
/read/[projectId]/[storyId]
- 各話:
- デフォルト動作:
- すべてのPartをデフォルトで展開(
defaultValueにすべてのpart.idを設定)
- すべてのPartをデフォルトで展開(
ProjectInfoCard
作品のメタデータを整理して表示するカードコンポーネントです。
- ファイル:
src/components/details/ProjectInfoCard.tsx - 責務:
- タグの表示(Badge形式、クリック可能)
- ステータス表示(完結済み/連載中)
- 文字数の表示
- 公開日/最終更新日の表示
- 主要なProps:
tags: タグの配列(string[] | null)status: ステータス("completed" | "ongoing")wordCount: 文字数(number | undefined)publishedAt: 公開日(string | null)updatedAt: 最終更新日(string | null)
- 使用しているUIコンポーネント:
Card,CardHeader,CardTitle,CardContent(shadcn/ui)Badge(shadcn/ui)
- アイコン:
FileText: 文字数Calendar: 日付Tag: タグ
ReviewChart
AI査読結果を視覚化するチャートコンポーネントです。
- ファイル:
src/components/details/ReviewChart.tsx - 責務:
- 動的評価軸(
dynamic_detailed_ratings)をレーダーチャートで表示 - AI品質チェック通過のメッセージ表示
- 査読結果がない場合は非表示
- 動的評価軸(
- 主要なProps:
reviewReport: AI査読レポート(ReviewReport | null)
- 使用しているライブラリ:
recharts: レーダーチャートの描画ChartContainer,ChartTooltip(shadcn/ui chart components)
- データ変換:
const data = reviewReport.dynamic_detailed_ratings.map((rating) => ({ axis: rating.axis, score: rating.score, })); - スタイル特性:
aspect-square max-h-[300px]: 正方形で最大300pxouterRadius="70%": チャートサイズ- プライマリカラーで統一(
hsl(var(--primary)))
OriginalLanguageBadge
作品のオリジナル言語を表示するバッジコンポーネントです。
- ファイル:
src/components/ui/original-language-badge.tsx - 責務:
- 言語コード(例: 'ja', 'en')を人間が読める言語名に変換して表示
- グローバルアイコン(Globe)と共にコンパクトなバッジとして表示
- 言語コードがnullの場合は非表示
- 主要なProps:
languageCode: 言語コード(string | null)className: 追加のCSSクラス(オプション)
- 技術的特徴:
Intl.DisplayNamesAPIを使用して言語コードをローカライズされた言語名に変換- shadcn/uiの
Badgeコンポーネントをベースに使用 - フォールバック処理: Intl APIが利用できない場合は言語コードをそのまま表示
- スタイル特性:
text-[10px] h-5: コンパクトなサイズbg-background/50 backdrop-blur-sm: 半透明の背景にぼかし効果gap-1: アイコンとテキストの間隔
- 使用箇所:
ProjectDetailsContainer: ヒーローセクションの左上に表示ProjectDetailView: プロジェクト詳細モーダル内に表示ProjectCard: カードの右下に表示(Explore、Library、My Worksページ)
設計思想
1. 情報の階層化
- 左カラム: 読者が最も求める情報(あらすじ、目次)
- 右カラム: 補助的な情報(メタデータ、査読結果)
2. アクションの明確化
- 「Open in Reader」を最も目立つプライマリボタンとして配置
- ライブラリ追加は二次的なアクションとして控えめに
3. 拡張性
- 右カラムには将来の機能(レビュー、関連作品など)を追加するスペースを確保
- コンポーネントは独立しており、個別に拡張可能
4. ユーザージャーニー
Explore → 作品カード → 詳細ページ → Open in Reader → Reader
↓
Library追加5. 役割分担の明確化
- Explore: 「偶然の出会い」の場所
- 作品詳細: 「深く知る」場所
- Reader: 「没入する」場所
関連ドキュメント
/doc/system/06_routing_architecture.md- ルーティング設計/doc/system/07_component_bible.md- 全体のコンポーネント設計/doc/system/04_database_schema_supabase.md- データベーススキーマ/doc/log/reports/2025-12-02_report_implement-project-details-page.md- 実装レポート