# 画面設計書 2-ホーム画面

## 概要

本ドキュメントは、Bagisto eコマースモバイルアプリのホーム画面に関する設計書です。アプリのメイン画面として、商品カテゴリ、新商品、おすすめ商品、バナー等を表示し、ユーザーが商品を閲覧・購入するための起点となる重要な画面です。

### 本画面の処理概要

**業務上の目的・背景**：ホーム画面は、eコマースアプリにおけるユーザーの最初の接点となる画面です。商品の発見性を高め、プロモーションバナーやおすすめ商品を効果的に表示することで、購買意欲を促進し、売上向上に貢献します。また、ドロワーメニューを通じて各種機能へのアクセスポイントを提供し、アプリ全体のナビゲーションハブとしての役割を果たします。

**画面へのアクセス方法**：
- スプラッシュ画面から初期化完了後に自動遷移
- ボトムナビゲーションの「ホーム」タブをタップ
- 各画面からのバックナビゲーション
- 通貨・言語変更後のアプリ再起動時

**主要な操作・処理内容**：
1. テーマカスタマイズデータ（バナー、カルーセル等）の取得と表示
2. カテゴリ一覧の取得と横スクロール表示
3. 商品カルーセル（新商品、おすすめ商品等）の動的表示
4. 商品のカートへの追加
5. 商品のウィッシュリストへの追加/削除
6. 商品の比較リストへの追加
7. ニュースレターの購読登録
8. プルリフレッシュによるデータ再取得
9. ドロワーメニューによるナビゲーション

**画面遷移**：
- 遷移元：スプラッシュ画面、ダッシュボード画面、サインイン画面（ログイン成功後）、各種画面からのバック
- 遷移先：商品詳細画面、カテゴリ商品一覧画面、サブカテゴリ画面、検索画面、カート画面、サインイン画面

**権限による表示制御**：
- ログインユーザー：ウィッシュリスト・比較リスト機能が完全に利用可能
- 未ログインユーザー：ウィッシュリスト・比較リスト操作時にログイン促進メッセージを表示

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 6 | ホームページ表示 | 主機能 | カテゴリ・バナー・新着商品等のホーム画面コンテンツを表示 |
| 7 | テーマカスタマイズ取得 | 補助機能 | CMSから設定されたテーマ・バナー情報を取得してUI表示に反映 |
| 8 | カテゴリ一覧取得 | 補助機能 | ドロワーおよびホーム画面用のカテゴリ一覧を取得 |
| 9 | ニュースレター登録 | 補助機能 | メールアドレスによるニュースレター購読登録 |
| 20 | カートに追加 | API連携 | ホーム画面から商品を直接カートに追加 |
| 28 | ウィッシュリストに追加 | API連携 | ホーム画面から商品をお気に入りに追加 |
| 33 | 比較リストに追加 | API連携 | ホーム画面から商品を比較リストに追加 |
| 72 | ナビゲーションドロワー | 補助機能 | サイドメニューによるナビゲーション表示 |

## 画面種別

メイン画面（ポータル/ダッシュボード型）

## URL/ルーティング

- ルート名: `home` (homeScreen)
- パス: `/home`

## 入出力項目

| 項目名 | 入出力 | データ型 | 必須 | 説明 |
|--------|--------|----------|------|------|
| ニュースレターメール | 入力 | String | - | ニュースレター購読用メールアドレス |

## 表示項目

| 項目名 | データ型 | 説明 |
|--------|----------|------|
| アプリ名 | String | AppBarに表示されるアプリケーション名 |
| 画像カルーセル | List<Widget> | プロモーションバナーのスライダー |
| カテゴリ一覧 | List<HomeCategories> | 横スクロール可能なカテゴリアイコン一覧 |
| 商品カルーセル | List<NewProducts> | カテゴリ別商品の横スクロールリスト |
| 商品名 | String | 各商品カードに表示される商品名 |
| 商品価格 | String (HTML) | 価格HTML（セール価格・通常価格） |
| 商品画像 | String (URL) | 商品サムネイル画像 |
| セールバッジ | Widget | セール中の商品に表示されるバッジ |
| 新着バッジ | Widget | 新着商品に表示されるバッジ |
| サービスコンテンツ | List<Service> | 店舗サービス情報（配送、返品等） |
| 静的コンテンツ | HTML/CSS | CMSで設定された静的コンテンツ |
| フッターリンク | List<Link> | フッターに表示されるリンク一覧 |
| 最近閲覧した商品 | List<NewProducts> | ユーザーが最近閲覧した商品一覧 |

