用 Modal 组件替换所有 alert 弹窗

- 创建 ConfirmModal 和 MessageModal 组件
- 更新 App.tsx 使用新的 Modal 组件
- 改进表单验证错误显示
- 提升用户体验和界面一致性
This commit is contained in:
farion1231
2025-08-06 07:44:50 +08:00
parent e613696e08
commit 48dcb23ea5
5 changed files with 170 additions and 11 deletions

View File

@@ -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

View 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

View File

@@ -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

View 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