# CheckoutDonate

`CheckoutDonate`コンポーネントは、アプリケーションに寄付機能を追加するための、柔軟で統合しやすいソリューションを提供します。チェックアウトダイアログを開くシンプルなボタンから、完全に制御可能なカスタムUIまで、さまざまな表示モードをサポートしています。

このコンポーネントが正しく機能するためには、`PaymentProvider`と`DonateProvider`の両方でラップする必要があります。`DonateProvider`は、アプリケーションの特定のスコープ内における寄付インスタンスの設定と状態を管理します。

## 仕組み

寄付のフローは`DonateProvider`と`CheckoutDonate`の組み合わせによって調整されます。以下にその概要を示します。

<!-- DIAGRAM_IMAGE_START:flowchart:4:3::1765377352 -->
![CheckoutDonate](assets/diagram/components-checkout-checkout-donate-01.ja.jpg)
<!-- DIAGRAM_IMAGE_END -->

1.  **初期化**：`DonateProvider`は、一意の`mountLocation`によって識別されるバックエンドから、寄付設定（プリセット金額、ボタンテキストなど）を取得してキャッシュします。
2.  **レンダリング**：`CheckoutDonate`は、取得した設定と自身のpropsに基づいて、ボタンまたはカスタムUIをレンダリングします。
3.  **インタラクション**：ユーザーが寄付を開始すると、`CheckoutDonate`は寄付用に事前設定された`CheckoutForm`を含むダイアログを開きます。
4.  **支払い**：ユーザーは`CheckoutForm`を通じて支払いを完了します。
5.  **確認**：支払いが成功すると、`onPaid`コールバックがトリガーされ、コンポーネントは自動的に支援者リストを更新します。

## Providerのセットアップ

`CheckoutDonate`を使用する前に、コンポーネントツリーを`PaymentProvider`と`DonateProvider`でラップする必要があります。

```tsx Provider Setup Example icon=logos:react
import {
  PaymentProvider,
  DonateProvider,
  CheckoutDonate,
} from '@blocklet/payment-react';
import { useSessionContext } from '../hooks/session-context'; // あなたのセッションコンテキストフック

function DonationPage() {
  const { session, connect } = useSessionContext();

  // プロバイダーをレンダリングする前にセッションがロードされていることを確認
  if (!session) {
    return <div>読み込み中...</div>;
  }

  return (
    <PaymentProvider session={session} connect={connect}>
      <DonateProvider
        mountLocation="unique-page-identifier" // この寄付コンテキストのための一意のキー
        description="私の素晴らしいブログ投稿への寄付"
        defaultSettings={{
          btnText: '私を支援する',
        }}>
        {/* ここにCheckoutDonateコンポーネントを配置します */}
        <CheckoutDonate 
          settings={{
            target: "post-123",
            title: "著者を支援",
            description: "この記事が役に立ったと思ったら、ぜひコーヒーを一杯おごってください",
            reference: "https://your-site.com/posts/123",
            beneficiaries: [
              {
                address: "z2qa...",
                share: "100",
              },
            ],
          }}
        />
      </DonateProvider>
    </PaymentProvider>
  );
}
```

詳細は[`DonateProvider`](./providers-donate-provider.md)のドキュメントを参照してください。

## コンポーネントのProps

### `DonateProps`

| Prop | Type | Description |
| --- | --- | --- |
| `settings` | `CheckoutDonateSettings` | **必須。** この特定の寄付インスタンスの設定。 |
| `onPaid` | `(session) => void` | 任意。支払いが成功した後に実行されるコールバック関数。 |
| `onError` | `(error) => void` | 任意。エラーが発生した場合に実行されるコールバック関数。 |
| `mode` | `'default' \| 'inline' \| 'custom'` | 任意。レンダリングモード。デフォルトは`'default'`です。 |
| `livemode` | `boolean` | 任意。`PaymentProvider`からの`livemode`を上書きします。 |
| `timeout` | `number` | 任意。支払い後にダイアログを閉じるまでの待機時間（ミリ秒）。デフォルトは`5000`です。 |
| `theme` | `'default' \| 'inherit' \| object` | 任意。テーマのカスタマイズオプション。[テーマ設定](./guides-theming.md)ガイドを参照してください。 |
| `children` | `(openDialog, donateTotalAmount, supporters, loading, donateSettings) => React.ReactNode` | 任意。`mode="custom"`の場合にのみ使用されるレンダープロップ関数。 |

### `CheckoutDonateSettings`

このオブジェクトは`settings` propに渡され、寄付の核心的な詳細を定義します。