## イベント仕様

### 1-画面初期化イベント（initState）

**トリガー**: 画面がマウントされたタイミング

**処理フロー**:
1. `_registerStreamListener()`でプロダクトストリームのリスナー登録
2. `_fetchSharedPreferenceData()`でログイン状態・ユーザー情報を取得
3. `DrawerBloc`の取得
4. `getCartCount()`でカート数を取得しグローバルコントローラーに通知
5. 言語・通貨設定の取得
6. `fetchHomepageData()`でホームページデータを取得
7. `fetchOfflineProductData()`でオフラインカテゴリデータを取得

### 2-テーマカスタマイズデータ取得イベント

**トリガー**: initState時、プルリフレッシュ時

**処理フロー**:
1. `HomePageBloc`に`FetchHomeCustomData`イベントを送信
2. `repository.getThemeCustomizationData()`でAPI呼び出し
3. 取得したデータを`ThemeCustomDataModel`としてパース
4. `FetchHomeCustomDataState`として状態を更新
5. データに基づいて動的にUIウィジェットを構築

### 3-カートに追加イベント

**トリガー**: 商品カードの「カートに追加」ボタンタップ

**処理フロー**:
1. `OnClickLoaderEvent`でローダー表示
2. `AddToCartEvent`を送信
3. `repository.callAddToCartAPi()`でAPI呼び出し
4. 成功時：成功メッセージを表示、カート数を更新
5. 失敗時：エラーメッセージを表示

### 4-ウィッシュリスト追加/削除イベント

**トリガー**: 商品カードのハートアイコンタップ

**処理フロー**:
1. ログイン状態を確認
2. 未ログインの場合：警告メッセージを表示
3. ログイン済みの場合：
   - ウィッシュリストに存在する場合：`RemoveWishlistItemEvent`を送信
   - 存在しない場合：`FetchAddWishlistHomepageEvent`を送信
4. API呼び出し実行
5. 結果に応じてメッセージを表示、商品の`isInWishlist`フラグを更新

### 5-比較リスト追加イベント

**トリガー**: 商品カードの比較アイコンタップ

**処理フロー**:
1. ログイン状態を確認
2. 未ログインの場合：警告メッセージを表示
3. ログイン済みの場合：`AddToCompareHomepageEvent`を送信
4. API呼び出し実行
5. 結果に応じてメッセージを表示

### 6-ニュースレター購読イベント

**トリガー**: ニュースレター登録フォームの送信

**処理フロー**:
1. `SubscribeNewsLetterEvent`を送信
2. `repository.subscribeNewsletter()`でAPI呼び出し
3. 成功/失敗に応じてメッセージを表示

### 7-プルリフレッシュイベント

**トリガー**: 画面を下に引っ張る操作

**処理フロー**:
1. `HomePageBloc`に`FetchHomeCustomData`イベントを送信
2. 4秒のディレイ後にリフレッシュインジケーターを非表示

## データベース更新仕様

### 操作別データベース影響一覧

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| カートに追加 | cart_items | INSERT/UPDATE | 商品をカートに追加または数量更新 |
| ウィッシュリストに追加 | wishlist_items | INSERT | 商品をウィッシュリストに追加 |
| ウィッシュリストから削除 | wishlist_items | DELETE | 商品をウィッシュリストから削除 |
| 比較リストに追加 | compare_items | INSERT | 商品を比較リストに追加 |
| ニュースレター登録 | subscribers | INSERT | メールアドレスを購読者リストに追加 |

※ 上記はサーバーサイドのデータベース操作です。モバイルアプリ側ではSharedPreferencesに以下を保存：
- カート数（cartCount）
- ドロワーカテゴリ（drawerCategories）
- ユーザー情報（customerDetails, customerImage）

## メッセージ仕様

| メッセージID | メッセージ種別 | 表示条件 | メッセージ内容 |
|-------------|--------------|----------|--------------|
| MSG-001 | 成功 | カート追加成功時 | APIから返却されるメッセージ |
| MSG-002 | エラー | カート追加失敗時 | graphqlErrorsまたはエラーメッセージ |
| MSG-003 | 成功 | ウィッシュリスト追加成功時 | APIから返却されるメッセージ |
| MSG-004 | エラー | ウィッシュリスト操作失敗時 | graphqlErrorsまたはエラーメッセージ |
| MSG-005 | 成功 | 比較リスト追加成功時 | APIから返却されるメッセージ |
| MSG-006 | エラー | 比較リスト追加失敗時 | graphqlErrorsまたはエラーメッセージ |
| MSG-007 | 警告 | 未ログイン時の操作 | ログインを促すメッセージ |
| MSG-008 | 成功 | ニュースレター登録成功時 | APIから返却されるメッセージ |
| MSG-009 | エラー | ニュースレター登録失敗時 | graphqlErrorsまたはエラーメッセージ |

