From 48dcb23ea59a95d07df9248f9245e02defffdda4 Mon Sep 17 00:00:00 2001 From: farion1231 Date: Wed, 6 Aug 2025 07:44:50 +0800 Subject: [PATCH] =?UTF-8?q?=E7=94=A8=20Modal=20=E7=BB=84=E4=BB=B6=E6=9B=BF?= =?UTF-8?q?=E6=8D=A2=E6=89=80=E6=9C=89=20alert=20=E5=BC=B9=E7=AA=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 创建 ConfirmModal 和 MessageModal 组件 - 更新 App.tsx 使用新的 Modal 组件 - 改进表单验证错误显示 - 提升用户体验和界面一致性 --- src/renderer/App.tsx | 76 +++++++++++++++++-- src/renderer/components/AddProviderModal.tsx | 12 ++- src/renderer/components/ConfirmModal.tsx | 40 ++++++++++ src/renderer/components/EditProviderModal.tsx | 9 ++- src/renderer/components/MessageModal.tsx | 44 +++++++++++ 5 files changed, 170 insertions(+), 11 deletions(-) create mode 100644 src/renderer/components/ConfirmModal.tsx create mode 100644 src/renderer/components/MessageModal.tsx diff --git a/src/renderer/App.tsx b/src/renderer/App.tsx index cd75efb..843fc34 100644 --- a/src/renderer/App.tsx +++ b/src/renderer/App.tsx @@ -3,6 +3,8 @@ import { Provider } from '../shared/types' import ProviderList from './components/ProviderList' import AddProviderModal from './components/AddProviderModal' import EditProviderModal from './components/EditProviderModal' +import ConfirmModal from './components/ConfirmModal' +import MessageModal from './components/MessageModal' import './App.css' function App() { @@ -11,6 +13,20 @@ function App() { const [isAddModalOpen, setIsAddModalOpen] = useState(false) const [configPath, setConfigPath] = useState('') const [editingProviderId, setEditingProviderId] = useState(null) + + // Modal states + const [confirmModal, setConfirmModal] = useState<{ + show: boolean + title: string + message: string + onConfirm: () => void + } | null>(null) + const [messageModal, setMessageModal] = useState<{ + show: boolean + title: string + message: string + type: 'success' | 'error' | 'info' + } | null>(null) // 加载供应商列表 useEffect(() => { @@ -43,19 +59,35 @@ function App() { } const handleDeleteProvider = async (id: string) => { - if (confirm('确定要删除这个供应商吗?')) { - await window.electronAPI.deleteProvider(id) - await loadProviders() - } + setConfirmModal({ + show: true, + title: '删除供应商', + message: '确定要删除这个供应商吗?', + onConfirm: async () => { + await window.electronAPI.deleteProvider(id) + await loadProviders() + setConfirmModal(null) + } + }) } const handleSwitchProvider = async (id: string) => { const success = await window.electronAPI.switchProvider(id) if (success) { setCurrentProviderId(id) - alert('切换成功!') + setMessageModal({ + show: true, + title: '切换成功', + message: '供应商已成功切换!', + type: 'success' + }) } else { - alert('切换失败,请检查配置') + setMessageModal({ + show: true, + title: '切换失败', + message: '切换失败,请检查配置', + type: 'error' + }) } } @@ -64,10 +96,20 @@ function App() { await window.electronAPI.updateProvider(provider) await loadProviders() setEditingProviderId(null) - alert('保存成功!') + setMessageModal({ + show: true, + title: '保存成功', + message: '供应商信息已更新!', + type: 'success' + }) } catch (error) { console.error('更新供应商失败:', error) - alert('保存失败,请重试') + setMessageModal({ + show: true, + title: '保存失败', + message: '保存失败,请重试', + type: 'error' + }) } } @@ -129,6 +171,24 @@ function App() { onClose={() => setEditingProviderId(null)} /> )} + + {confirmModal && ( + setConfirmModal(null)} + /> + )} + + {messageModal && ( + setMessageModal(null)} + /> + )} ) } diff --git a/src/renderer/components/AddProviderModal.tsx b/src/renderer/components/AddProviderModal.tsx index 6d79af3..024a1de 100644 --- a/src/renderer/components/AddProviderModal.tsx +++ b/src/renderer/components/AddProviderModal.tsx @@ -5,21 +5,23 @@ import './AddProviderModal.css' interface AddProviderModalProps { onAdd: (provider: Omit) => void onClose: () => void + onError?: (message: string) => void } -const AddProviderModal: React.FC = ({ onAdd, onClose }) => { +const AddProviderModal: React.FC = ({ onAdd, onClose, onError }) => { const [formData, setFormData] = useState({ name: '', apiUrl: '', apiKey: '' }) const [showPassword, setShowPassword] = useState(false) + const [error, setError] = useState('') const handleSubmit = (e: React.FormEvent) => { e.preventDefault() if (!formData.name || !formData.apiUrl || !formData.apiKey) { - alert('请填写所有必填字段') + setError('请填写所有必填字段') return } @@ -75,6 +77,12 @@ const AddProviderModal: React.FC = ({ onAdd, onClose }) =
+ {error && ( +
+ {error} +
+ )} +
void + onCancel: () => void +} + +const ConfirmModal: React.FC = ({ + title, + message, + confirmText = '确定', + cancelText = '取消', + onConfirm, + onCancel +}) => { + return ( +
+
e.stopPropagation()}> +

{title}

+

{message}

+ +
+ + +
+
+
+ ) +} + +export default ConfirmModal \ No newline at end of file diff --git a/src/renderer/components/EditProviderModal.tsx b/src/renderer/components/EditProviderModal.tsx index 6ef0a9f..8822925 100644 --- a/src/renderer/components/EditProviderModal.tsx +++ b/src/renderer/components/EditProviderModal.tsx @@ -15,6 +15,7 @@ const EditProviderModal: React.FC = ({ provider, onSave, apiKey: provider.apiKey }) const [showPassword, setShowPassword] = useState(false) + const [error, setError] = useState('') useEffect(() => { setFormData({ @@ -28,7 +29,7 @@ const EditProviderModal: React.FC = ({ provider, onSave, e.preventDefault() if (!formData.name || !formData.apiUrl || !formData.apiKey) { - alert('请填写所有必填字段') + setError('请填写所有必填字段') return } @@ -52,6 +53,12 @@ const EditProviderModal: React.FC = ({ provider, onSave,

编辑供应商

+ {error && ( +
+ {error} +
+ )} +
void +} + +const MessageModal: React.FC = ({ + title, + message, + type = 'info', + onClose +}) => { + const getIcon = () => { + switch (type) { + case 'success': + return '✅' + case 'error': + return '❌' + default: + return 'ℹ️' + } + } + + return ( +
+
e.stopPropagation()}> +

{getIcon()} {title}

+

{message}

+ +
+ +
+
+
+ ) +} + +export default MessageModal \ No newline at end of file