# blockTimeModal 接入说明

`blockTimeModal` 是一个以 `Promise` 形式调用的屏蔽时间弹窗，不需要先在页面里渲染 `<BlockTimeModal />`。

## 1. 基本调用

```ts
import blockTimeModal from './index';

await blockTimeModal
  .open({
    resources,
    initialName: 'Blocked time',
    initialResourceId: 101,
    initialTimeRange: [start, end],
  })
  .then((result) => {
    console.log('submit success', result);
  })
  .catch((reason) => {
    console.log('modal closed', reason);
  });
```

## 2. 推荐接入方式

通常你会在打开时同时传入：

- `resources`: 场地列表
- `initialName`: 默认标题
- `initialNote`: 默认备注
- `initialResourceId`: 默认选中的场地
- `initialTimeRange`: 默认时间范围
- `blockedSalesChannels`: 提交时写入 `blocked_sales_channels`
- `minuteStep`: 时间选择器步长
- `onSubmit`: 点击保存后，在弹窗内部执行提交

示例：

```ts
await blockTimeModal.open({
  resources: [
    { id: 101, name: 'Court A' },
    { id: 102, name: 'Court B' },
  ],
  initialName: 'Court maintenance',
  initialNote: 'Net replacement',
  initialResourceId: 101,
  initialTimeRange: [start, end],
  blockedSalesChannels: ['online_store'],
  minuteStep: 30,
  onSubmit: async ({ submitPayload }) => {
    return request('/shop/schedule/blocked-time', {
      method: 'POST',
      data: submitPayload,
    });
  },
});
```

## 3. `open` 主要参数

### 必传

```ts
{
  resources: BlockTimeModalResource[];
}
```

### 常用可选参数

- `initialName`: 初始标题
- `initialNote`: 初始备注
- `initialResourceId`: 初始场地 id
- `initialTimeRange`: 初始时间范围
- `blockedSalesChannels`: 提交 payload 中的销售渠道，默认 `['online_store']`
- `minuteStep`: 时间面板分钟步长，默认 `60`
- `theme`: `'light' | 'dark'`
- `title` / `confirmText` / `cancelText`: 自定义文案
- `submitErrorMessage`: 提交失败时的兜底错误文案
- `onSubmit`: 点击保存后在弹窗内部执行提交

## 4. `onSubmit` 的调用时机

点击保存按钮后，弹窗内部会：

1. 先校验时间范围与场地
2. 根据当前表单生成 `submitPayload`
3. 如果没传 `onSubmit`，直接 `resolve`
4. 如果传了 `onSubmit`，则 `await onSubmit(context)`
5. 提交成功后关闭弹窗并 `resolve`
6. 提交失败时保留弹窗，并显示错误信息

## 5. `onSubmit` 收到的上下文

```ts
type BlockTimeModalSubmitContext = {
  draft;
  submitPayload;
  options;
};
```

其中最常用的是：

- `draft`: 当前用户填写后的表单值
- `submitPayload`: 组件内部组装好的提交参数

## 6. 返回值

`open()` 返回一个 Promise。

### 成功时 `resolve(result)`

```ts
{
  draft,
  submitPayload,
  submitResult,
}
```

### 关闭时 `reject(reason)`

```ts
{
  type: 'cancel' | 'backdrop' | 'escape' | 'programmatic-close' | 'replaced';
  message?: string;
}
```

## 7. `submitPayload` 结构

```ts
{
  name,
  note,
  resource_ids,
  blocked_sales_channels,
  start_time,
  end_time,
}
```
