Refactor GlobalPromptModal to use antd-mobile Popup for improved mobile experience. Update styles for modal footer and enhance user feedback with Toast notifications. Remove deprecated Ant Design Modal components and adjust layout for better usability.

This commit is contained in:
超级老白兔
2025-10-30 16:26:15 +08:00
parent 515c85e600
commit da87f9a865
2 changed files with 79 additions and 53 deletions

View File

@@ -1,12 +1,14 @@
import React, { useState, useEffect } from "react";
import { Modal, Switch, message } from "antd";
import { Popup, Toast } from "antd-mobile";
import { Input, Button, Switch } from "antd";
import { CloseOutlined } from "@ant-design/icons";
const { TextArea } = Input;
import {
InfoCircleOutlined,
BulbOutlined,
ExclamationCircleOutlined,
ExclamationCircleFilled,
InfoCircleFilled,
} from "@ant-design/icons";
import { getGlobalPrompt, saveGlobalPrompt } from "../api";
import type { GlobalPromptConfig } from "../data";
import style from "../index.module.scss";
interface GlobalPromptModalProps {
@@ -35,6 +37,7 @@ const GlobalPromptModal: React.FC<GlobalPromptModalProps> = ({
if (visible) {
fetchGlobalPrompt();
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [visible]);
const fetchGlobalPrompt = async () => {
@@ -44,7 +47,7 @@ const GlobalPromptModal: React.FC<GlobalPromptModalProps> = ({
setEnabled(config.enabled);
setContent(config.content || DEFAULT_PROMPT);
} catch (error) {
message.error("获取配置失败");
Toast.show({ content: "获取配置失败", position: "bottom" });
} finally {
setLoading(false);
}
@@ -52,66 +55,83 @@ const GlobalPromptModal: React.FC<GlobalPromptModalProps> = ({
const handleSave = async () => {
if (enabled && !content.trim()) {
message.error("启用统一提示词时,请输入提示词内容");
Toast.show({
content: "启用统一提示词时,请输入提示词内容",
position: "bottom",
});
return;
}
setSaving(true);
try {
await saveGlobalPrompt({
enabled,
content: content.trim(),
});
message.success("保存成功");
Toast.show({ content: "保存成功", position: "bottom" });
onClose();
} catch (error) {
message.error("保存失败");
Toast.show({ content: "保存失败", position: "bottom" });
} finally {
setSaving(false);
}
};
return (
<Modal
title={
<div style={{ display: "flex", alignItems: "center", gap: 8 }}>
<InfoCircleOutlined style={{ color: "#1890ff" }} />
</div>
}
open={visible}
onCancel={onClose}
onOk={handleSave}
confirmLoading={saving}
width={600}
okText="保存配置"
cancelText="取消"
<Popup
visible={visible}
onMaskClick={onClose}
bodyStyle={{ borderRadius: "16px 16px 0 0", minHeight: 300, padding: 0 }}
position="bottom"
closeOnMaskClick
className={style.promptModal}
>
<div
className={style.promptMobileHead}
style={{
display: "flex",
alignItems: "center",
justifyContent: "space-between",
padding: "18px 20px 0 20px",
}}
>
<div style={{ display: "flex", alignItems: "center" }}>
<InfoCircleOutlined
style={{
color: "#1677ff",
fontSize: 20,
marginRight: 8,
verticalAlign: "middle",
}}
/>
<span></span>
</div>
<CloseOutlined onClick={onClose} />
</div>
<div className={style.promptContent}>
<p style={{ fontSize: 13, color: "#666", marginBottom: 16 }}>
<div style={{ fontSize: 13, color: "#888", marginBottom: 12 }}>
</p>
</div>
<div className={style.promptToggle}>
<span className={style.promptToggleLabel}></span>
<Switch checked={enabled} onChange={setEnabled} />
<Switch checked={enabled} onChange={setEnabled} loading={loading} />
</div>
{enabled && (
<textarea
className={style.promptTextarea}
<TextArea
value={content}
onChange={e => setContent(e.target.value)}
placeholder="请输入统一提示词..."
maxLength={2000}
disabled={loading}
className={style.promptTextarea}
/>
)}
<div className={style.promptSection}>
<div className={style.sectionTitle}>
<BulbOutlined className={style.sectionIcon} />
:
<InfoCircleFilled
className={style.sectionIcon}
style={{ fontSize: 16 }}
/>
</div>
<div className={style.sectionContent}>
<ul>
@@ -121,18 +141,38 @@ const GlobalPromptModal: React.FC<GlobalPromptModalProps> = ({
</ul>
</div>
</div>
<div className={style.warningBox}>
<div className={style.warningTitle}>
<ExclamationCircleOutlined /> :
<ExclamationCircleFilled
style={{
marginRight: 3,
fontSize: 16,
verticalAlign: "middle",
color: "#FC772B",
}}
/>
:
</div>
<div className={style.warningText}>
<div> + </div>
<div style={{ marginTop: 4 }}>= AI回复内容</div>
+ =
AI回复内容
</div>
</div>
<div className={style.modalFooter}>
<Button size="large" onClick={onClose}>
</Button>
<Button
size="large"
onClick={handleSave}
disabled={saving}
type="primary"
>
{saving ? "保存中..." : "保存配置"}
</Button>
</div>
</div>
</Modal>
</Popup>
);
};

View File

@@ -296,21 +296,8 @@
.modalFooter {
display: flex;
justify-content: space-between;
gap: 12px;
padding: 16px 20px;
border-top: 1px solid #f0f0f0;
background: #fff;
}
.modalButton {
flex: 1;
padding: 10px;
border: none;
border-radius: 8px;
font-size: 15px;
font-weight: 500;
cursor: pointer;
transition: all 0.2s;
}
.cancelButton {
@@ -346,7 +333,6 @@
display: flex;
align-items: center;
justify-content: space-between;
padding: 12px;
background: #f9f9f9;
border-radius: 8px;
margin-bottom: 16px;