# DonateProvider

`DonateProvider` 是一個關鍵的 context provider，負責管理應用程式中所有捐款相關元件的狀態和設定。它會處理從後端擷取設定、為了效能而快取設定，並將設定提供給像 `CheckoutDonate` 這樣的元件。

若要使用任何捐款功能，您必須用 `DonateProvider` 包裹您的元件。此 provider 也必須巢狀嵌套在 [`PaymentProvider`](./providers-payment-provider.md) 內，以確保能存取必要的支付 context 和 session 資訊。

## 運作方式

`DonateProvider` 執行幾個關鍵功能：

1.  **擷取設定**：在掛載時，它會呼叫一個 API 端點來擷取與唯一的 `mountLocation` prop 相關聯的捐款設定。這些設定決定了子捐款元件的行為。
2.  **快取資料**：為了提升效能並減少網路請求，擷取到的設定會儲存在 `localStorage` 中。快取會在後續載入時自動使用，如有需要也可以手動清除。
3.  **提供 Context**：它使用 React 的 Context API 將設定和控制函式（`refresh`、`updateSettings`）傳遞給任何需要它們的後代元件。
4.  **啟用捐款**：對於管理員使用者（'owner' 或 'admin'），如果捐款實例處於非活動狀態但設定了 `enableDonate` prop，provider 將會渲染一個 UI 來啟用它。

## Props

`DonateProvider` 接受以下 props 來設定其行為：

| Prop | Type | Required | Description |
| ----------------- | ---------------------------------- | :------: | ---------------------------------------------------------------------------------------------------------------------------------------- |
| `mountLocation` | `string` | 是 | 此特定捐款實例的唯一字串識別碼。它被用作擷取、快取和更新設定的鍵。 |
| `description` | `string` | 是 | 一個人類可讀的描述，有助於在系統後端或日誌中識別此捐款實例。 |
| `children` | `ReactNode` | 是 | 將在 provider 內渲染的子元件，通常包含 `CheckoutDonate`。 |
| `defaultSettings` | `DonateConfigSettings` | 否 | 一個包含預設設定的物件，如果在後端找不到設定時套用。有關可用選項，請參閱下方的類型定義。 |
| `active` | `boolean` | 否 | 設定捐款實例首次建立時的初始活動狀態。預設為 `true`。 |
| `enableDonate` | `boolean` | 否 | 如果為 `true`，允許管理員使用者在捐款實例目前為非活動狀態時，從 UI 啟用它。預設為 `false`。 |

### DonateConfigSettings 類型

這是 `defaultSettings` 物件的結構：

```typescript DonateConfigSettings type
export interface DonateConfigSettings {
  amount?: {
    presets?: string[]; // 例如 ['1', '5', '10']
    preset?: string; // 預設選擇的預設金額
    custom: boolean; // 允許使用者輸入自訂金額
    minimum?: string; // 最小自訂金額
    maximum?: string; // 最大自訂金額
  };
  btnText?: string; // 主要捐款按鈕的文字，例如 "Donate"
  historyType?: 'table' | 'avatar'; // 如何顯示支持者列表
}
```

## 使用範例

這是一個在頁面上設定捐款區塊的完整範例。它展示了如何使用 `DonateProvider` 和 `PaymentProvider` 來包裹 `CheckoutDonate`。

```tsx App.tsx icon=logos:react
import {
  PaymentProvider,
  DonateProvider,
  CheckoutDonate,
} from '@blocklet/payment-react';
import { useSessionContext } from './hooks/use-session'; // 您的自訂 session hook

function DonationSection() {
  const { session, connectApi } = useSessionContext();

  // 如果使用者未經驗證，則不渲染任何內容或顯示登入提示
  if (!session?.user) {
    return <div>Please log in to make a donation.</div>;
  }

  return (
    <PaymentProvider session={session} connect={connectApi}>
      <DonateProvider
        mountLocation="support-our-blog-post-123"
        description="Donation for the article 'Getting Started with React'"
        defaultSettings={{
          btnText: 'Support the Author',
          amount: {
            presets: ['1', '5', '10'],
            custom: true,
            minimum: '1',
          },
        }}>
        <CheckoutDonate
          settings={{
            target: 'post-123', // 捐款目標的唯一識別碼
            title: 'Support the Author',
            description: 'If you found this article helpful, feel free to buy me a coffee.',
            reference: 'https://your-site.com/posts/123',
            beneficiaries: [
              {
                address: 'z8iZ75n8fWJ2aL1c9a9f4c3b2e1a0d9f8e7d6c5b4a392817',
                share: '100',
              },
            ],
          }}
        />
      </DonateProvider>
    </PaymentProvider>
  );
}
```

## Hooks 和公用程式

該函式庫還匯出了一些輔助函式，用於對捐款 context 和快取進行進階控制。

### `useDonateContext`

一個 React hook，用於從 `DonateProvider` 的任何子元件中直接存取捐款 context。

```tsx
import { useDonateContext } from '@blocklet/payment-react';

function CustomDonationInfo() {
  const { settings, refresh } = useDonateContext();

  return (
    <div>
      <p>Donations are currently {settings.active ? 'enabled' : 'disabled'}.</p>
      <button onClick={() => refresh(true)}>Refresh Settings</button>
    </div>
  );
}
```

### `clearDonateCache`

此函式會從 `localStorage` 中手動移除特定 `mountLocation` 的快取設定。當您知道伺服器上的設定已變更，並希望在下次元件渲染時強制重新擷取時，這非常有用。

```javascript
import { clearDonateCache } from '@blocklet/payment-react';

// 當您需要讓快取失效時，呼叫此函式
clearDonateCache('support-our-blog-post-123');
```

### `clearDonateSettings`

此函式會向後端 API 發送一個 `DELETE` 請求，以永久移除給定 `mountLocation` 的設定。它也會清除該位置的本地快取。

```javascript
import { clearDonateSettings } from '@blocklet/payment-react';

async function deleteDonationInstance() {
  try {
    await clearDonateSettings('support-our-blog-post-123');
    console.log('Donation settings have been deleted.');
  } catch (error) {
    console.error('Failed to delete settings:', error);
  }
}
```

設定好 `DonateProvider` 後，您現在可以實作各種捐款功能。下一步是探索用於顯示捐款 UI 的主要元件。

➡️ 接下來，學習如何使用 [`CheckoutDonate`](./components-checkout-checkout-donate.md) 元件來渲染捐款小工具。