# 画面設計書 43-アナウンスバー設定

## 概要

本ドキュメントは、Ghost管理画面の「アナウンスバー設定」画面の設計仕様を定義する。この画面はサイト上部に表示されるお知らせバーの内容、背景色、表示対象の設定を行う機能を提供する。

### 本画面の処理概要

この画面では、サイト訪問者に重要な情報やオファーを伝えるためのアナウンスバーを設定する。テキスト内容の編集、背景色の選択、表示対象ユーザーの指定が可能である。

**業務上の目的・背景**：アナウンスバーは、サイト訪問者に対して最新ニュース、特別オファー、重要なお知らせなどを目立つ形で伝える手段として有効である。特定のユーザーセグメント（公開訪問者、無料会員、有料会員）に対して異なるメッセージを表示することで、よりターゲットを絞ったコミュニケーションが可能になる。

**画面へのアクセス方法**：管理画面のサイドバーから「Settings」→「Site」セクション→「Announcement bar」カードの「Customize」ボタンをクリックしてアクセスする。URLは`/ghost/#/settings/announcement-bar/edit`となる。

**主要な操作・処理内容**：
1. アナウンスバーのテキスト内容の編集（リッチテキスト）
2. 背景色の選択（Dark/Light/Accent）
3. 表示対象の設定（Public visitors/Free members/Paid members）
4. ホームページまたは投稿ページでのリアルタイムプレビュー
5. デスクトップ/モバイルプレビュー切り替え

**画面遷移**：設定画面（Site設定セクション）から遷移し、アナウンスバー編集モーダルが表示される。保存またはキャンセル後は設定画面に戻る。

**権限による表示制御**：Administrator以上のロールを持つユーザーのみがアナウンスバー設定にアクセスできる。有料会員向け表示オプションは`paid_members_enabled`設定がtrueの場合のみ表示される。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 39 | アナウンスメントバー | 主機能 | サイト上部のお知らせバー設定 |

## 画面種別

設定画面（プレビューモーダル型）

## URL/ルーティング

- メイン画面: `/ghost/#/settings` (navid: `announcement-bar`)
- 編集モーダル: `/ghost/#/settings/announcement-bar/edit`

## 入出力項目

| 項目名 | 種別 | データ型 | 必須 | 説明 |
|--------|------|---------|------|------|
| Announcement | 入力 | string (HTML) | - | アナウンスバーに表示するテキスト（リッチテキスト） |
| Background color | 入力 | enum | - | 背景色（dark/light/accent） |
| Visibility | 入力 | string[] | - | 表示対象ユーザーグループ |

## 表示項目

| 項目名 | データ型 | 説明 |
|--------|---------|------|
| Preview | iframe | アナウンスバーのリアルタイムプレビュー |
| Tab (Homepage/Post) | string | プレビュー対象ページの選択 |

## イベント仕様

### 1-Customizeボタン押下

「Customize」ボタンをクリックすると、`announcement-bar/edit`ルートへ遷移し、アナウンスバー編集モーダルが表示される。

### 2-アナウンステキスト編集

HtmlFieldでテキストを編集すると：

1. `debounce`による500ms遅延後、`updateSetting`で`announcement_content`を更新
2. プレビューがリアルタイムで更新される

### 3-背景色変更

カラースウォッチをクリックすると：

1. `toggleColorSwatch`関数で`announcement_background`を更新
2. 選択可能な色：Dark（#08090c）、Light（#ffffff）、Accent（サイトのアクセントカラー）

### 4-表示対象変更

チェックボックスを変更すると：

1. `toggleVisibility`関数で`announcement_visibility`を更新
2. JSON配列形式で保存（例：`["visitors", "free_members"]`）
3. 選択可能な対象：Public visitors、Free members、Paid members

### 5-プレビュータブ切り替え

Homepage/Postタブを切り替えると：

1. `selectedPreviewTab`状態が更新される
2. プレビューURLが対応するページに切り替わる
3. Post選択時は最新の公開記事URLを使用

### 6-保存

「Save」ボタンをクリックすると：

1. `handleSave`で設定をAPIに送信
2. 成功時はモーダルを閉じる
3. 失敗時はエラートーストを表示

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| アナウンスバー保存 | settings | UPDATE | announcement_content更新 |
| アナウンスバー保存 | settings | UPDATE | announcement_background更新 |
| アナウンスバー保存 | settings | UPDATE | announcement_visibility更新 |

### テーブル別更新項目詳細

#### settings

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | key='announcement_content' | HTMLテキスト | アナウンス内容 |
| UPDATE | key='announcement_background' | 'dark'/'light'/'accent' | 背景色 |
| UPDATE | key='announcement_visibility' | JSON配列 | 表示対象 |

## メッセージ仕様

| 種別 | メッセージ | 表示条件 |
|------|-----------|----------|
| エラー | An error occurred while saving your changes. Please try again. | 保存失敗時 |

## 例外処理

| 状態 | 処理内容 |
|------|----------|
| 保存エラー | エラートーストを表示 |
| プレビュー読み込みエラー | iframeでエラーをキャッチ（静かに失敗） |
| 投稿が存在しない | Postタブを非表示にする |

## 備考

