# DonateProvider

`DonateProvider` 是一个关键的上下文提供程序，用于管理应用程序中所有与捐赠相关的组件的状态和设置。它负责从后端获取配置、为提高性能而缓存配置，并将其提供给像 `CheckoutDonate` 这样的组件。

要使用任何捐赠功能，您必须用 `DonateProvider` 包装您的组件。此提供程序还必须嵌套在 [`PaymentProvider`](./providers-payment-provider.md) 中，以确保能访问必要的支付上下文和会话信息。

## 工作原理

`DonateProvider` 执行以下几个关键功能：

1.  **获取设置**：在挂载时，它会调用一个 API 端点来检索与唯一的 `mountLocation` prop 关联的捐赠设置。这些设置决定了子捐赠组件的行为。
2.  **缓存数据**：为了提高性能并减少网络请求，获取的设置会存储在 `localStorage` 中。缓存会在后续加载时自动使用，并可在需要时手动清除。
3.  **提供上下文**：它使用 React 的 Context API 将设置和控制函数（`refresh`、`updateSettings`）传递给任何需要它们的后代组件。
4.  **启用捐赠**：对于管理用户（“owner”或“admin”），如果捐赠实例处于非活动状态但设置了 `enableDonate` prop，提供程序将渲染一个 UI 来激活它。

## Props

`DonateProvider` 接受以下 props 来配置其行为：

| Prop              | Type                               | Required | Description                                                                                                                              |
| ----------------- | ---------------------------------- | :------: | ---------------------------------------------------------------------------------------------------------------------------------------- |
| `mountLocation`   | `string`                           |   是    | 此特定捐赠实例的唯一字符串标识符。它用作获取、缓存和更新设置的键。        |
| `description`     | `string`                           |   是    | 一个人类可读的描述，以帮助在系统后端或日志中识别此捐赠实例。                                      |
| `children`        | `ReactNode`                        |   是    | 将在提供程序内部渲染的子组件，通常包括 `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; // 主捐赠按钮的文本，例如“捐赠”
  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'; // 您的自定义会话钩子

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

  // 如果用户未通过身份验证，则不渲染任何内容或显示登录提示
  if (!session?.user) {
    return <div>请登录以进行捐赠。</div>;
  }

  return (
    <PaymentProvider session={session} connect={connectApi}>
      <DonateProvider
        mountLocation="support-our-blog-post-123"
        description="为文章《React 入门》捐赠"
        defaultSettings={{
          btnText: '支持作者',
          amount: {
            presets: ['1', '5', '10'],
            custom: true,
            minimum: '1',
          },
        }}>
        <CheckoutDonate
          settings={{
            target: 'post-123', // 捐赠目标的唯一标识符
            title: '支持作者',
            description: '如果您觉得这篇文章有帮助，欢迎请我喝杯咖啡。',
            reference: 'https://your-site.com/posts/123',
            beneficiaries: [
              {
                address: 'z8iZ75n8fWJ2aL1c9a9f4c3b2e1a0d9f8e7d6c5b4a392817',
                share: '100',
              },
            ],
          }}
        />
      </DonateProvider>
    </PaymentProvider>
  );
}
```

## Hooks 和实用工具

该库还导出了几个辅助函数，用于对捐赠上下文和缓存进行高级控制。

### `useDonateContext`

一个 React 钩子，用于从 `DonateProvider` 的任何子组件直接访问捐赠上下文。

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

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

  return (
    <div>
      <p>捐赠功能当前为{settings.active ? '启用' : '禁用'}状态。</p>
      <button onClick={() => refresh(true)}>刷新设置</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('捐赠设置已被删除。');
  } catch (error) {
    console.error('删除设置失败：', error);
  }
}
```

配置好 `DonateProvider` 后，您现在可以实现各种捐赠功能。下一步是探索用于显示捐赠 UI 的主组件。

➡️ 接下来，学习如何使用 [`CheckoutDonate`](./components-checkout-checkout-donate.md) 组件来渲染捐赠小部件。