| Property | Type | Description |
| --- | --- | --- |
| `target` | `string` | **必須。** 寄付対象の一意の識別子（例：投稿ID、プロジェクト名）。 |
| `title` | `string` | **必須。** 寄付ダイアログの上部に表示されるタイトル。 |
| `description` | `string` | **必須。** 寄付ダイアログに表示される短い説明。 |
| `reference` | `string` | **必須。** 参照用として使用される、寄付に関連するURL。 |
| `beneficiaries` | `PaymentBeneficiary[]` | **必須。** 資金を受け取る人を定義するオブジェクトの配列。各オブジェクトには`address`（受取人のDID）と`share`（パーセンテージ）が必要です。 |
| `amount` | `object` | 任意。寄付金額を設定します。`presets`（例：`['1', '5', '10']`）、デフォルトの`preset`、`minimum`、`maximum`、および`custom`金額が許可されるかどうかを含みます。 |
| `appearance` | `object` | 任意。`button`（テキスト、アイコン、バリアント）や`history`の表示（`'avatar'`または`'table'`）を含む、ルックアンドフィールをカスタマイズします。 |

## 使用例

### デフォルトモード

これは`CheckoutDonate`を使用する最も簡単な方法です。寄付ダイアログを開くボタンと、最近の支援者の概要をレンダリングします。

```tsx Default Donation Button icon=logos:react
import {
  PaymentProvider,
  DonateProvider,
  CheckoutDonate,
} from '@blocklet/payment-react';
import { useSessionContext } from '../hooks/session-context';

function App() {
  const { session, connect } = useSessionContext();

  if (!session) {
    return <div>セッションを読み込み中...</div>;
  }

  return (
    <PaymentProvider session={session} connect={connect}>
      <DonateProvider
        mountLocation="blog-post-123"
        description="ブログ投稿123への寄付"
        defaultSettings={{
          btnText: 'コーヒーをおごる',
          historyType: 'avatar',
        }}>
        <CheckoutDonate
          settings={{
            target: 'post-123',
            title: '著者を支援',
            description: 'この記事が役に立ったと思ったら、少額の寄付をご検討ください。',
            reference: 'https://example.com/posts/123',
            beneficiaries: [
              {
                address: 'z2qa...gCLd', // 著者のDIDアドレス
                share: '100',
              },
            ],
          }}
          onPaid={() => {
            console.log('寄付が成功しました！');
          }}
        />
      </DonateProvider>
    </PaymentProvider>
  );
}
```

### カスタムUIモード

ユーザーインターフェースを完全に制御するには、`mode="custom"`を使用し、`children`としてレンダープロップを提供します。この関数は、集まった総額や支援者リストを含む寄付の状態へのアクセスを提供し、完全にカスタムな表示を構築することができます。

```tsx Custom Donation UI icon=logos:react
import {
  PaymentProvider,
  DonateProvider,
  CheckoutDonate,
} from '@blocklet/payment-react';
import { useSessionContext } from '../hooks/session-context';
import { CircularProgress, Button } from '@mui/material';

function CustomDonationDisplay() {
  const { session, connect } = useSessionContext();

  if (!session) {
    return <div>セッションを読み込み中...</div>;
  }

  const donateSettings = {
    target: 'post-123',
    title: '著者を支援',
    description: 'この記事が役に立ったと思ったら、少額の寄付をご検討ください。',
    reference: 'https://example.com/posts/123',
    beneficiaries: [
      {
        address: 'z2qa...gCLd', // 著者のDIDアドレス
        share: '100',
      },
    ],
  };

  return (
    <PaymentProvider session={session} connect={connect}>
      <DonateProvider
        mountLocation="blog-post-123"
        description="ブログ投稿123への寄付">
        <CheckoutDonate mode="custom" settings={donateSettings}>
          {(openDonate, totalAmount, supporters, loading, settings) => (
            <div style={{ border: '1px solid #ccc', padding: '16px', borderRadius: '8px' }}>
              <h2>私たちの支援者</h2>
              <p>寄付総額：<strong>{totalAmount}</strong></p>
              <Button variant="contained" onClick={openDonate}>
                {settings?.appearance?.button?.text || '今すぐ寄付'}
              </Button>
              {loading ? (
                <CircularProgress style={{ marginTop: '16px' }} />
              ) : (
                <ul style={{ listStyle: 'none', padding: 0, marginTop: '16px' }}>
                  {(supporters.supporters || []).map((supporter) => (
                    <li key={supporter.id}>
                      <span>{supporter.customer?.name}</span>
                    </li>
                  ))}
                </ul>
              )}
            </div>
          )}
        </CheckoutDonate>
      </DonateProvider>
    </PaymentProvider>
  );
}
```

`children`関数は、以下の引数を受け取ります：

-   `openDonate`：手動で寄付ダイアログをトリガーする関数。
-   `totalAmount`：寄付された総額のフォーマット済み文字列（例：`"125.00 T"`）。
-   `supporters`：`supporters`配列と通貨情報を含む`DonateHistory`オブジェクト。
-   `loading`：支援者データが取得中かどうかを示すブール値。
-   `settings`：`DonateProvider`とpropsからマージされた、解決済みの寄付設定。