## 例外処理

| 例外ケース | 処理内容 | ユーザーへの影響 |
|-----------|---------|----------------|
| テーマカスタマイズ取得失敗 | エラー状態をemit、ローダー表示継続 | ホームページが空白または古いデータ表示 |
| 商品データ取得失敗 | エラー状態をemit | 商品カルーセルが表示されない |
| カート追加失敗 | エラーメッセージ表示 | カートに商品が追加されない |
| ウィッシュリスト操作失敗 | エラーメッセージ表示 | ウィッシュリスト状態が変更されない |
| ネットワークエラー | エラーメッセージ表示 | 各種操作が失敗 |

## 備考

- ホーム画面のコンテンツはCMSで設定されたテーマカスタマイズに基づいて動的に生成される
- 対応するコンテンツタイプ：image_carousel, category_carousel, product_carousel, static_content, services_content, footer_links
- GlobalData.allProductsに商品データをIDをキーとしてキャッシュ
- 最近閲覧した商品はHiveデータベースに保存され、画面下部に表示

---

## コードリーディングガイド

本画面を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | theme_customization.dart | `lib/screens/home_page/data_model/theme_customization.dart` | テーマカスタマイズのデータモデル構造 |
| 1-2 | new_product_data.dart | `lib/screens/home_page/data_model/new_product_data.dart` | 商品データモデルの構造 |
| 1-3 | get_categories_drawer_data_model.dart | `lib/screens/home_page/data_model/get_categories_drawer_data_model.dart` | カテゴリデータモデルの構造 |

**読解のコツ**: ThemeCustomDataModelのthemeCustomizationリストが画面の各セクションに対応。typeフィールドで表示内容が決定される。

#### Step 2: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | home_page.dart | `lib/screens/home_page/home_page.dart` | 画面のメインウィジェットとライフサイクル |

**主要処理フロー**:
1. **35-48行目**: `initState()`で各種初期化処理を実行
2. **54-57行目**: `fetchHomepageData()`でHomePageBlocにイベント送信
3. **68-74行目**: `buildUI()`でScaffold構築、ドロワーとボディ設定
4. **77-117行目**: `_drawerData()`でDrawerBlocのBlocConsumer
5. **120-174行目**: `buildView()`でHomePageBlocのBlocConsumer
6. **177-285行目**: `buildContainer()`で各状態に応じたUI構築
7. **325-358行目**: `getHomePageData()`でテーマカスタマイズに基づくイベント発行

#### Step 3: Blocレイヤーを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | home_page_bloc.dart | `lib/screens/home_page/bloc/home_page_bloc.dart` | イベント処理とステート管理 |
| 3-2 | home_page_event.dart | `lib/screens/home_page/bloc/home_page_event.dart` | イベント定義 |
| 3-3 | home_page_state.dart | `lib/screens/home_page/bloc/home_page_state.dart` | 状態定義 |

**主要処理フロー**:
- **115-126行目**: `FetchHomeCustomData`イベントでテーマデータ取得
- **127-141行目**: `FetchAllProductsEvent`で商品データ取得
- **163-172行目**: `FetchHomePageCategoriesEvent`でカテゴリデータ取得
- **28-43行目**: `AddToCartEvent`でカート追加処理

#### Step 4: ビューレイヤーを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | home_page_view.dart | `lib/screens/home_page/widget/home_page_view.dart` | メインビューの構築ロジック |
| 4-2 | new_product_view.dart | `lib/screens/home_page/widget/new_product_view.dart` | 商品カルーセルの表示 |
| 4-3 | carousal_slider.dart | `lib/screens/home_page/widget/carousal_slider.dart` | 画像スライダーの実装 |

**主要処理フロー**:
- **154-229行目**: `getHomepageView()`でテーマカスタマイズに基づくウィジェット生成
- **84-152行目**: `buildCategories()`でカテゴリ一覧の構築

### プログラム呼び出し階層図

