Files
stash/stash-web/src/components/sidebar/ServicePanel.tsx
T
stash 1942e201e9 fix(web): 视觉与交互 1:1(页头/侧栏/卡片/详情/动效)
对齐项(8080 vs 8081 实测,误差 ≤1px):
- 侧栏:资料卡 224、服务面板 144、导航 143,navTop 548 与原版一致
- 分区卡:142/142/327/270 vs 142/142/326/269;标题 16/1.2、更多按钮 24px
- 应用条目:48px 圆形头像 + 10px 小认证标;hover 名字变主色(不再整行变色)
- 封面:hover 上浮 2px(0.2s ease),去掉缩放;CES 封面恢复 16/10
- 搜索框:44 高、无边框 + 卡片阴影
- 服务面板:状态药丸 22、统计 12/18、操作按钮 28、刷新时图标原地旋转
- 详情:返回链接 hover 下划线、跳转按钮 hover 深主色、view-in 淡入动画
- 菜单:hover 主色、子菜单 0.28s grid 高度动画、chevron 6px 旋转
- 回到顶部:right 30、top 50%、滚动后淡入(补内容区滚动监听)
- 主题:卡片阴影恢复 2%/6%(旧版值)
2026-10-28 20:16:41 +08:00

67 lines
1.9 KiB
TypeScript

import { Button, Card, Icon, Space, Tag, Text, Title } from '@stash/ui'
import type { Project } from '../../api'
/**
* 本地服务面板:连接状态、项目数、访问地址,以及两个操作入口。
* 只读展示 + 触发刷新,不负责导航。
*/
type ServicePanelProps = {
projects: Project[]
live: boolean
refreshing: boolean
onRefresh: () => void
}
export function ServicePanel({ projects, live, refreshing, onRefresh }: ServicePanelProps) {
const host = typeof window === 'undefined' ? '-' : window.location.host
return (
<Card padding="none" className="service-panel">
<Space justify="between">
<Title level={4} as="h2" weight="semibold">
本地服务
</Title>
<Tag tone={live ? 'success' : 'neutral'} dot className="service-status">
{live ? '已连接' : '未连接'}
</Tag>
</Space>
<div className="service-stats">
<Space justify="between">
<Text size="xs" tone="sub">
项目数
</Text>
<Text size="xs" strong>{projects.length}</Text>
</Space>
<Space justify="between">
<Text size="xs" tone="sub">
访问地址
</Text>
<Text size="xs" truncate title={host} className="service-host">
{host}
</Text>
</Space>
</div>
<div className="service-actions">
<Button
size="sm"
variant="secondary"
className="service-action"
spinning={refreshing}
icon={<Icon name="refresh_3_line" />}
onClick={onRefresh}
title="重新扫描项目"
>
重新扫描
</Button>
<a className="link-button" href="/api/projects" target="_blank" rel="noreferrer">
<Icon name="link_3_line" />
查看接口
</a>
</div>
</Card>
)
}