style: 数据源类型使用品牌SVG图标 + 按钮去装饰

- MySQL: 官方海豚蓝色SVG
- PostgreSQL: 官方大象蓝色轮廓SVG
- Redis: 官方红色菱形堆叠SVG
- MongoDB: 官方绿色叶子SVG
- 底部按钮去掉闪电图标,纯文字简洁风格
- 前端构建零错误, 后端202测试通过
This commit is contained in:
logan committed 2026-05-22 23:35:55 +08:00
1 parent e0cb505d43
commit 836ea97ee5
142 files changed
+54 -36571

No files matched your search

+54 -19
View File
@@ -317,6 +317,46 @@ function InstanceDetail({ instance, onBack, config, canEdit, canDelete, onDelete
);
}
/* ---------- Database Brand SVG Icons ---------- */
function MySQLIcon({ className }: { className?: string }) {
return (
<svg viewBox="0 0 256 256" className={className}>
<path d="M235.6 184.1c-13.2-1.3-24.5-10.2-29.8-22.1a7.7 7.7 0 01-.4-1.5c-1.2-3.2-1.5-7-.7-10.8 2-9.5 9.9-15.2 18.6-14.3 8.7.9 15.6 8.1 16.2 17.7.5 7.6-3.2 14.3-9 18.2a1.3 1.3 0 00-.5 1.5c2.7 7.4 8 12.6 14.9 14.4a1.3 1.3 0 01-.8 2.4c-3-.5-5.9-2.4-8.5-5.5z" fill="#00758F"/>
<path d="M28.3 200.3c0 .3.2.5.5.5h5.6c.3 0 .5-.2.5-.5v-19.4h7.8c.3 0 .5-.2.5-.5v-4.4c0-.3-.2-.5-.5-.5H20.5c-.3 0-.5.2-.5.5v4.4c0 .3.2.5.5.5h7.8v19.4zm22.5 0c0 .3.2.5.5.5h5.6c.3 0 .5-.2.5-.5v-24.8c0-.3-.2-.5-.5-.5h-5.6c-.3 0-.5.2-.5.5v24.8zm15.6 0c0 .3.2.5.5.5h13.2c.3 0 .5-.2.5-.5v-4.4c0-.3-.2-.5-.5-.5h-7.1v-19.9c0-.3-.2-.5-.5-.5h-5.6c-.3 0-.5.2-.5.5v24.8zm22.5 0c0 .3.2.5.5.5h5.6c.3 0 .5-.2.5-.5v-24.8c0-.3-.2-.5-.5-.5h-5.6c-.3 0-.5.2-.5.5v24.8zm16.8-12.4c0-7.5 5.7-12.9 13.2-12.9 4.6 0 8.1 1.9 10.5 5l-3.9 3.2c-1.7-2.2-3.9-3.3-6.4-3.3-4.6 0-7.9 3.4-7.9 8s3.3 8 7.9 8c2.5 0 4.7-1.1 6.4-3.3l3.9 3.2c-2.4 3.1-5.9 5-10.5 5-7.5 0-13.2-5.4-13.2-12.9z" fill="#F29111"/>
<ellipse cx="128" cy="56" rx="90" ry="28" fill="none" stroke="#00758F" strokeWidth="6"/>
</svg>
);
}
function PostgreSQLIcon({ className }: { className?: string }) {
return (
<svg viewBox="0 0 256 256" className={className}>
<path d="M191.5 18.2c-1.2-10.2-7.8-17.6-18.3-18C163.6-.3 153 4 145.2 12c-7.2 7.3-11 17-10.6 27 .3 5.7 1.5 11 3.6 15.7-3.2 7.5-7.6 18.2-10.5 25.8-4.5 11.8-13.4 29.7-19.6 29.7-1.5 0-3.2-.8-5-2.4-6.5-5.8-14.4-8.8-22.9-8.8-11 0-20.7 5.2-25.5 13.6-3.6 6.3-3.7 13.5-.4 19.7 4 7.4 12.5 12.8 22 14l.7.1c6.6.6 13.6-2.3 20.7-8.6 3.3-2.9 7.6-4.5 12.4-4.7 7.4-.3 14.8 3.3 18.7 9.1 3.4 5.1 3.5 11.5.2 16.6-2.2 3.4-5.3 5.8-9 7.1-3 1-5.3 3.3-6.3 6.3-1 3.1-.5 6.4 1.4 9 3.8 5.2 9.3 7.9 15.8 7.9 4.5 0 9.2-1.3 13.5-3.8 4.6-2.7 7.9-6.7 9.6-11.7 1.4-4.1 1.5-8.5.2-12.8l-.1-.3c-2-6.5.3-13.8 5.7-17.9 5.6-4.2 13-4.5 18.9-.7 8.8 5.6 14.1 13.2 15.4 22 .6 3.8.4 7.7-.6 11.4" fill="none" stroke="#336791" strokeWidth="10" strokeLinecap="round" strokeLinejoin="round"/>
</svg>
);
}
function RedisIcon({ className }: { className?: string }) {
return (
<svg viewBox="0 0 256 256" className={className}>
<path d="M128 190L20.5 145.3v-20.6l107.5 44.7 107.5-44.7v20.6L128 190z" fill="#912626"/>
<path d="M128 149.4L20.5 104.7V84.1L128 128.8l107.5-44.7v20.6L128 149.4z" fill="#C6302B"/>
<path d="M128 108.8L20.5 64.1V43.5L128 88.2l107.5-44.7v20.6L128 108.8z" fill="#912626"/>
<path d="M128 66.5L73.2 43.7 128 20.9l54.8 22.8L128 66.5z" fill="#C6302B"/>
<path d="M128 235.2l-107.5-44.7v-20.6L128 214.6l107.5-44.7v20.6L128 235.2z" fill="#912626"/>
</svg>
);
}
function MongoDBIcon({ className }: { className?: string }) {
return (
<svg viewBox="0 0 256 256" className={className}>
<path d="M128 20c-4.4 16-10 28-17.6 39.2C101.6 72.4 88.8 84 78 98c-14.8 19.2-23.2 40.4-23.2 65.2 0 38.8 31.2 72.8 73.2 72.8s73.2-34 73.2-72.8c0-24.8-8.4-46-23.2-65.2C167.2 84 154.4 72.4 145.6 59.2 138 48 132.4 36 128 20z" fill="#439934"/>
<path d="M128 20c-2 12-6.8 22-12.8 31.2C107.6 63.6 98 73.6 89.6 85.2 78 100.4 72 118 72 138c0 30 22 56 56 56s56-26 56-56c0-20-6-37.6-17.6-52.8C158 73.6 148.4 63.6 140.8 51.2 134.8 42 130 32 128 20z" fill="#4AA841"/>
</svg>
);
}
/* ---------- CreateInstanceForm ---------- */
const PRESET_MASK_FIELDS = [
'mobile', 'concat_mobile', 'email_alias', 'email', 'password',
@@ -426,23 +466,18 @@ function CreateInstanceForm({ defaultType, onCancel, onCreated }: { defaultType:
<h3 className="text-sm font-semibold text-[var(--dg-text-secondary)]">数据源类型</h3>
<div className="grid grid-cols-4 gap-3">
{[
{ value: 'mysql', label: 'MySQL', icon: Database, color: 'text-[#26a69a]', bg: 'bg-[rgba(0,117,143,0.15)]' },
{ value: 'postgres', label: 'PostgreSQL', icon: Server, color: 'text-[#42a5f5]', bg: 'bg-[rgba(51,103,145,0.15)]' },
{ value: 'redis', label: 'Redis', icon: Zap, color: 'text-[#ef5350]', bg: 'bg-[rgba(220,50,32,0.15)]' },
{ value: 'mongo', label: 'MongoDB', icon: Leaf, color: 'text-[#66bb6a]', bg: 'bg-[rgba(71,162,72,0.15)]' },
].map(t => {
const Icon = t.icon;
return (
<button key={t.value} type="button" onClick={() => handleTypeChange(t.value)}
className={'flex flex-col items-center gap-2 p-3 rounded-lg border-2 transition-all '
+ (dbType === t.value ? 'border-blue-500 bg-blue-500/5' : 'border-[var(--dg-border)] hover:border-[var(--dg-text-muted)]')}>
<div className={'w-10 h-10 rounded-lg flex items-center justify-center ' + t.bg}>
<Icon className={'w-5 h-5 ' + t.color} />
</div>
<span className="text-xs font-medium">{t.label}</span>
</button>
);
})}
{ value: 'mysql', label: 'MySQL', Icon: MySQLIcon },
{ value: 'postgres', label: 'PostgreSQL', Icon: PostgreSQLIcon },
{ value: 'redis', label: 'Redis', Icon: RedisIcon },
{ value: 'mongo', label: 'MongoDB', Icon: MongoDBIcon },
].map(t => (
<button key={t.value} type="button" onClick={() => handleTypeChange(t.value)}
className={'flex flex-col items-center gap-2 p-3 rounded-lg border-2 transition-all '
+ (dbType === t.value ? 'border-blue-500 bg-blue-500/5' : 'border-[var(--dg-border)] hover:border-[var(--dg-text-muted)]')}>
<t.Icon className="w-8 h-8" />
<span className="text-xs font-medium">{t.label}</span>
</button>
))}
</div>
</CardContent>
</Card>
@@ -614,8 +649,8 @@ function CreateInstanceForm({ defaultType, onCancel, onCreated }: { defaultType:
{error && <div className="text-sm text-red-400">{error}</div>}
<div className="flex items-center justify-between">
<button onClick={handleTestConnection} disabled={testing || !host || !port}
className="flex items-center gap-2 px-4 py-2.5 bg-[var(--dg-bg-tertiary)] border border-[var(--dg-border)] rounded-lg text-sm font-medium text-[var(--dg-text-primary)] hover:bg-[var(--dg-bg-hover)] disabled:opacity-40">
<Zap className="w-4 h-4" /> {testing ? '测试中...' : '测试连接'}
className="px-4 py-2.5 bg-[var(--dg-bg-tertiary)] border border-[var(--dg-border)] rounded-lg text-sm font-medium text-[var(--dg-text-primary)] hover:bg-[var(--dg-bg-hover)] disabled:opacity-40">
{testing ? '测试中...' : '测试连接'}
</button>
<div className="flex gap-3">
<button onClick={onCancel} className="px-4 py-2 bg-[var(--dg-bg-tertiary)] border border-[var(--dg-border)] rounded-lg text-sm hover:bg-[var(--dg-bg-hover)]">取消</button>