mirror of
https://github.com/hicccc77/WeFlow.git
synced 2026-03-24 23:06:51 +00:00
feat: show settings as modal dialog
This commit is contained in:
@@ -10,7 +10,7 @@ import {
|
||||
Eye, EyeOff, FolderSearch, FolderOpen, Search, Copy,
|
||||
RotateCcw, Trash2, Plug, Check, Sun, Moon, Monitor,
|
||||
Palette, Database, HardDrive, Info, RefreshCw, ChevronDown, Download, Mic,
|
||||
ShieldCheck, Fingerprint, Lock, KeyRound, Bell, Globe, BarChart2
|
||||
ShieldCheck, Fingerprint, Lock, KeyRound, Bell, Globe, BarChart2, X
|
||||
} from 'lucide-react'
|
||||
import { Avatar } from '../components/Avatar'
|
||||
import './SettingsPage.scss'
|
||||
@@ -36,7 +36,11 @@ interface WxidOption {
|
||||
modifiedTime: number
|
||||
}
|
||||
|
||||
function SettingsPage() {
|
||||
interface SettingsPageProps {
|
||||
onClose?: () => void
|
||||
}
|
||||
|
||||
function SettingsPage({ onClose }: SettingsPageProps = {}) {
|
||||
const location = useLocation()
|
||||
const {
|
||||
isDbConnected,
|
||||
@@ -195,6 +199,17 @@ function SettingsPage() {
|
||||
setActiveTab(initialTab)
|
||||
}, [location.state])
|
||||
|
||||
useEffect(() => {
|
||||
if (!onClose) return
|
||||
const handleKeyDown = (event: KeyboardEvent) => {
|
||||
if (event.key === 'Escape') {
|
||||
onClose()
|
||||
}
|
||||
}
|
||||
document.addEventListener('keydown', handleKeyDown)
|
||||
return () => document.removeEventListener('keydown', handleKeyDown)
|
||||
}, [onClose])
|
||||
|
||||
useEffect(() => {
|
||||
const removeDb = window.electronAPI.key.onDbKeyStatus((payload: { message: string; level: number }) => {
|
||||
setDbKeyStatus(payload.message)
|
||||
@@ -2049,66 +2064,81 @@ function SettingsPage() {
|
||||
)
|
||||
|
||||
return (
|
||||
<div className="settings-page">
|
||||
{message && <div className={`message-toast ${message.success ? 'success' : 'error'}`}>{message.text}</div>}
|
||||
<div className="settings-modal-overlay" onClick={() => onClose?.()}>
|
||||
<div className="settings-page" onClick={(event) => event.stopPropagation()}>
|
||||
{message && <div className={`message-toast ${message.success ? 'success' : 'error'}`}>{message.text}</div>}
|
||||
|
||||
{/* 多账号选择对话框 */}
|
||||
{showWxidSelect && wxidOptions.length > 1 && (
|
||||
<div className="wxid-dialog-overlay" onClick={() => setShowWxidSelect(false)}>
|
||||
<div className="wxid-dialog" onClick={(e) => e.stopPropagation()}>
|
||||
<div className="wxid-dialog-header">
|
||||
<h3>检测到多个微信账号</h3>
|
||||
<p>请选择要使用的账号</p>
|
||||
</div>
|
||||
<div className="wxid-dialog-list">
|
||||
{wxidOptions.map((opt) => (
|
||||
<div
|
||||
key={opt.wxid}
|
||||
className={`wxid-dialog-item ${opt.wxid === wxid ? 'active' : ''}`}
|
||||
onClick={() => handleSelectWxid(opt.wxid)}
|
||||
>
|
||||
<span className="wxid-id">{opt.wxid}</span>
|
||||
<span className="wxid-date">最后修改 {new Date(opt.modifiedTime).toLocaleString()}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<div className="wxid-dialog-footer">
|
||||
<button className="btn btn-secondary" onClick={() => setShowWxidSelect(false)}>取消</button>
|
||||
{/* 多账号选择对话框 */}
|
||||
{showWxidSelect && wxidOptions.length > 1 && (
|
||||
<div className="wxid-dialog-overlay" onClick={() => setShowWxidSelect(false)}>
|
||||
<div className="wxid-dialog" onClick={(e) => e.stopPropagation()}>
|
||||
<div className="wxid-dialog-header">
|
||||
<h3>检测到多个微信账号</h3>
|
||||
<p>请选择要使用的账号</p>
|
||||
</div>
|
||||
<div className="wxid-dialog-list">
|
||||
{wxidOptions.map((opt) => (
|
||||
<div
|
||||
key={opt.wxid}
|
||||
className={`wxid-dialog-item ${opt.wxid === wxid ? 'active' : ''}`}
|
||||
onClick={() => handleSelectWxid(opt.wxid)}
|
||||
>
|
||||
<span className="wxid-id">{opt.wxid}</span>
|
||||
<span className="wxid-date">最后修改 {new Date(opt.modifiedTime).toLocaleString()}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<div className="wxid-dialog-footer">
|
||||
<button className="btn btn-secondary" onClick={() => setShowWxidSelect(false)}>取消</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
)}
|
||||
|
||||
<div className="settings-header">
|
||||
<h1>设置</h1>
|
||||
<div className="settings-actions">
|
||||
<button className="btn btn-secondary" onClick={handleTestConnection} disabled={isLoading || isTesting}>
|
||||
<Plug size={16} /> {isTesting ? '测试中...' : '测试连接'}
|
||||
</button>
|
||||
<div className="settings-header">
|
||||
<div className="settings-title-block">
|
||||
<h1>设置</h1>
|
||||
<p>在这里集中调整 WeFlow 的功能、外观与数据行为。</p>
|
||||
</div>
|
||||
<div className="settings-actions">
|
||||
<button className="btn btn-secondary" onClick={handleTestConnection} disabled={isLoading || isTesting}>
|
||||
<Plug size={16} /> {isTesting ? '测试中...' : '测试连接'}
|
||||
</button>
|
||||
{onClose && (
|
||||
<button type="button" className="settings-close-btn" onClick={onClose} aria-label="关闭设置">
|
||||
<X size={18} />
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="settings-layout">
|
||||
<div className="settings-tabs" role="tablist" aria-label="设置项">
|
||||
{tabs.map(tab => (
|
||||
<button
|
||||
key={tab.id}
|
||||
className={`tab-btn ${activeTab === tab.id ? 'active' : ''}`}
|
||||
onClick={() => setActiveTab(tab.id)}
|
||||
>
|
||||
<tab.icon size={16} />
|
||||
<span>{tab.label}</span>
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="settings-body">
|
||||
{activeTab === 'appearance' && renderAppearanceTab()}
|
||||
{activeTab === 'notification' && renderNotificationTab()}
|
||||
{activeTab === 'database' && renderDatabaseTab()}
|
||||
{activeTab === 'models' && renderModelsTab()}
|
||||
{activeTab === 'cache' && renderCacheTab()}
|
||||
{activeTab === 'api' && renderApiTab()}
|
||||
{activeTab === 'analytics' && renderAnalyticsTab()}
|
||||
{activeTab === 'security' && renderSecurityTab()}
|
||||
{activeTab === 'about' && renderAboutTab()}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="settings-tabs">
|
||||
{tabs.map(tab => (
|
||||
<button key={tab.id} className={`tab-btn ${activeTab === tab.id ? 'active' : ''}`} onClick={() => setActiveTab(tab.id)}>
|
||||
<tab.icon size={16} />
|
||||
<span>{tab.label}</span>
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="settings-body">
|
||||
{activeTab === 'appearance' && renderAppearanceTab()}
|
||||
{activeTab === 'notification' && renderNotificationTab()}
|
||||
{activeTab === 'database' && renderDatabaseTab()}
|
||||
{activeTab === 'models' && renderModelsTab()}
|
||||
{activeTab === 'cache' && renderCacheTab()}
|
||||
{activeTab === 'api' && renderApiTab()}
|
||||
{activeTab === 'analytics' && renderAnalyticsTab()}
|
||||
{activeTab === 'security' && renderSecurityTab()}
|
||||
{activeTab === 'about' && renderAboutTab()}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user