- プレビューはiframeを使用し、POSTリクエストで`x-ghost-preview`ヘッダーを送信
- テキスト入力は500msのdebounceを適用してパフォーマンスを最適化
- 有料会員オプションは`paid_members_enabled`がtrueの場合のみ表示
- Postプレビューには最新の公開記事を使用
- `IframeBuffering`コンポーネントでスムーズなプレビュー更新を実現

---

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

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

### 推奨読解順序

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

まず、アナウンスバーに関連する設定値を理解することが重要である。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | announcement-bar-modal.tsx | `apps/admin-x-settings/src/components/settings/site/announcement-bar-modal.tsx` | 設定値の取得（114-119行目） |

**読解のコツ**: `getSettingValues`で取得される設定キー（`announcement_content`, `announcement_background`, `announcement_visibility`）がアナウンスバーの主要なデータである。

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

処理の起点となるファイル・関数を特定する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | announcement-bar.tsx | `apps/admin-x-settings/src/components/settings/site/announcement-bar.tsx` | メインコンポーネントの構造（6-24行目） |
| 2-2 | announcement-bar-modal.tsx | `apps/admin-x-settings/src/components/settings/site/announcement-bar-modal.tsx` | モーダルコンポーネントの構造（111-227行目） |

**主要処理フロー**:
1. **announcement-bar.tsx 8-10行目**: `openModal`でモーダルを表示
2. **announcement-bar-modal.tsx 113行目**: `useSettingGroup`でローカル設定を管理
3. **announcement-bar-modal.tsx 137-141行目**: `debounce`によるテキスト更新の遅延処理

#### Step 3: サイドバーUIを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | announcement-bar-modal.tsx | `apps/admin-x-settings/src/components/settings/site/announcement-bar-modal.tsx` | Sidebarコンポーネント（25-109行目） |

**主要処理フロー**:
- **36-61行目**: 表示対象チェックボックスの設定
- **64-72行目**: HtmlFieldによるリッチテキスト編集
- **73-102行目**: ColorIndicatorによる背景色選択
- **103-106行目**: CheckboxGroupによる表示対象選択

#### Step 4: プレビューロジックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | announcement-bar-preview.tsx | `apps/admin-x-settings/src/components/settings/site/announcement-bar/announcement-bar-preview.tsx` | プレビュー表示ロジック |

**主要処理フロー**:
- **4-12行目**: `getPreviewData`でプレビュー用パラメータを構築
- **25-69行目**: `injectContentIntoIframe`でiframeにコンテンツを注入
- **72-80行目**: `IframeBuffering`でスムーズなプレビュー更新

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

```
AnnouncementBar (announcement-bar.tsx)
    │
    └─ openModal()
           │
           └─ updateRoute('announcement-bar/edit')
                  │
                  └─ AnnouncementBarModal (announcement-bar-modal.tsx)
                         │
                         ├─ useSettingGroup()
                         │      └─ localSettings
                         │             ├─ announcement_content
                         │             ├─ announcement_background
                         │             └─ announcement_visibility
                         │
                         ├─ useBrowsePosts() ──► GET /posts/ (最新記事取得)
                         │
                         ├─ Sidebar
                         │      ├─ HtmlField (announcement_content)
                         │      ├─ ColorIndicator (announcement_background)
                         │      └─ CheckboxGroup (announcement_visibility)
                         │
                         ├─ AnnouncementBarPreview
                         │      └─ IframeBuffering
                         │             └─ injectContentIntoIframe()
                         │                    └─ POST {url} (x-ghost-preview header)
                         │
                         └─ handleSave()
                                └─ PUT /settings/
```

### データフロー図

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

                    ┌─────────────────┐
ユーザー入力 ───────┤   Sidebar UI     │
(text/color/       │                  │
 visibility)       └────────┬─────────┘
                            │
                   ┌────────▼─────────┐
                   │   debounce(500)   │
                   │   updateSetting   │
                   └────────┬─────────┘
                            │
                   ┌────────▼─────────┐
                   │   localSettings   │
                   └────────┬─────────┘
                            │
              ┌─────────────┼─────────────┐
              │             │             │
    ┌─────────▼────┐  ┌─────▼────┐  ┌────▼────┐
    │Preview Update│  │ Sidebar  │  │  Save   │
    └──────┬───────┘  │  State   │  └────┬────┘
           │          └──────────┘       │
           │                             │
    ┌──────▼───────┐              ┌──────▼──────┐
    │getPreviewData│              │PUT /settings/│
    │+ iframe POST │              └──────────────┘
    └──────────────┘
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| announcement-bar.tsx | `apps/admin-x-settings/src/components/settings/site/announcement-bar.tsx` | ソース | メイン設定カードコンポーネント |
| announcement-bar-modal.tsx | `apps/admin-x-settings/src/components/settings/site/announcement-bar-modal.tsx` | ソース | アナウンスバー編集モーダル |
| announcement-bar-preview.tsx | `apps/admin-x-settings/src/components/settings/site/announcement-bar/announcement-bar-preview.tsx` | ソース | プレビュー表示コンポーネント |
| iframe-buffering.tsx | `apps/admin-x-settings/src/utils/iframe-buffering.tsx` | ソース | iframeバッファリングユーティリティ |
| settings.ts | `apps/admin-x-framework/src/api/settings.ts` | ソース | 設定API定義 |
| posts.ts | `apps/admin-x-framework/src/api/posts.ts` | ソース | 投稿API定義（最新記事取得用） |
