163 lines
6.3 KiB
JavaScript
163 lines
6.3 KiB
JavaScript
import AddOutlined from "@mui/icons-material/AddOutlined";
|
|
import DeleteOutlineOutlined from "@mui/icons-material/DeleteOutlineOutlined";
|
|
import SaveOutlined from "@mui/icons-material/SaveOutlined";
|
|
import Drawer from "@mui/material/Drawer";
|
|
import IconButton from "@mui/material/IconButton";
|
|
import TextField from "@mui/material/TextField";
|
|
import { AdminSwitch } from "@/shared/ui/AdminSwitch.jsx";
|
|
import { Button } from "@/shared/ui/Button.jsx";
|
|
import styles from "@/features/red-packets/red-packets.module.css";
|
|
|
|
export function RedPacketConfigDrawer({
|
|
abilities,
|
|
configLoading,
|
|
configSaving,
|
|
form,
|
|
onClose,
|
|
onSubmit,
|
|
open,
|
|
setForm,
|
|
}) {
|
|
const disabled = !abilities.canUpdate || configLoading || configSaving;
|
|
|
|
const updateValue = (key, value) => {
|
|
setForm((current) => ({ ...current, [key]: value }));
|
|
};
|
|
|
|
const updateTier = (key, index, value) => {
|
|
setForm((current) => ({
|
|
...current,
|
|
[key]: (current[key] || []).map((item, itemIndex) => (itemIndex === index ? value : item)),
|
|
}));
|
|
};
|
|
|
|
const addTier = (key) => {
|
|
setForm((current) => ({ ...current, [key]: [...(current[key] || []), ""] }));
|
|
};
|
|
|
|
const removeTier = (key, index) => {
|
|
setForm((current) => ({
|
|
...current,
|
|
[key]: (current[key] || []).filter((_, itemIndex) => itemIndex !== index),
|
|
}));
|
|
};
|
|
|
|
return (
|
|
<Drawer anchor="right" open={open} onClose={configSaving ? undefined : onClose}>
|
|
<form className="form-drawer" onSubmit={onSubmit}>
|
|
<h2>红包配置</h2>
|
|
<section className="form-drawer__section">
|
|
<div className="form-drawer__section-title">发放状态</div>
|
|
<AdminSwitch
|
|
checked={form.enabled}
|
|
checkedLabel="开启"
|
|
disabled={disabled}
|
|
label="红包状态"
|
|
uncheckedLabel="关闭"
|
|
onChange={(event) => updateValue("enabled", event.target.checked)}
|
|
/>
|
|
</section>
|
|
<section className="form-drawer__section">
|
|
<div className="form-drawer__grid">
|
|
<TextField
|
|
disabled={disabled}
|
|
inputProps={{ min: 0 }}
|
|
label="延迟红包秒数"
|
|
type="number"
|
|
value={form.delayedOpenSeconds}
|
|
onChange={(event) => updateValue("delayedOpenSeconds", event.target.value)}
|
|
/>
|
|
<TextField
|
|
disabled={disabled}
|
|
inputProps={{ min: 1 }}
|
|
label="过期退款秒数"
|
|
type="number"
|
|
value={form.expireSeconds}
|
|
onChange={(event) => updateValue("expireSeconds", event.target.value)}
|
|
/>
|
|
<TextField
|
|
disabled={disabled}
|
|
inputProps={{ min: 1 }}
|
|
label="每用户每日最多发送"
|
|
type="number"
|
|
value={form.dailySendLimit}
|
|
onChange={(event) => updateValue("dailySendLimit", event.target.value)}
|
|
/>
|
|
</div>
|
|
</section>
|
|
<TierSection
|
|
disabled={disabled}
|
|
label="红包数量档位"
|
|
tierKey="countTiers"
|
|
values={form.countTiers}
|
|
onAdd={addTier}
|
|
onRemove={removeTier}
|
|
onUpdate={updateTier}
|
|
/>
|
|
<TierSection
|
|
disabled={disabled}
|
|
label="红包金额档位"
|
|
tierKey="amountTiers"
|
|
values={form.amountTiers}
|
|
onAdd={addTier}
|
|
onRemove={removeTier}
|
|
onUpdate={updateTier}
|
|
/>
|
|
<div className="form-drawer__actions">
|
|
<Button disabled={configSaving} type="button" onClick={onClose}>
|
|
取消
|
|
</Button>
|
|
<Button
|
|
disabled={disabled}
|
|
startIcon={<SaveOutlined fontSize="small" />}
|
|
type="submit"
|
|
variant="primary"
|
|
>
|
|
保存
|
|
</Button>
|
|
</div>
|
|
</form>
|
|
</Drawer>
|
|
);
|
|
}
|
|
|
|
function TierSection({ disabled, label, onAdd, onRemove, onUpdate, tierKey, values }) {
|
|
return (
|
|
<section className="form-drawer__section">
|
|
<div className="form-drawer__section-title">
|
|
<span>{label}</span>
|
|
<Button
|
|
disabled={disabled}
|
|
startIcon={<AddOutlined fontSize="small" />}
|
|
type="button"
|
|
onClick={() => onAdd(tierKey)}
|
|
>
|
|
添加
|
|
</Button>
|
|
</div>
|
|
<div className={styles.tierEditor}>
|
|
{(values || []).map((value, index) => (
|
|
<div className={styles.tierGrid} key={`${tierKey}-${index}`}>
|
|
<TextField
|
|
disabled={disabled}
|
|
inputProps={{ min: 1 }}
|
|
label={`${label} ${index + 1}`}
|
|
type="number"
|
|
value={value}
|
|
onChange={(event) => onUpdate(tierKey, index, event.target.value)}
|
|
/>
|
|
<IconButton
|
|
aria-label="删除档位"
|
|
disabled={disabled || values.length <= 1}
|
|
size="small"
|
|
onClick={() => onRemove(tierKey, index)}
|
|
>
|
|
<DeleteOutlineOutlined fontSize="small" />
|
|
</IconButton>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</section>
|
|
);
|
|
}
|