用 Modal 组件替换所有 alert 弹窗
- 创建 ConfirmModal 和 MessageModal 组件 - 更新 App.tsx 使用新的 Modal 组件 - 改进表单验证错误显示 - 提升用户体验和界面一致性
This commit is contained in:
@@ -5,21 +5,23 @@ import './AddProviderModal.css'
|
||||
interface AddProviderModalProps {
|
||||
onAdd: (provider: Omit<Provider, 'id'>) => void
|
||||
onClose: () => void
|
||||
onError?: (message: string) => void
|
||||
}
|
||||
|
||||
const AddProviderModal: React.FC<AddProviderModalProps> = ({ onAdd, onClose }) => {
|
||||
const AddProviderModal: React.FC<AddProviderModalProps> = ({ onAdd, onClose, onError }) => {
|
||||
const [formData, setFormData] = useState({
|
||||
name: '',
|
||||
apiUrl: '',
|
||||
apiKey: ''
|
||||
})
|
||||
const [showPassword, setShowPassword] = useState(false)
|
||||
const [error, setError] = useState<string>('')
|
||||
|
||||
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<AddProviderModalProps> = ({ onAdd, onClose }) =
|
||||
</div>
|
||||
|
||||
<form onSubmit={handleSubmit}>
|
||||
{error && (
|
||||
<div style={{ color: 'red', marginBottom: '1rem', padding: '0.5rem', backgroundColor: '#ffe6e6', borderRadius: '4px' }}>
|
||||
{error}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="form-group">
|
||||
<label htmlFor="name">供应商名称 *</label>
|
||||
<input
|
||||
|
||||
40
src/renderer/components/ConfirmModal.tsx
Normal file
40
src/renderer/components/ConfirmModal.tsx
Normal file
@@ -0,0 +1,40 @@
|
||||
import React from 'react'
|
||||
import './AddProviderModal.css'
|
||||
|
||||
interface ConfirmModalProps {
|
||||
title: string
|
||||
message: string
|
||||
confirmText?: string
|
||||
cancelText?: string
|
||||
onConfirm: () => void
|
||||
onCancel: () => void
|
||||
}
|
||||
|
||||
const ConfirmModal: React.FC<ConfirmModalProps> = ({
|
||||
title,
|
||||
message,
|
||||
confirmText = '确定',
|
||||
cancelText = '取消',
|
||||
onConfirm,
|
||||
onCancel
|
||||
}) => {
|
||||
return (
|
||||
<div className="modal-overlay" onClick={onCancel}>
|
||||
<div className="modal-content" onClick={(e) => e.stopPropagation()}>
|
||||
<h2>{title}</h2>
|
||||
<p>{message}</p>
|
||||
|
||||
<div className="form-actions">
|
||||
<button type="button" className="cancel-btn" onClick={onCancel}>
|
||||
{cancelText}
|
||||
</button>
|
||||
<button type="button" className="submit-btn" onClick={onConfirm}>
|
||||
{confirmText}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default ConfirmModal
|
||||
@@ -15,6 +15,7 @@ const EditProviderModal: React.FC<EditProviderModalProps> = ({ provider, onSave,
|
||||
apiKey: provider.apiKey
|
||||
})
|
||||
const [showPassword, setShowPassword] = useState(false)
|
||||
const [error, setError] = useState<string>('')
|
||||
|
||||
useEffect(() => {
|
||||
setFormData({
|
||||
@@ -28,7 +29,7 @@ const EditProviderModal: React.FC<EditProviderModalProps> = ({ provider, onSave,
|
||||
e.preventDefault()
|
||||
|
||||
if (!formData.name || !formData.apiUrl || !formData.apiKey) {
|
||||
alert('请填写所有必填字段')
|
||||
setError('请填写所有必填字段')
|
||||
return
|
||||
}
|
||||
|
||||
@@ -52,6 +53,12 @@ const EditProviderModal: React.FC<EditProviderModalProps> = ({ provider, onSave,
|
||||
<h2>编辑供应商</h2>
|
||||
|
||||
<form onSubmit={handleSubmit}>
|
||||
{error && (
|
||||
<div style={{ color: 'red', marginBottom: '1rem', padding: '0.5rem', backgroundColor: '#ffe6e6', borderRadius: '4px' }}>
|
||||
{error}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="form-group">
|
||||
<label htmlFor="name">供应商名称 *</label>
|
||||
<input
|
||||
|
||||
44
src/renderer/components/MessageModal.tsx
Normal file
44
src/renderer/components/MessageModal.tsx
Normal file
@@ -0,0 +1,44 @@
|
||||
import React from 'react'
|
||||
import './AddProviderModal.css'
|
||||
|
||||
interface MessageModalProps {
|
||||
title: string
|
||||
message: string
|
||||
type?: 'success' | 'error' | 'info'
|
||||
onClose: () => void
|
||||
}
|
||||
|
||||
const MessageModal: React.FC<MessageModalProps> = ({
|
||||
title,
|
||||
message,
|
||||
type = 'info',
|
||||
onClose
|
||||
}) => {
|
||||
const getIcon = () => {
|
||||
switch (type) {
|
||||
case 'success':
|
||||
return '✅'
|
||||
case 'error':
|
||||
return '❌'
|
||||
default:
|
||||
return 'ℹ️'
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="modal-overlay" onClick={onClose}>
|
||||
<div className="modal-content" onClick={(e) => e.stopPropagation()}>
|
||||
<h2>{getIcon()} {title}</h2>
|
||||
<p>{message}</p>
|
||||
|
||||
<div className="form-actions">
|
||||
<button type="button" className="submit-btn" onClick={onClose}>
|
||||
确定
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default MessageModal
|
||||
Reference in New Issue
Block a user