# DonateProvider

The `DonateProvider` is a crucial context provider that manages the state and settings for all donation-related components within your application. It handles fetching configuration from the backend, caching it for performance, and providing it to components like `CheckoutDonate`.

To use any donation features, you must wrap your components with `DonateProvider`. This provider must also be nested within a [`PaymentProvider`](./providers-payment-provider.md) to ensure access to the necessary payment context and session information.

## How It Works

The `DonateProvider` performs several key functions:

1.  **Fetches Settings**: On mount, it calls an API endpoint to retrieve the donation settings associated with the unique `mountLocation` prop. These settings determine the behavior of child donation components.
2.  **Caches Data**: To improve performance and reduce network requests, the fetched settings are stored in `localStorage`. The cache is automatically used on subsequent loads and can be manually cleared if needed.
3.  **Provides Context**: It uses React's Context API to pass down the settings and control functions (`refresh`, `updateSettings`) to any descendant component that needs them.
4.  **Enables Donations**: For administrative users ('owner' or 'admin'), if the donation instance is inactive but the `enableDonate` prop is set, the provider will render a UI to activate it.

## Props

The `DonateProvider` accepts the following props to configure its behavior:

| Prop              | Type                               | Required | Description                                                                                                                              |
| ----------------- | ---------------------------------- | :------: | ---------------------------------------------------------------------------------------------------------------------------------------- |
| `mountLocation`   | `string`                           |   Yes    | A unique string identifier for this specific donation instance. This is used as the key for fetching, caching, and updating settings.        |
| `description`     | `string`                           |   Yes    | A human-readable description to help identify this donation instance in the system backend or logs.                                      |
| `children`        | `ReactNode`                        |   Yes    | The child components that will render inside the provider, typically including `CheckoutDonate`.                                       |
| `defaultSettings` | `DonateConfigSettings`             |    No    | An object with default settings to apply if no settings are found on the backend. See the type definition below for available options. |
| `active`          | `boolean`                          |    No    | Sets the initial active state for the donation instance when it's first created. Defaults to `true`.                                   |
| `enableDonate`    | `boolean`                          |    No    | If `true`, allows admin users to enable this donation instance from the UI if it's currently inactive. Defaults to `false`.               |

### DonateConfigSettings Type

This is the shape of the `defaultSettings` object:

```typescript DonateConfigSettings type
export interface DonateConfigSettings {
  amount?: {
    presets?: string[]; // e.g., ['1', '5', '10']
    preset?: string; // Default selected preset amount
    custom: boolean; // Allow users to enter a custom amount
    minimum?: string; // Minimum custom amount
    maximum?: string; // Maximum custom amount
  };
  btnText?: string; // Text for the main donation button, e.g., "Donate"
  historyType?: 'table' | 'avatar'; // How to display the list of supporters
}
```

## Usage Example

Here is a complete example of setting up a donation section on a page. It shows how to wrap `CheckoutDonate` with both `DonateProvider` and `PaymentProvider`.

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

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

  // Render nothing or a login prompt if the user is not authenticated
  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', // A unique identifier for the donation target
            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 and Utilities

The library also exports several helper functions for advanced control over the donation context and cache.

### `useDonateContext`

A React hook to access the donation context directly from any child component of `DonateProvider`.

```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`

This function manually removes the cached settings for a specific `mountLocation` from `localStorage`. This is useful when you know the settings have changed on the server and you want to force a fresh fetch on the next component render.

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

// Call this function when you need to invalidate the cache
clearDonateCache('support-our-blog-post-123');
```

### `clearDonateSettings`

This function sends a `DELETE` request to the backend API to permanently remove the settings for a given `mountLocation`. It also clears the local cache for that location.

```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);
  }
}
```

With `DonateProvider` configured, you can now implement various donation features. The next step is to explore the main component for displaying the donation UI.

➡️ Next, learn how to use the [`CheckoutDonate`](./components-checkout-checkout-donate.md) component to render the donation widget.