これは優れた設計タスクだ。では分析に入る。
| # | コンポーネント名 | 責務概要 | 再利用性 | インタラクティブ |
|---|---|---|---|---|
| 1 | OrderManagementPage | ルートコンポーネント、データ取得・SEO | 低 | なし |
| 2 | OrderListLayout | メインコンテンツ領域のレイアウト構造 | 中 | なし |
| 3 | OrderSearchBar | 注文番号・顧客名によるキーワード検索フォーム | 中 | あり |
| 4 | OrderFilterPanel | ステータス・期間フィルター + アクションボタン群 | 中 | あり |
| 5 | StatusSelect | ステータス選択ドロップダウン | 高 | あり |
| 6 | DateRangePicker | 期間選択(開始〜終了) | 高 | あり |
| 7 | OrderTable | 注文一覧テーブル(ソート・選択機能付き) | 低 | あり |
| 8 | OrderTableHeader | テーブルヘッダー(ソート・一括選択チェックボックス) | 低 | あり |
| 9 | OrderTableRow | テーブル行(チェックボックス・操作メニュー) | 低 | あり |
| 10 | OrderStatusBadge | ステータス表示バッジ | 高 | なし |
| 11 | OrderActionsMenu | 行ごとの操作メニュー(…ボタン) | 中 | あり |
| 12 | OrderDetailModal | 注文詳細モーダル | 低 | あり |
| 13 | CustomerInfoSection | モーダル内:顧客情報表示 | 低 | なし |
| 14 | OrderItemsSection | モーダル内:注文商品リスト | 低 | なし |
| 15 | StatusChangeButtons | モーダル内:ステータス変更ボタン群 | 中 | あり |
| 16 | BulkActionBar | 一括操作バー(選択時に表示) | 低 | あり |
| 17 | CsvExportButton | CSV出力ボタン | 高 | あり |
| 18 | OrderTableSkeleton | テーブルローディングスケルトン | 中 | なし |
| 19 | OrderListEmptyState | 検索結果0件時の空状態表示 | 中 | なし |
| コンポーネント名 | カテゴリ | 配置先 | Server/Client | 分類理由 |
|---|---|---|---|---|
| OrderManagementPage | Route | app/orders/page.tsx |
Server | URLパスに対応するエントリポイント |
| OrderListLayout | Layout | components/layouts/order-list-layout.tsx |
Server | コンテンツ領域の構造定義のみ |
| OrderSearchBar | Feature | features/orders/components/order-search-bar.tsx |
Client | URL状態との同期、検索実行ロジック含む |
| OrderFilterPanel | Feature | features/orders/components/order-filter-panel.tsx |
Client | フィルター状態管理、CSV出力トリガー |
| StatusSelect | Form | components/forms/status-select.tsx |
Client | ステータスマスタ連携のセレクト入力 |
| DateRangePicker | Form | components/forms/date-range-picker.tsx |
Client | 既存DatePickerを組み合わせた範囲選択 |
| OrderTable | Feature | features/orders/components/order-table.tsx |
Client | ソート・選択状態、クリックイベント処理 |
| OrderTableHeader | Feature | features/orders/components/order-table-header.tsx |
Client | ソートトリガー、一括選択ロジック |
| OrderTableRow | Feature | features/orders/components/order-table-row.tsx |
Client | 行選択、詳細モーダル起動 |
| OrderStatusBadge | UI | components/ui/order-status-badge.tsx |
Client | ステータスに応じたバリアント表示 |
| OrderActionsMenu | Feature | features/orders/components/order-actions-menu.tsx |
Client | 行操作のドロップダウンメニュー |
| OrderDetailModal | Feature | features/orders/components/order-detail-modal.tsx |
Client | 詳細取得、ステータス更新API連携 |
| CustomerInfoSection | Shared | components/shared/customer-info-section.tsx |
Client | データ表示のみ、汎用性あり |
| OrderItemsSection | Feature | features/orders/components/order-items-section.tsx |
Client | 注文商品固有の計算・表示ロジック |
| StatusChangeButtons | Feature | features/orders/components/status-change-buttons.tsx |
Client | ステータス更新API呼び出し |
| BulkActionBar | Feature | features/orders/components/bulk-action-bar.tsx |
Client | 一括更新API連携 |
| CsvExportButton | Feature | features/orders/components/csv-export-button.tsx |
Client | ダウンロードトリガー、現在フィルター条件連携 |
| OrderTableSkeleton | Shared | components/shared/order-table-skeleton.tsx |
Server | 純粋なUI、状態不要 |
| OrderListEmptyState | Shared | components/shared/order-list-empty-state.tsx |
Server | 既存EmptyStateの具体化 |
flowchart TD
subgraph Route ["Route Components"]
Page["app/orders/page.tsx"]
end
subgraph Layout ["Layout Components"]
OLL["OrderListLayout"]
end
subgraph Feature ["Feature Components"]
OSB["OrderSearchBar"]
OFP["OrderFilterPanel"]
OT["OrderTable"]
OTH["OrderTableHeader"]
OTR["OrderTableRow"]
OAM["OrderActionsMenu"]
ODM["OrderDetailModal"]
OIS["OrderItemsSection"]
SCB["StatusChangeButtons"]
BAB["BulkActionBar"]
CEB["CsvExportButton"]
end
subgraph Form ["Form Components"]
SS["StatusSelect"]
DRP["DateRangePicker"]
end
subgraph Shared ["Shared Components"]
CIS["CustomerInfoSection"]
OTS["OrderTableSkeleton"]
OLE["OrderListEmptyState"]
BC["Breadcrumb(既存)"]
PG["Pagination(既存)"]
end
subgraph UI ["UI Components"]
OSBadge["OrderStatusBadge"]
BTN["Button(既存)"]
INP["Input(既存)"]
DLG["Dialog(既存)"]
SEL["Select(既存)"]
CB["Checkbox(既存)"]
TBL["Table(既存)"]
BDG["Badge(既存)"]
SKL["Skeleton(既存)"]
end
Page --> OLL
Page --> OSB
Page --> OFP
Page --> OT
Page --> BAB
Page --> ODM
Page --> BC
OLL --> SKL
OSB --> INP
OSB --> BTN
OFP --> SS
OFP --> DRP
OFP --> BTN
OFP --> CEB
OT --> OTH
OT --> OTR
OT --> TBL
OT --> PG
OT --> OLE
OT --> OTS
OTH --> CB
OTR --> CB
OTR --> OSBadge
OTR --> OAM
OAM --> BTN
ODM --> DLG
ODM --> CIS
ODM --> OIS
ODM --> SCB
ODM --> BTN
SCB --> BTN
SCB --> OSBadge
BAB --> BTN
BAB --> SS
CEB --> BTN
SS --> SEL
DRP --> INP
OSBadge --> BDG
OTS --> SKL
OTS --> TBL
| 状態 | スコープ | 管理方法 | 配置コンポーネント |
|---|---|---|---|
| 検索キーワード | URL | nuqs useQueryState |
OrderSearchBar |
| ステータスフィルター | URL | nuqs useQueryState |
OrderFilterPanel |
| 期間フィルター(開始) | URL | nuqs useQueryState |
OrderFilterPanel |
| 期間フィルター(終了) | URL | nuqs useQueryState |
OrderFilterPanel |
| ソートカラム | URL | nuqs useQueryState |
OrderTableHeader |
| ソート順序 | URL | nuqs useQueryState |
OrderTableHeader |
| 現在ページ | URL | nuqs useQueryState |
Pagination |
| 注文一覧データ | サーバー | TanStack Query useQuery |
OrderTable |
| 注文詳細データ | サーバー | TanStack Query useQuery |
OrderDetailModal |
| ステータスマスタ | サーバー | TanStack Query useQuery(staleTime: Infinity) |
アプリ起動時プリフェッチ |
| 選択中の注文ID群 | ローカル | useState(Set) | OrderTable |
| モーダル開閉状態 | ローカル | useState | OrderManagementPage |
| 選択中の注文ID(詳細表示用) | ローカル | useState | OrderManagementPage |
| 楽観的更新状態 | サーバー | TanStack Query useMutation + optimisticUpdate |
StatusChangeButtons / BulkActionBar |
| CSV出力ローディング | ローカル | useState | CsvExportButton |
# Route Component生成依頼
## コンポーネント情報
- **パス**: `app/orders/`
- **ファイル構成**:
- `page.tsx`
- `layout.tsx`(不要:親layoutで十分)
- `loading.tsx`
- `error.tsx`
- **基本境界**: Server Component
## 要件
### ルート情報
| 項目 | 値 |
|------|-----|
| URLパス | `/orders` |
| 動的セグメント | なし |
| 認証要否 | 要(管理画面のため) |
### データフェッチ
| データ | 取得方法 | キャッシュ戦略 |
|--------|----------|---------------|
| 注文一覧初期データ | Server Component内でfetch | no-store(リアルタイム性重視) |
| ステータスマスタ | Server Component内でfetch | force-cache(24時間) |
### SEO/Metadata
| 項目 | 値 |
|------|-----|
| title | 注文管理 | 管理画面 |
| description | 注文の検索・フィルタリング・ステータス管理を行う管理画面 |
| robots | noindex, nofollow |
### 子コンポーネント配置
| コンポーネント | カテゴリ | Suspense |
|---------------|----------|----------|
| Breadcrumb | Shared | ❌ |
| OrderSearchBar | Feature | ❌ |
| OrderFilterPanel | Feature | ❌ |
| OrderTable | Feature | ✅ |
| BulkActionBar | Feature | ❌ |
| OrderDetailModal | Feature | ❌ |
## 制約条件
- [ ] Server Componentとして実装
- [ ] searchParamsを受け取り、クライアントコンポーネントに初期値として渡す
- [ ] ステータスマスタはHydration Boundaryでプリフェッチ
- [ ] Suspense境界をOrderTable周辺に配置
## 出力要求
1. page.tsx
2. loading.tsx(OrderTableSkeletonを使用)
3. error.tsx(リトライボタン付き)
4. generateMetadata関数
## Suspense設計
┌─ page.tsx (Server) ─────────────────────────────────┐ │ Breadcrumb │ │ OrderSearchBar (Client) │ │ OrderFilterPanel (Client) │ │ ┌─ Suspense fallback={OrderTableSkeleton} ──────┐ │ │ │ OrderTable (Client) │ │ │ └───────────────────────────────────────────────┘ │ │ BulkActionBar (Client, conditional) │ │ OrderDetailModal (Client, conditional) │ └─────────────────────────────────────────────────────┘
# UI Component生成依頼
## コンポーネント情報
- **名前**: OrderStatusBadge
- **配置先**: `components/ui/order-status-badge.tsx`
- **基本境界**: Client Component
## 要件
### 機能概要
注文ステータスを視覚的に区別するためのバッジコンポーネント。既存のBadgeコンポーネントを拡張し、注文ステータス固有のカラーバリアントを追加。
### Variants
| variant名 | 説明 | スタイル概要 |
|-----------|------|-------------|
| new | 新規注文 | bg-blue-100 text-blue-800 border-blue-200 |
| processing | 処理中 | bg-yellow-100 text-yellow-800 border-yellow-200 |
| shipped | 発送済 | bg-purple-100 text-purple-800 border-purple-200 |
| completed | 完了 | bg-green-100 text-green-800 border-green-200 |
| cancelled | キャンセル | bg-gray-100 text-gray-500 border-gray-200 line-through |
### Sizes
| size名 | 説明 |
|--------|------|
| sm | テーブル行内表示用(text-xs py-0.5 px-2) |
| md | モーダル・詳細画面用(text-sm py-1 px-3) |
## 制約条件
- [ ] 既存Badge(components/ui/badge.tsx)を継承・拡張
- [ ] ビジネスロジックを含めない(ステータスコードとvariantのマッピングのみ)
- [ ] CVA(class-variance-authority)でvariantsを定義
- [ ] forwardRefでref転送に対応
- [ ] aria-label="ステータス: {ステータス名}"を設定
## 出力要求
1. コンポーネント実装(.tsx)
2. 型定義(Props Interface:status: OrderStatus, size?: 'sm' | 'md')
3. Storybook(.stories.tsx):全variant × 全size
4. ステータスコードとvariantのマッピングユーティリティ
## 参考:既存のshadcn/uiコンポーネント
components/ui/badge.tsx
# Form Component生成依頼
## コンポーネント情報
- **名前**: StatusSelect
- **配置先**: `components/forms/status-select.tsx`
- **基本境界**: Client Component('use client'必須)
## 要件
### 入力仕様
| プロパティ | 型 | 必須 | 説明 |
|-----------|-----|------|------|
| value | string \| null | ❌ | 選択中のステータスコード(null = 全て) |
| onChange | (value: string \| null) => void | ✅ | 選択変更時コールバック |
| options | StatusOption[] | ✅ | 選択肢リスト(APIから取得したマスタ) |
| placeholder | string | ❌ | 未選択時のプレースホルダー(デフォルト: "全て") |
| disabled | boolean | ❌ | 無効化フラグ |
| includeAll | boolean | ❌ | "全て"オプションを含めるか(デフォルト: true) |
### バリデーションルール
| ルール | 条件 | エラーメッセージ |
|--------|------|-----------------|
| 有効値 | optionsに存在するvalue | 無効なステータスが選択されています |
### 状態
- [x] disabled
- [ ] loading(オプションは親から渡されるため不要)
- [x] error表示
- [ ] ヒントテキスト
## 制約条件
- [ ] Zodスキーマを定義(statusSchema)
- [ ] React Hook FormのControllerと連携可能な設計(name, control propsに対応)
- [ ] aria-invalid, aria-describedbyでアクセシビリティ対応
- [ ] 既存Select(components/ui/select.tsx)をラップ
## 出力要求
1. コンポーネント実装(.tsx)
2. Zodスキーマ定義(status-select.schema.ts)
3. Props Interface
4. Storybook(default, selected, disabled状態)
5. React Hook Formとの連携例
# Form Component生成依頼
## コンポーネント情報
- **名前**: DateRangePicker
- **配置先**: `components/forms/date-range-picker.tsx`
- **基本境界**: Client Component('use client'必須)
## 要件
### 入力仕様
| プロパティ | 型 | 必須 | 説明 |
|-----------|-----|------|------|
| startDate | Date \| null | ❌ | 開始日 |
| endDate | Date \| null | ❌ | 終了日 |
| onStartDateChange | (date: Date \| null) => void | ✅ | 開始日変更コールバック |
| onEndDateChange | (date: Date \| null) => void | ✅ | 終了日変更コールバック |
| minDate | Date | ❌ | 選択可能な最小日付 |
| maxDate | Date | ❌ | 選択可能な最大日付(デフォルト: 今日) |
| disabled | boolean | ❌ | 無効化フラグ |
| presets | Preset[] | ❌ | プリセット選択肢(今日、過去7日、今月など) |
### バリデーションルール
| ルール | 条件 | エラーメッセージ |
|--------|------|-----------------|
| 日付順序 | startDate <= endDate | 開始日は終了日以前を選択してください |
| 範囲制限 | minDate <= value <= maxDate | 選択可能な期間外です |
### 状態
- [x] disabled
- [ ] loading
- [x] error表示(日付順序エラー時)
- [ ] ヒントテキスト
## 制約条件
- [ ] Zodスキーマを定義(dateRangeSchema)
- [ ] 既存DatePicker(components/forms/date-picker.tsx)を2つ組み合わせ
- [ ] aria-invalid, aria-describedbyでアクセシビリティ対応
- [ ] 日付フォーマット: YYYY/MM/DD
## 出力要求
1. コンポーネント実装(.tsx)
2. Zodスキーマ定義(日付範囲のリファインメント付き)
3. Props Interface
4. Storybook(default, with-presets, error, disabled状態)
5. プリセットボタン群のUI(今日、過去7日、過去30日、今月)
# Layout Component生成依頼
## コンポーネント情報
- **名前**: OrderListLayout
- **配置先**: `components/layouts/order-list-layout.tsx`
- **基本境界**: Server Component
## 要件
### レイアウト構造
┌─────────────────────────────────────────────────────────┐ │ {breadcrumb} │ ├─────────────────────────────────────────────────────────┤ │ {searchBar} │ ├─────────────────────────────────────────────────────────┤ │ {filterPanel} │ ├─────────────────────────────────────────────────────────┤ │ │ │ {children} ← メインコンテンツ(テーブル) │ │ │ ├─────────────────────────────────────────────────────────┤ │ {bulkActionBar} ← 条件付き表示 │ └─────────────────────────────────────────────────────────┘
### Slots
| slot名 | 説明 | 必須 |
|--------|------|------|
| breadcrumb | パンくずリスト | ❌ |
| searchBar | 検索バー | ✅ |
| filterPanel | フィルターパネル | ✅ |
| children | メインコンテンツ(テーブル) | ✅ |
| bulkActionBar | 一括操作バー | ❌ |
### レスポンシブ対応
| ブレークポイント | 挙動 |
|-----------------|------|
| mobile (<768px) | 検索バーとフィルターパネルを縦積み、フィルターは折りたたみ可 |
| tablet (768-1024px) | 検索バーとフィルターパネルを縦積み |
| desktop (>1024px) | 検索バーとフィルターパネルを横並び可能 |
## 制約条件
- [ ] Server Componentとして実装
- [ ] childrenでClient Componentを受け入れ可能
- [ ] Tailwind CSSでレスポンシブ対応
- [ ] 各slot間に適切なgap(space-y-4)
- [ ] max-w-7xl mx-auto でコンテンツ幅制限
## 出力要求
1. コンポーネント実装(.tsx)
2. Props Interface
3. Storybook(desktop, tablet, mobile表示)
4. 使用例
# Shared Component生成依頼
## コンポーネント情報
- **名前**: CustomerInfoSection
- **配置先**: `components/shared/customer-info-section.tsx`
- **基本境界**: Client Component
## 要件
### 機能概要
顧客の基本情報(名前、メール、電話番号)を定義リスト形式で表示するセクションコンポーネント。注文詳細モーダル以外でも顧客情報表示が必要な場面で再利用可能。
### Props設計
| プロパティ | 型 | 必須 | デフォルト | 説明 |
|-----------|-----|------|-----------|------|
| name | string | ✅ | - | 顧客名 |
| email | string | ✅ | - | メールアドレス |
| phone | string | ❌ | - | 電話番号 |
| variant | 'default' \| 'compact' | ❌ | 'default' | 表示バリアント |
| showCopyButtons | boolean | ❌ | false | コピーボタン表示 |
### 使用箇所
1. OrderDetailModal: 注文詳細の顧客情報セクション
2. 将来: 顧客管理画面の顧客カード
## 制約条件
- [ ] 特定のfeatureに依存しない
- [ ] 必要なデータはすべてPropsで受け取る
- [ ] メール・電話のクリックでデフォルトアプリ起動(mailto:, tel:)
- [ ] APIコール禁止
## 出力要求
1. コンポーネント実装(.tsx)
2. Props Interface
3. Storybook(default, compact, with-copy-buttons)
4. 単体テスト
## Server/Client判定理由
コピーボタンのクリックイベント、mailto:/tel:リンクのインタラクションがあるためClient Component
# Shared Component生成依頼
## コンポーネント情報
- **名前**: OrderTableSkeleton
- **配置先**: `components/shared/order-table-skeleton.tsx`
- **基本境界**: Server Component
## 要件
### 機能概要
注文テーブルのローディング状態を表示するスケルトンUI。テーブル構造を維持しつつ、データ取得中であることを視覚的に示す。
### Props設計
| プロパティ | 型 | 必須 | デフォルト | 説明 |
|-----------|-----|------|-----------|------|
| rows | number | ❌ | 5 | 表示するスケルトン行数 |
| columns | number | ❌ | 6 | 表示するカラム数 |
| showCheckbox | boolean | ❌ | true | チェックボックス列を表示 |
| showActions | boolean | ❌ | true | 操作列を表示 |
### 使用箇所
1. app/orders/loading.tsx: ページ初期ローディング
2. OrderTable: データ再取得時のインライン表示
## 制約条件
- [ ] 既存Skeleton(components/ui/skeleton.tsx)を使用
- [ ] 既存Table(components/ui/table.tsx)の構造を維持
- [ ] アニメーション: pulse効果
- [ ] APIコール禁止
## 出力要求
1. コンポーネント実装(.tsx)
2. Props Interface
3. Storybook(default, minimal-columns)
4. 単体テスト
## Server/Client判定理由
純粋なプレゼンテーションコンポーネント、状態・イベントなしのためServer Component
# Shared Component生成依頼
## コンポーネント情報
- **名前**: OrderListEmptyState
- **配置先**: `components/shared/order-list-empty-state.tsx`
- **基本境界**: Server Component
## 要件
### 機能概要
検索・フィルター結果が0件の場合に表示する空状態コンポーネント。既存EmptyStateを注文一覧用にプリセット。
### Props設計
| プロパティ | 型 | 必須 | デフォルト | 説明 |
|-----------|-----|------|-----------|------|
| variant | 'no-results' \| 'no-orders' | ❌ | 'no-results' | 表示バリアント |
| onReset | () => void | ❌ | - | フィルターリセットコールバック |
### 使用箇所
1. OrderTable: 検索結果0件時
## 制約条件
- [ ] 既存EmptyState(components/shared/empty-state.tsx)をラップ
- [ ] アイコン: Search(no-results), Package(no-orders)
- [ ] APIコール禁止
## 出力要求
1. コンポーネント実装(.tsx)
2. Props Interface
3. Storybook(no-results, no-orders)
4. 単体テスト
## Server/Client判定理由
onResetコールバックがオプショナルで、基本は表示のみのためServer Component。onReset使用時は親がClient Componentとなる。
# Feature Component生成依頼
## コンポーネント情報
- **名前**: OrderSearchBar
- **配置先**: `features/orders/components/order-search-bar.tsx`
- **関連ファイル**:
- hooks: `features/orders/hooks/use-order-search.ts`
- types: `features/orders/types.ts`
## 要件
### 機能概要
注文番号・顧客名によるキーワード検索を行うフォームコンポーネント。検索キーワードはURLクエリパラメータと同期し、ブラウザの戻る/進むで状態が復元される。
### データ要件
| データ | ソース | 取得方法 |
|--------|--------|----------|
| 検索キーワード | URL query `?q=` | nuqs useQueryState |
### 状態管理
| 状態 | スコープ | 管理方法 |
|------|----------|----------|
| inputValue | ローカル | useState(デバウンス用) |
| searchQuery | URL | nuqs useQueryState |
### API連携
なし(URL変更によりOrderTableがデータ再取得)
### イベント
| イベント | トリガー | 処理内容 |
|---------|----------|----------|
| onInputChange | input入力 | ローカル状態更新 |
| onSearch | 検索ボタンクリック / Enter | URL query更新 |
| onClear | クリアボタンクリック | 入力クリア、URL query削除 |
## 制約条件
- [ ] デバウンス: 300ms(入力中のURL更新抑制)
- [ ] 空文字での検索時はqueryパラメータ削除
- [ ] 既存Input、Buttonコンポーネントを使用
- [ ] アクセシビリティ: role="search"、aria-label
## 出力要求
1. コンポーネント実装(.tsx)
2. カスタムフック(use-order-search.ts)
3. 型定義
4. Storybook(empty, with-value, searching状態)
5. 単体テスト
## エラーハンドリング方針
URLクエリ更新は同期的で失敗しないため、エラーハンドリング不要
# Feature Component生成依頼
## コンポーネント情報
- **名前**: OrderFilterPanel
- **配置先**: `features/orders/components/order-filter-panel.tsx`
- **関連ファイル**:
- hooks: `features/orders/hooks/use-order-filters.ts`
- types: `features/orders/types.ts`
## 要件
### 機能概要
ステータス・期間によるフィルタリングを行うパネルコンポーネント。フィルター条件はURLクエリパラメータと同期。CSV出力ボタンも配置。
### データ要件
| データ | ソース | 取得方法 |
|--------|--------|----------|
| ステータスフィルター | URL query `?status=` | nuqs useQueryState |
| 開始日 | URL query `?from=` | nuqs useQueryState |
| 終了日 | URL query `?to=` | nuqs useQueryState |
| ステータスマスタ | Props(親からprefetch済み) | - |
### 状態管理
| 状態 | スコープ | 管理方法 |
|------|----------|----------|
| localStatus | ローカル | useState(適用前のドラフト) |
| localDateRange | ローカル | useState(適用前のドラフト) |
| urlFilters | URL | nuqs useQueryStates |
### API連携
なし(URL変更によりOrderTableがデータ再取得)
### イベント
| イベント | トリガー | 処理内容 |
|---------|----------|----------|
| onApply | フィルター適用ボタン | ローカル状態 → URL query |
| onReset | リセットボタン | 全フィルターをクリア |
## 制約条件
- [ ] StatusSelect、DateRangePickerコンポーネントを使用
- [ ] 既存Buttonコンポーネントを使用
- [ ] フィルター適用前は確定しない(明示的なApplyボタン)
- [ ] リセット時はページ番号も1にリセット
## 出力要求
1. コンポーネント実装(.tsx)
2. カスタムフック(use-order-filters.ts)
3. 型定義
4. Storybook(default, with-filters-applied状態)
5. 単体テスト
## エラーハンドリング方針
URLクエリ更新は同期的で失敗しないため、エラーハンドリング不要
# Feature Component生成依頼
## コンポーネント情報
- **名前**: OrderTable
- **配置先**: `features/orders/components/order-table.tsx`
- **関連ファイル**:
- hooks: `features/orders/hooks/use-orders.ts`
- actions: なし(参照のみ)
- types: `features/orders/types.ts`
## 要件
### 機能概要
注文一覧をテーブル形式で表示。ソート、ページネーション、行選択、行クリックによる詳細モーダル起動を行う。
### データ要件
| データ | ソース | 取得方法 |
|--------|--------|----------|
| 注文一覧 | REST API `/api/orders` | TanStack Query useQuery |
| 総件数 | REST API レスポンス | 同上 |
### 状態管理
| 状態 | スコープ | 管理方法 |
|------|----------|----------|
| orders | サーバー | TanStack Query |
| selectedIds | ローカル | useState (Set<string>) |
| sortColumn | URL | nuqs useQueryState |
| sortOrder | URL | nuqs useQueryState |
| page | URL | nuqs useQueryState |
### API連携
| エンドポイント | メソッド | 用途 |
|---------------|----------|------|
| GET /api/orders | GET | 注文一覧取得(URLクエリ全パラメータ連携) |
### イベント
| イベント | トリガー | 処理内容 |
|---------|----------|----------|
| onRowClick | 行クリック | onOpenDetail(orderId)コールバック |
| onSelectionChange | チェックボックス操作 | selectedIds更新 |
| onSortChange | ヘッダークリック | URL query更新 |
| onPageChange | ページネーションクリック | URL query更新 |
## 制約条件
- [ ] TanStack QueryでQuery実装(queryKey: ['orders', searchParams])
- [ ] 既存Table、Pagination、Checkbox、Skeletonを使用
- [ ] 空状態: OrderListEmptyState表示
- [ ] ローディング: OrderTableSkeleton表示
## 出力要求
1. コンポーネント実装(.tsx)
2. カスタムフック(use-orders.ts)
3. 型定義(Order, OrdersResponse, UseOrdersParams)
4. Storybook(loading, empty, with-data, with-selection)
5. 単体テスト
## エラーハンドリング方針
| エラー種別 | 表示方法 |
|-----------|----------|
| API 4xx | Toast通知 + 空状態表示 |
| API 5xx | 親のerror.tsxでキャッチ |
# Feature Component生成依頼
## コンポーネント情報
- **名前**: OrderTableHeader
- **配置先**: `features/orders/components/order-table-header.tsx`
- **関連ファイル**:
- types: `features/orders/types.ts`
## 要件
### 機能概要
テーブルヘッダー行。ソート可能なカラムにはソートインジケーター表示。一括選択チェックボックスを配置。
### データ要件
| データ | ソース | 取得方法 |
|--------|--------|----------|
| currentSort | Props | 親から |
| isAllSelected | Props | 親から |
| isIndeterminate | Props | 親から(一部選択状態) |
### 状態管理
なし(全てProps経由)
### API連携
なし
### イベント
| イベント | トリガー | 処理内容 |
|---------|----------|----------|
| onSort | ソート可能カラムクリック | onSortChange(column)コールバック |
| onSelectAll | ヘッダーチェックボックス | onSelectAllChange(checked)コールバック |
## 制約条件
- [ ] ソート可能カラム: orderId, createdAt, totalAmount
- [ ] ソートインジケーター: ChevronUp / ChevronDown / ChevronsUpDown
- [ ] 既存Checkboxを使用
- [ ] aria-sort属性を設定
## 出力要求
1. コンポーネント実装(.tsx)
2. 型定義
3. Storybook(no-selection, partial-selection, all-selected, sorted-asc, sorted-desc)
4. 単体テスト
## エラーハンドリング方針
なし(表示のみ)
# Feature Component生成依頼
## コンポーネント情報
- **名前**: OrderTableRow
- **配置先**: `features/orders/components/order-table-row.tsx`
- **関連ファイル**:
- types: `features/orders/types.ts`
## 要件
### 機能概要
テーブルの1行を表示。チェックボックス、注文データ、ステータスバッジ、操作メニューを配置。行クリックで詳細モーダル起動。
### データ要件
| データ | ソース | 取得方法 |
|--------|--------|----------|
| order | Props | 親から |
| isSelected | Props | 親から |
### 状態管理
なし(全てProps経由)
### API連携
なし
### イベント
| イベント | トリガー | 処理内容 |
|---------|----------|----------|
| onClick | 行クリック(チェックボックス・メニュー以外) | onRowClick(orderId) |
| onSelect | チェックボックスクリック | onSelectionChange(orderId, checked) |
## 制約条件
- [ ] 金額表示: Intl.NumberFormat('ja-JP', { style: 'currency', currency: 'JPY' })
- [ ] 日付表示: YYYY/MM/DD HH:mm
- [ ] OrderStatusBadge使用
- [ ] OrderActionsMenu使用
- [ ] 行ホバー時の背景色変更
- [ ] 選択行のハイライト
## 出力要求
1. コンポーネント実装(.tsx)
2. 型定義
3. Storybook(default, selected, hover状態)
4. 単体テスト
## エラーハンドリング方針
なし(表示のみ)
# Feature Component生成依頼
## コンポーネント情報
- **名前**: OrderActionsMenu
- **配置先**: `features/orders/components/order-actions-menu.tsx`
- **関連ファイル**:
- types: `features/orders/types.ts`
## 要件
### 機能概要
テーブル行の操作メニュー(…ボタン)。詳細表示、ステータス変更、注文キャンセルのアクションを提供。
### データ要件
| データ | ソース | 取得方法 |
|--------|--------|----------|
| orderId | Props | 親から |
| currentStatus | Props | 親から |
### 状態管理
| 状態 | スコープ | 管理方法 |
|------|----------|----------|
| isOpen | ローカル | useState |
### API連携
なし(アクション実行は親にコールバック)
### イベント
| イベント | トリガー | 処理内容 |
|---------|----------|----------|
| onViewDetail | 詳細表示クリック | onAction('view', orderId) |
| onChangeStatus | ステータス変更クリック | onAction('changeStatus', orderId) |
| onCancel | キャンセルクリック | onAction('cancel', orderId) |
## 制約条件
- [ ] ドロップダウンメニュー形式
- [ ] キャンセル済み注文はキャンセルアクション非表示
- [ ] イベント伝播停止(行クリックとの干渉防止)
- [ ] キーボードナビゲーション対応
## 出力要求
1. コンポーネント実装(.tsx)
2. 型定義
3. Storybook(closed, open, cancelled-order状態)
4. 単体テスト
## エラーハンドリング方針
なし(アクション実行は親の責務)
# Feature Component生成依頼
## コンポーネント情報
- **名前**: OrderDetailModal
- **配置先**: `features/orders/components/order-detail-modal.tsx`
- **関連ファイル**:
- hooks: `features/orders/hooks/use-order-detail.ts`
- actions: `features/orders/actions/update-order-status.ts`
- types: `features/orders/types.ts`
## 要件
### 機能概要
注文の詳細情報を表示し、ステータス変更を行うモーダルダイアログ。
### データ要件
| データ | ソース | 取得方法 |
|--------|--------|----------|
| 注文詳細 | REST API `/api/orders/{id}` | TanStack Query useQuery |
### 状態管理
| 状態 | スコープ | 管理方法 |
|------|----------|----------|
| orderDetail | サーバー | TanStack Query |
| isUpdating | ローカル | useMutationのisPending |
### API連携
| エンドポイント | メソッド | 用途 |
|---------------|----------|------|
| GET /api/orders/{id} | GET | 注文詳細取得 |
| PATCH /api/orders/{id}/status | PATCH | ステータス更新 |
### イベント
| イベント | トリガー | 処理内容 |
|---------|----------|----------|
| onClose | ×ボタン / 閉じるボタン / オーバーレイクリック | モーダル閉じる |
| onStatusChange | ステータスボタンクリック | ステータス更新API呼び出し |
| onSave | 変更を保存ボタン | 更新確定、モーダル閉じる |
## 制約条件
- [ ] 既存Dialog(components/ui/dialog.tsx)を使用
- [ ] 楽観的更新実装(useMutation + onMutate)
- [ ] 更新成功時: Toast通知、一覧のキャッシュ無効化
- [ ] 更新失敗時: ロールバック、Toast通知
## 出力要求
1. コンポーネント実装(.tsx)
2. カスタムフック(use-order-detail.ts)
3. Server Actions(update-order-status.ts)
4. 型定義
5. Storybook(loading, loaded, updating状態)
6. 単体テスト
## エラーハンドリング方針
| エラー種別 | 表示方法 |
|-----------|----------|
| 詳細取得失敗 | モーダル内エラー表示 + リトライボタン |
| ステータス更新4xx | Toast通知(バリデーションエラーメッセージ) |
| ステータス更新5xx | Toast通知(汎用エラー) + ロールバック |
# Feature Component生成依頼
## コンポーネント情報
- **名前**: OrderItemsSection
- **配置先**: `features/orders/components/order-items-section.tsx`
- **関連ファイル**:
- types: `features/orders/types.ts`
## 要件
### 機能概要
注文に含まれる商品リストを表示するセクション。商品名、数量、小計、合計金額を表示。
### データ要件
| データ | ソース | 取得方法 |
|--------|--------|----------|
| items | Props | 親から(OrderDetail.items) |
| totalAmount | Props | 親から(OrderDetail.totalAmount) |
### 状態管理
なし(全てProps経由)
### API連携
なし
### イベント
なし(表示のみ)
## 制約条件
- [ ] 金額表示: Intl.NumberFormat('ja-JP', { style: 'currency', currency: 'JPY' })
- [ ] 商品画像サムネイル表示(あれば)
- [ ] 合計行は視覚的に区別(太字、上線)
## 出力要求
1. コンポーネント実装(.tsx)
2. 型定義(OrderItem)
3. Storybook(single-item, multiple-items状態)
4. 単体テスト
## エラーハンドリング方針
なし(表示のみ)
# Feature Component生成依頼
## コンポーネント情報
- **名前**: StatusChangeButtons
- **配置先**: `features/orders/components/status-change-buttons.tsx`
- **関連ファイル**:
- types: `features/orders/types.ts`
## 要件
### 機能概要
注文ステータスを変更するためのボタン群。現在のステータスはハイライト表示。
### データ要件
| データ | ソース | 取得方法 |
|--------|--------|----------|
| currentStatus | Props | 親から |
| statuses | Props | 親から(ステータスマスタ) |
| isUpdating | Props | 親から(更新中フラグ) |
### 状態管理
なし(全てProps経由)
### API連携
なし(更新処理は親にコールバック)
### イベント
| イベント | トリガー | 処理内容 |
|---------|----------|----------|
| onStatusSelect | ステータスボタンクリック | onStatusChange(newStatus)コールバック |
## 制約条件
- [ ] 現在のステータスはvariant="default"、他はvariant="outline"
- [ ] 更新中は全ボタンdisabled + 選択中ボタンにローディングスピナー
- [ ] キャンセル→他ステータスへの変更は警告ダイアログ表示
- [ ] OrderStatusBadge使用可(ボタン内にバッジ表示する場合)
## 出力要求
1. コンポーネント実装(.tsx)
2. 型定義
3. Storybook(各ステータス状態、updating状態)
4. 単体テスト
## エラーハンドリング方針
なし(更新処理は親の責務)
# Feature Component生成依頼
## コンポーネント情報
- **名前**: BulkActionBar
- **配置先**: `features/orders/components/bulk-action-bar.tsx`
- **関連ファイル**:
- hooks: `features/orders/hooks/use-bulk-status-update.ts`
- actions: `features/orders/actions/bulk-update-status.ts`
- types: `features/orders/types.ts`
## 要件
### 機能概要
複数注文を選択した際に表示される一括操作バー。選択件数表示、一括ステータス変更、選択解除を行う。
### データ要件
| データ | ソース | 取得方法 |
|--------|--------|----------|
| selectedIds | Props | 親から |
| statuses | Props | 親から(ステータスマスタ) |
### 状態管理
| 状態 | スコープ | 管理方法 |
|------|----------|----------|
| isUpdating | サーバー | useMutationのisPending |
### API連携
| エンドポイント | メソッド | 用途 |
|---------------|----------|------|
| PATCH /api/orders/bulk-status | PATCH | 一括ステータス更新 |
### イベント
| イベント | トリガー | 処理内容 |
|---------|----------|----------|
| onBulkStatusChange | ステータス選択 → 適用 | 一括更新API呼び出し |
| onClearSelection | 選択解除ボタン | onClearSelection()コールバック |
## 制約条件
- [ ] selectedIds.size === 0 の場合は非表示(親で制御)
- [ ] 画面下部に固定表示(sticky bottom-0)
- [ ] StatusSelectで新ステータス選択 → 適用ボタンで実行
- [ ] 楽観的更新実装
## 出力要求
1. コンポーネント実装(.tsx)
2. カスタムフック(use-bulk-status-update.ts)
3. Server Actions(bulk-update-status.ts)
4. 型定義
5. Storybook(default, updating状態)
6. 単体テスト
## エラーハンドリング方針
| エラー種別 | 表示方法 |
|-----------|----------|
| 一部失敗 | Toast通知(成功N件、失敗M件) |
| 全件失敗 | Toast通知(エラーメッセージ) |
# Feature Component生成依頼
## コンポーネント情報
- **名前**: CsvExportButton
- **配置先**: `features/orders/components/csv-export-button.tsx`
- **関連ファイル**:
- hooks: `features/orders/hooks/use-csv-export.ts`
- types: `features/orders/types.ts`
## 要件
### 機能概要
現在のフィルター条件を反映したCSVファイルをダウンロードするボタン。
### データ要件
| データ | ソース | 取得方法 |
|--------|--------|----------|
| currentFilters | Props | 親から(現在のURLクエリパラメータ) |
### 状態管理
| 状態 | スコープ | 管理方法 |
|------|----------|----------|
| isExporting | ローカル | useState |
### API連携
| エンドポイント | メソッド | 用途 |
|---------------|----------|------|
| GET /api/orders/export | GET | CSVダウンロード(Blobレスポンス) |
### イベント
| イベント | トリガー | 処理内容 |
|---------|----------|----------|
| onClick | ボタンクリック | CSVダウンロード開始 |
## 制約条件
- [ ] ファイル名: orders_YYYYMMDD_HHmmss.csv
- [ ] Blobダウンロード形式
- [ ] ダウンロード中はボタンdisabled + ローディングスピナー
- [ ] 大量データ(1000件以上)の場合は確認ダイアログ
## 出力要求
1. コンポーネント実装(.tsx)
2. カスタムフック(use-csv-export.ts)
3. 型定義
4. Storybook(default, exporting状態)
5. 単体テスト
## エラーハンドリング方針
| エラー種別 | 表示方法 |
|-----------|----------|
| タイムアウト | Toast通知(時間をおいて再試行) |
| サーバーエラー | Toast通知(汎用エラー) |