```
HomeScreen (StatefulWidget)
    │
    ├─ initState()
    │      ├─ _registerStreamListener()
    │      ├─ _fetchSharedPreferenceData()
    │      ├─ DrawerBloc (context.read)
    │      ├─ getCartCount()
    │      ├─ fetchHomepageData()
    │      │      └─ HomePageBloc.add(FetchHomeCustomData())
    │      └─ fetchOfflineProductData()
    │
    ├─ build() → buildUI()
    │      ├─ Scaffold
    │      │      ├─ CommonAppBar
    │      │      ├─ _drawerData() → DrawerListView
    │      │      └─ buildView() → BlocConsumer<HomePageBloc>
    │      │             └─ buildContainer()
    │      │                    └─ HomePageView
    │      │                           └─ getHomepageView()
    │      │                                  ├─ CarousalSlider
    │      │                                  ├─ buildCategories()
    │      │                                  ├─ NewProductView
    │      │                                  ├─ StaticContentWidget
    │      │                                  ├─ ServiceGridScreen
    │      │                                  └─ FooterColumnsScreen
    │      │
    │      └─ HomePageBloc
    │             ├─ FetchHomeCustomData → getThemeCustomizationData()
    │             ├─ FetchAllProductsEvent → getAllProducts()
    │             ├─ FetchHomePageCategoriesEvent → getHomeCategoriesList()
    │             ├─ AddToCartEvent → callAddToCartAPi()
    │             ├─ FetchAddWishlistHomepageEvent → addItemToWishlist()
    │             ├─ RemoveWishlistItemEvent → removeItemFromWishlist()
    │             └─ AddToCompareHomepageEvent → callAddToCompareListApi()
    │
    └─ getHomePageData()
           └─ themeCustomization.forEach()
                  ├─ category_carousel → FetchHomePageCategoriesEvent
                  └─ product_carousel → FetchAllProductsEvent
```

### データフロー図

```
[入力]                    [処理]                         [出力]

アプリ起動 ──────────────▶ FetchHomeCustomData ─────────▶ ThemeCustomDataModel
                                │
                                ▼
ThemeCustomDataModel ────▶ getHomePageData() ──────────▶ FetchAllProductsEvent
                                │                             │
                                │                             ▼
                                │                      NewProductsModel
                                │                             │
                                ▼                             ▼
                         FetchHomePageCategoriesEvent    GlobalData.allProducts
                                │
                                ▼
                         GetDrawerCategoriesData
                                │
                                ▼
                         HomePageView.getHomepageView()
                                │
                                ▼
                         [動的UI構築]

商品操作 ─────────────────▶ AddToCartEvent ─────────────▶ カート更新
                         ▶ FetchAddWishlistHomepageEvent ─▶ ウィッシュリスト更新
                         ▶ AddToCompareHomepageEvent ────▶ 比較リスト更新
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| home_page.dart | `lib/screens/home_page/home_page.dart` | ソース | ホーム画面のメインウィジェット |
| home_page_bloc.dart | `lib/screens/home_page/bloc/home_page_bloc.dart` | ソース | 状態管理Bloc |
| home_page_event.dart | `lib/screens/home_page/bloc/home_page_event.dart` | ソース | イベント定義 |
| home_page_state.dart | `lib/screens/home_page/bloc/home_page_state.dart` | ソース | 状態定義 |
| home_page_repository.dart | `lib/screens/home_page/bloc/home_page_repository.dart` | ソース | データ取得リポジトリ |
| home_page_view.dart | `lib/screens/home_page/widget/home_page_view.dart` | ソース | メインビュー構築 |
| new_product_view.dart | `lib/screens/home_page/widget/new_product_view.dart` | ソース | 商品カルーセル表示 |
| carousal_slider.dart | `lib/screens/home_page/widget/carousal_slider.dart` | ソース | 画像スライダー |
| theme_customization.dart | `lib/screens/home_page/data_model/theme_customization.dart` | ソース | テーマデータモデル |
| new_product_data.dart | `lib/screens/home_page/data_model/new_product_data.dart` | ソース | 商品データモデル |
| get_categories_drawer_data_model.dart | `lib/screens/home_page/data_model/get_categories_drawer_data_model.dart` | ソース | カテゴリデータモデル |
| index.dart | `lib/screens/home_page/utils/index.dart` | ソース | エクスポート集約 |
| route_constants.dart | `lib/utils/route_constants.dart` | ソース | ルーティング定数 |
