迁移: - better-sqlite3(原生C++) → sql.js(WASM纯JS), 兼容Node 24 - database-service.ts: PreparedStatement包装器保持API兼容 - main.ts: initialize()改为async/await - 移除@electron/rebuild和@types/better-sqlite3依赖 - 新增.npmrc阿里云镜像加速 UI/代码修复(任务1-6): 1. TerminalView: 清理111行调试日志(645→534行) 2. 设计系统: cyan/slate→accent-blue/dark-*颜色统一(FileRow/TransferItem/Breadcrumb/ContextMenu) 3. StatusBar: 重写接入实时连接状态,三区布局 4. SessionDialog: 私钥浏览按钮添加onClick处理 5. WelcomeView: 真实session数据替换硬编码假数据 6. SFTPView: emoji→Lucide图标(FolderOpen/Upload/Download/Trash2) 构建验证: tsc零错误 + vite build成功(Node 24.14.0)
143 lines
6.5 KiB
TypeScript
143 lines
6.5 KiB
TypeScript
import { Terminal, FolderSync, ArrowRightLeft, Globe, Settings, Plus, Zap, Inbox } from 'lucide-react'
|
|
import { useSessionStore } from '../stores'
|
|
import { useTabStore } from '../stores/tabStore'
|
|
|
|
interface WelcomeViewProps {
|
|
onNewSession?: () => void
|
|
onQuickConnect?: () => void
|
|
}
|
|
|
|
export default function WelcomeView({ onNewSession, onQuickConnect }: WelcomeViewProps) {
|
|
const { addTab } = useTabStore()
|
|
const sessions = useSessionStore((s) => s.sessions)
|
|
|
|
// 取最近 5 个会话作为最近连接
|
|
const recentSessions = sessions.slice(-5).reverse()
|
|
|
|
const handleSessionClick = (session: typeof sessions[number]) => {
|
|
addTab({
|
|
title: session.name || session.host,
|
|
type: 'terminal',
|
|
sessionId: session.id,
|
|
})
|
|
}
|
|
|
|
return (
|
|
<div className="h-full flex flex-col items-center justify-center bg-dark-900 p-8">
|
|
<div className="text-center mb-12">
|
|
<div className="w-20 h-20 bg-dark-700 rounded-2xl flex items-center justify-center mx-auto shadow-lg">
|
|
<Terminal className="w-10 h-10 text-white" />
|
|
</div>
|
|
</div>
|
|
|
|
<div className="grid grid-cols-2 gap-4 w-full max-w-2xl mb-12">
|
|
<button
|
|
onClick={onQuickConnect}
|
|
className="flex items-center gap-4 p-6 bg-dark-800 hover:bg-dark-700 rounded-xl border border-dark-700 hover:border-accent-blue transition-all group"
|
|
>
|
|
<div className="w-12 h-12 bg-accent-blue/20 rounded-lg flex items-center justify-center group-hover:bg-accent-blue/30 transition-colors">
|
|
<Zap className="w-6 h-6 text-accent-blue" />
|
|
</div>
|
|
<div className="text-left">
|
|
<div className="font-semibold text-gray-200">快速连接</div>
|
|
<div className="text-sm text-gray-500">输入地址快速建立连接</div>
|
|
</div>
|
|
</button>
|
|
|
|
<button
|
|
onClick={onNewSession}
|
|
className="flex items-center gap-4 p-6 bg-dark-800 hover:bg-dark-700 rounded-xl border border-dark-700 hover:border-accent-green transition-all group"
|
|
>
|
|
<div className="w-12 h-12 bg-accent-green/20 rounded-lg flex items-center justify-center group-hover:bg-accent-green/30 transition-colors">
|
|
<Plus className="w-6 h-6 text-white" />
|
|
</div>
|
|
<div className="text-left">
|
|
<div className="font-semibold text-gray-200">新建会话</div>
|
|
<div className="text-sm text-gray-500">创建并保存新的会话</div>
|
|
</div>
|
|
</button>
|
|
|
|
<button
|
|
onClick={() => addTab({ title: 'SFTP', type: 'sftp' })}
|
|
className="flex items-center gap-4 p-6 bg-dark-800 hover:bg-dark-700 rounded-xl border border-dark-700 hover:border-accent-purple transition-all group"
|
|
>
|
|
<div className="w-12 h-12 bg-accent-purple/20 rounded-lg flex items-center justify-center group-hover:bg-accent-purple/30 transition-colors">
|
|
<FolderSync className="w-6 h-6 text-accent-purple" />
|
|
</div>
|
|
<div className="text-left">
|
|
<div className="font-semibold text-gray-200">SFTP 传输</div>
|
|
<div className="text-sm text-gray-500">可视化文件管理</div>
|
|
</div>
|
|
</button>
|
|
|
|
<button
|
|
onClick={() => addTab({ title: '端口转发', type: 'portforward' })}
|
|
className="flex items-center gap-4 p-6 bg-dark-800 hover:bg-dark-700 rounded-xl border border-dark-700 hover:border-accent-orange transition-all group"
|
|
>
|
|
<div className="w-12 h-12 bg-orange-500/20 rounded-lg flex items-center justify-center group-hover:bg-orange-500/30 transition-colors">
|
|
<ArrowRightLeft className="w-6 h-6 text-orange-400" />
|
|
</div>
|
|
<div className="text-left">
|
|
<div className="font-semibold text-gray-200">端口转发</div>
|
|
<div className="text-sm text-gray-500">本地/远程/SOCKS5 代理</div>
|
|
</div>
|
|
</button>
|
|
|
|
<button
|
|
onClick={() => addTab({ title: '设置', type: 'settings' })}
|
|
className="flex items-center gap-4 p-6 bg-dark-800 hover:bg-dark-700 rounded-xl border border-dark-700 hover:border-gray-500 transition-all group"
|
|
>
|
|
<div className="w-12 h-12 bg-gray-700/50 rounded-lg flex items-center justify-center group-hover:bg-gray-700 transition-colors">
|
|
<Settings className="w-6 h-6 text-gray-400" />
|
|
</div>
|
|
<div className="text-left">
|
|
<div className="font-semibold text-gray-200">设置</div>
|
|
<div className="text-sm text-gray-500">配置应用偏好</div>
|
|
</div>
|
|
</button>
|
|
</div>
|
|
|
|
{/* Recent connections */}
|
|
<div className="w-full max-w-2xl">
|
|
<h3 className="text-sm font-medium text-gray-400 mb-4">最近连接</h3>
|
|
{recentSessions.length === 0 ? (
|
|
<div className="flex flex-col items-center justify-center py-10 text-gray-500">
|
|
<Inbox className="w-10 h-10 mb-3 text-gray-600" />
|
|
<p className="text-sm">暂无会话记录</p>
|
|
<p className="text-xs mt-1">点击上方「新建会话」创建第一个连接</p>
|
|
</div>
|
|
) : (
|
|
<div className="space-y-2">
|
|
{recentSessions.map((session) => (
|
|
<button
|
|
key={session.id}
|
|
onClick={() => handleSessionClick(session)}
|
|
className="w-full flex items-center justify-between p-4 bg-dark-800 hover:bg-dark-700 rounded-lg border border-dark-700 hover:border-accent-blue/50 transition-colors"
|
|
>
|
|
<div className="flex items-center gap-3">
|
|
<Globe className="w-5 h-5 text-accent-blue" />
|
|
<div className="text-left">
|
|
<div className="font-medium text-gray-200">{session.name}</div>
|
|
<div className="text-sm text-gray-500">
|
|
{session.username}@{session.host}{session.port !== 22 ? `:${session.port}` : ''}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<span className="text-xs text-gray-500">--</span>
|
|
</button>
|
|
))}
|
|
</div>
|
|
)}
|
|
</div>
|
|
|
|
{/* Shortcuts hint */}
|
|
<div className="mt-12 flex items-center gap-6 text-sm text-gray-500">
|
|
<span>快捷键:</span>
|
|
<span><kbd className="px-2 py-1 bg-dark-800 rounded">Ctrl+N</kbd> 新建会话</span>
|
|
<span><kbd className="px-2 py-1 bg-dark-800 rounded">Ctrl+K</kbd> 快速连接</span>
|
|
<span><kbd className="px-2 py-1 bg-dark-800 rounded">Ctrl+T</kbd> 新建标签</span>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|