mirror of
https://github.com/shy3130/tick-stock-panel.git
synced 2026-11-02 02:16:13 +00:00
fix(ui): 修复 text-base 与色板 token base 撞名
色板里定义了颜色 token base, Tailwind 的 text-base 因此生成 color 规则 (文字被涂成 --base 背景色) 而非 16px 字号 —— 标题字号丢失, accent 底按钮 文字与底色同色不可见。全量替换: 字号意图改写 text-[16px] leading-6, accent 底按钮文字改写 text-white; tailwind.config.ts 注释禁用 text-base。
This commit is contained in:
@@ -12,7 +12,7 @@ export function EmptyState({ icon: Icon = Construction, title, hint }: Props) {
|
||||
<div className="h-full grid place-items-center px-8 py-16">
|
||||
<div className="text-center max-w-md">
|
||||
<Icon className="mx-auto h-10 w-10 text-muted" strokeWidth={1.5} />
|
||||
<h2 className="mt-4 text-base font-medium text-foreground">{title}</h2>
|
||||
<h2 className="mt-4 text-[16px] leading-6 font-medium text-foreground">{title}</h2>
|
||||
{hint && <p className="mt-2 text-sm text-secondary leading-relaxed">{hint}</p>}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -385,7 +385,7 @@ export function ExtDimensionAnalysis({
|
||||
<div className="px-5 py-4 border-b border-border flex items-center justify-between gap-4">
|
||||
<div>
|
||||
<div className="flex items-center gap-2">
|
||||
<h3 className="text-base font-semibold text-foreground">{menu?.template === 'table' || menu?.template === 'ranking' ? '明细列表' : currentGroup?.key ?? `选择${activeKindLabel}`}</h3>
|
||||
<h3 className="text-[16px] leading-6 font-semibold text-foreground">{menu?.template === 'table' || menu?.template === 'ranking' ? '明细列表' : currentGroup?.key ?? `选择${activeKindLabel}`}</h3>
|
||||
<span className="rounded-full bg-accent/10 px-2 py-0.5 text-[10px] text-accent">{tableRows.length} 条</span>
|
||||
</div>
|
||||
<p className="mt-1 text-xs text-muted">列来自菜单 detail_columns:{displayColumns.map(f => f.label || f.field).join(' / ') || '暂无字段'}</p>
|
||||
|
||||
@@ -98,7 +98,7 @@ export function StockIntradayChart({
|
||||
<div className="text-xs text-muted">暂无分钟数据</div>
|
||||
<button
|
||||
onClick={() => setMinuteDismissed(false)}
|
||||
className="px-4 py-1.5 rounded-btn bg-accent/90 text-base text-xs font-medium hover:bg-accent transition-colors duration-150"
|
||||
className="px-4 py-1.5 rounded-btn bg-accent/90 text-white text-xs font-medium hover:bg-accent transition-colors duration-150"
|
||||
>
|
||||
获取分钟K
|
||||
</button>
|
||||
@@ -109,7 +109,7 @@ export function StockIntradayChart({
|
||||
<div className="flex items-center gap-3">
|
||||
<button
|
||||
onClick={() => fetchMinute.mutate()}
|
||||
className="px-4 py-1.5 rounded-btn bg-accent/90 text-base text-xs font-medium hover:bg-accent transition-colors duration-150"
|
||||
className="px-4 py-1.5 rounded-btn bg-accent/90 text-white text-xs font-medium hover:bg-accent transition-colors duration-150"
|
||||
>
|
||||
确定
|
||||
</button>
|
||||
|
||||
@@ -479,7 +479,7 @@ export function PresetFetchState({
|
||||
<div className="h-full grid place-items-center px-8 py-16">
|
||||
<div className="text-center max-w-md">
|
||||
<DownloadCloud className="mx-auto h-10 w-10 text-muted" strokeWidth={1.5} />
|
||||
<h2 className="mt-4 text-base font-medium text-foreground">{title}</h2>
|
||||
<h2 className="mt-4 text-[16px] leading-6 font-medium text-foreground">{title}</h2>
|
||||
<p className="mt-2 text-sm text-secondary leading-relaxed">{hint}</p>
|
||||
<button
|
||||
onClick={onFetch}
|
||||
|
||||
@@ -86,7 +86,7 @@ export function ActiveJobCard({ job }: { job: PipelineJob }) {
|
||||
</div>
|
||||
{!isDone && (
|
||||
<div className="font-mono text-2xl font-bold tracking-tight">
|
||||
{job.progress}<span className="text-base text-muted">%</span>
|
||||
{job.progress}<span className="text-[16px] leading-6 text-muted">%</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -126,7 +126,7 @@ export function EnrichedRebuildPanel({
|
||||
<button
|
||||
onClick={() => rebuild.mutate()}
|
||||
disabled={!canRebuild || isRunning || rebuild.isPending}
|
||||
className="w-full inline-flex items-center justify-center gap-1.5 px-3 py-1.5 rounded-btn bg-accent/90 text-base text-xs font-medium hover:bg-accent disabled:opacity-40 disabled:pointer-events-none transition-colors duration-150"
|
||||
className="w-full inline-flex items-center justify-center gap-1.5 px-3 py-1.5 rounded-btn bg-accent/90 text-white text-xs font-medium hover:bg-accent disabled:opacity-40 disabled:pointer-events-none transition-colors duration-150"
|
||||
>
|
||||
{rebuild.isPending ? (
|
||||
<><Loader2 className="h-3 w-3 animate-spin" />计算中…</>
|
||||
|
||||
@@ -78,7 +78,7 @@ export function ExtendHistoryPanel({ hasCap, isRunning, earliestDate, onStart }:
|
||||
<button
|
||||
onClick={() => extend.mutate()}
|
||||
disabled={!hasBatchCap || isRunning || extend.isPending || !earliestDate}
|
||||
className="w-full inline-flex items-center justify-center gap-1.5 px-3 py-1.5 rounded-btn bg-accent/90 text-base text-xs font-medium hover:bg-accent disabled:opacity-40 disabled:pointer-events-none transition-colors duration-150"
|
||||
className="w-full inline-flex items-center justify-center gap-1.5 px-3 py-1.5 rounded-btn bg-accent/90 text-white text-xs font-medium hover:bg-accent disabled:opacity-40 disabled:pointer-events-none transition-colors duration-150"
|
||||
>
|
||||
{extend.isPending ? (
|
||||
<>
|
||||
|
||||
@@ -87,7 +87,7 @@ export function RepairDailyPanel({ hasCap, isRunning, latestDate, onStart }: {
|
||||
<button
|
||||
onClick={() => repair.mutate()}
|
||||
disabled={!canSubmit}
|
||||
className="w-full inline-flex items-center justify-center gap-1.5 px-3 py-1.5 rounded-btn bg-accent/90 text-base text-xs font-medium hover:bg-accent disabled:opacity-40 disabled:pointer-events-none transition-colors duration-150"
|
||||
className="w-full inline-flex items-center justify-center gap-1.5 px-3 py-1.5 rounded-btn bg-accent/90 text-white text-xs font-medium hover:bg-accent disabled:opacity-40 disabled:pointer-events-none transition-colors duration-150"
|
||||
>
|
||||
{repair.isPending ? (
|
||||
<>
|
||||
|
||||
@@ -324,7 +324,7 @@ export function CreateExtDialog({ onClose }: { onClose: () => void }) {
|
||||
<div className="px-6 pt-5 pb-4">
|
||||
<div className="flex items-center justify-between">
|
||||
<div>
|
||||
<h3 className="text-base font-semibold text-foreground">新增扩展数据</h3>
|
||||
<h3 className="text-[16px] leading-6 font-semibold text-foreground">新增扩展数据</h3>
|
||||
<p className="text-[11px] mt-1 inline-flex items-center gap-1 bg-amber-500/10 text-amber-400 px-2 py-0.5 rounded-md font-medium">
|
||||
接入自有数据,与标的自动关联(第三方接口或 CSV/Excel),支持概念、人气、资金流、舆情、研报评分标签等场景
|
||||
</p>
|
||||
@@ -452,7 +452,7 @@ export function CreateExtDialog({ onClose }: { onClose: () => void }) {
|
||||
<button
|
||||
onClick={handleDetectUrl}
|
||||
disabled={detecting || !url.trim()}
|
||||
className="h-8 inline-flex items-center gap-1.5 rounded-lg bg-accent px-3 text-xs font-medium text-base hover:bg-accent/90 disabled:opacity-40 transition-colors"
|
||||
className="h-8 inline-flex items-center gap-1.5 rounded-lg bg-accent px-3 text-xs font-medium text-white hover:bg-accent/90 disabled:opacity-40 transition-colors"
|
||||
>
|
||||
{detecting ? <Loader2 className="h-3.5 w-3.5 animate-spin" /> : <RefreshCw className="h-3.5 w-3.5" />}
|
||||
测试识别
|
||||
@@ -656,7 +656,7 @@ export function CreateExtDialog({ onClose }: { onClose: () => void }) {
|
||||
<div className="text-[11px] text-muted">手动添加字段后即可创建空表结构</div>
|
||||
<button
|
||||
onClick={addField}
|
||||
className="inline-flex items-center gap-1 rounded-lg bg-accent px-3 py-1.5 text-xs font-medium text-base hover:bg-accent/90 transition-colors"
|
||||
className="inline-flex items-center gap-1 rounded-lg bg-accent px-3 py-1.5 text-xs font-medium text-white hover:bg-accent/90 transition-colors"
|
||||
>
|
||||
<Plus className="h-3.5 w-3.5" />
|
||||
添加字段
|
||||
@@ -788,7 +788,7 @@ export function CreateExtDialog({ onClose }: { onClose: () => void }) {
|
||||
<button
|
||||
onClick={() => create.mutate()}
|
||||
disabled={!valid || create.isPending}
|
||||
className="px-5 py-2 rounded-lg bg-accent text-base text-xs font-medium hover:bg-accent/90 disabled:opacity-40 transition-colors shadow-sm shadow-accent/20"
|
||||
className="px-5 py-2 rounded-lg bg-accent text-white text-xs font-medium hover:bg-accent/90 disabled:opacity-40 transition-colors shadow-sm shadow-accent/20"
|
||||
>
|
||||
{create.isPending ? '创建中…' : '创建'}
|
||||
</button>
|
||||
|
||||
@@ -243,7 +243,7 @@ export function EditExtDialog({ config, onClose }: { config: ExtDataConfig; onCl
|
||||
<button
|
||||
onClick={() => update.mutate()}
|
||||
disabled={!valid || update.isPending}
|
||||
className="px-4 py-1.5 rounded-btn bg-accent/90 text-base text-xs font-medium hover:bg-accent disabled:opacity-40 transition-colors"
|
||||
className="px-4 py-1.5 rounded-btn bg-accent/90 text-white text-xs font-medium hover:bg-accent disabled:opacity-40 transition-colors"
|
||||
>
|
||||
{update.isPending ? '保存中…' : '保存'}
|
||||
</button>
|
||||
|
||||
@@ -475,7 +475,7 @@ export function ExtDataPullPanel({ config, onSaved }: {
|
||||
<button
|
||||
onClick={handleRun}
|
||||
disabled={running || !url}
|
||||
className="inline-flex items-center justify-center gap-1 px-2 py-2 rounded-btn bg-accent/90 text-base text-xs font-medium hover:bg-accent disabled:opacity-40 transition-colors"
|
||||
className="inline-flex items-center justify-center gap-1 px-2 py-2 rounded-btn bg-accent/90 text-white text-xs font-medium hover:bg-accent disabled:opacity-40 transition-colors"
|
||||
>
|
||||
{running ? <Loader2 className="h-3.5 w-3.5 animate-spin" /> : <Zap className="h-3.5 w-3.5" />}
|
||||
立即执行
|
||||
@@ -484,7 +484,7 @@ export function ExtDataPullPanel({ config, onSaved }: {
|
||||
<button
|
||||
onClick={() => handleSave(false)}
|
||||
disabled={saving || !url}
|
||||
className="w-full inline-flex items-center justify-center gap-1 py-2 rounded-btn bg-accent/90 text-base text-xs font-medium hover:bg-accent disabled:opacity-40 transition-colors"
|
||||
className="w-full inline-flex items-center justify-center gap-1 py-2 rounded-btn bg-accent/90 text-white text-xs font-medium hover:bg-accent disabled:opacity-40 transition-colors"
|
||||
>
|
||||
{saving ? <Loader2 className="h-3.5 w-3.5 animate-spin" /> : <Check className="h-3.5 w-3.5" />}
|
||||
保存配置
|
||||
@@ -513,7 +513,7 @@ export function ExtDataPullPanel({ config, onSaved }: {
|
||||
onClick={handleBackfill}
|
||||
disabled={bfRunning || !dateParam.trim() || !bfStart || !bfEnd}
|
||||
title="按本地交易日逐日拉取写入历史分区; 已有分区自动跳过, 可重复执行"
|
||||
className="shrink-0 inline-flex items-center gap-1 px-2.5 py-1.5 rounded-btn bg-accent/90 text-base text-[10px] font-medium hover:bg-accent disabled:opacity-40 transition-colors"
|
||||
className="shrink-0 inline-flex items-center gap-1 px-2.5 py-1.5 rounded-btn bg-accent/90 text-white text-[10px] font-medium hover:bg-accent disabled:opacity-40 transition-colors"
|
||||
>
|
||||
{bfRunning ? <Loader2 className="h-3 w-3 animate-spin" /> : <History className="h-3 w-3" />}
|
||||
回补
|
||||
|
||||
@@ -301,7 +301,7 @@ export function ExtDataStatCard({ config, onDelete, deleting, onEdit }: {
|
||||
<button
|
||||
onClick={() => { onDelete(); setShowDelete(false) }}
|
||||
disabled={deleting}
|
||||
className="px-3 py-1.5 rounded-btn bg-danger/90 text-base text-sm font-medium hover:bg-danger disabled:opacity-50 transition-colors"
|
||||
className="px-3 py-1.5 rounded-btn bg-danger/90 text-white text-sm font-medium hover:bg-danger disabled:opacity-50 transition-colors"
|
||||
>
|
||||
{deleting ? '删除中…' : '确认删除'}
|
||||
</button>
|
||||
|
||||
@@ -137,7 +137,7 @@ export function MarkdownRenderer({ content }: { content: string }) {
|
||||
if (hMatch) {
|
||||
const level = hMatch[1].length
|
||||
const text = hMatch[2]
|
||||
const sizeCls = level === 1 ? 'text-base' : level === 2 ? 'text-sm' : 'text-xs'
|
||||
const sizeCls = level === 1 ? 'text-[16px] leading-6' : level === 2 ? 'text-sm' : 'text-xs'
|
||||
const mtCls = level <= 2 ? 'mt-6' : 'mt-5'
|
||||
blocks.push(
|
||||
<div key={key++} className={`${sizeCls} ${mtCls} mb-3 font-semibold text-foreground flex items-center gap-1.5`}>
|
||||
|
||||
@@ -544,7 +544,7 @@ export function RuleEditor({ rule, preset, simple, onClose, onSaved }: Props) {
|
||||
|
||||
<div className="flex justify-end gap-2">
|
||||
<button onClick={onClose} className="px-4 py-1.5 rounded-btn bg-elevated text-secondary text-xs cursor-pointer">取消</button>
|
||||
<button onClick={() => save.mutate()} disabled={save.isPending} className="inline-flex items-center gap-1.5 px-4 py-1.5 rounded-btn bg-accent text-base text-xs font-medium disabled:opacity-50 cursor-pointer">
|
||||
<button onClick={() => save.mutate()} disabled={save.isPending} className="inline-flex items-center gap-1.5 px-4 py-1.5 rounded-btn bg-accent text-white text-xs font-medium disabled:opacity-50 cursor-pointer">
|
||||
<Save className="h-3.5 w-3.5" />加入监控
|
||||
</button>
|
||||
</div>
|
||||
@@ -1615,7 +1615,7 @@ export function RuleEditor({ rule, preset, simple, onClose, onSaved }: Props) {
|
||||
|
||||
<div className="flex justify-end gap-2">
|
||||
<button onClick={onClose} className="px-4 py-1.5 rounded-btn bg-elevated text-secondary text-xs cursor-pointer">取消</button>
|
||||
<button onClick={() => save.mutate()} disabled={save.isPending} className="inline-flex items-center gap-1.5 px-4 py-1.5 rounded-btn bg-accent text-base text-xs font-medium disabled:opacity-50 cursor-pointer">
|
||||
<button onClick={() => save.mutate()} disabled={save.isPending} className="inline-flex items-center gap-1.5 px-4 py-1.5 rounded-btn bg-accent text-white text-xs font-medium disabled:opacity-50 cursor-pointer">
|
||||
<Save className="h-3.5 w-3.5" />保存
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -50,7 +50,7 @@ export function StrategyStoreDialog({ open, onClose }: Props) {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h3 className="text-base font-semibold text-foreground mb-1.5">
|
||||
<h3 className="text-[16px] leading-6 font-semibold text-foreground mb-1.5">
|
||||
不定时更新更多策略
|
||||
</h3>
|
||||
<p className="text-sm text-muted leading-relaxed max-w-[380px]">
|
||||
|
||||
@@ -254,7 +254,7 @@ export function CustomSignalDialog({ open, signal, defaultKind = 'exit', onClose
|
||||
<button
|
||||
onClick={generateByAI}
|
||||
disabled={aiLoading}
|
||||
className="inline-flex items-center gap-1.5 px-3 py-1.5 rounded-btn bg-amber-500/90 text-base text-xs font-medium disabled:opacity-50 cursor-pointer"
|
||||
className="inline-flex items-center gap-1.5 px-3 py-1.5 rounded-btn bg-amber-500/90 text-white text-xs font-medium disabled:opacity-50 cursor-pointer"
|
||||
>
|
||||
{aiLoading ? <Loader2 className="h-3.5 w-3.5 animate-spin" /> : <Sparkles className="h-3.5 w-3.5" />}
|
||||
{aiLoading ? '生成中…' : '生成条件'}
|
||||
@@ -274,7 +274,7 @@ export function CustomSignalDialog({ open, signal, defaultKind = 'exit', onClose
|
||||
|
||||
<div className="flex justify-end gap-2 border-t border-border/50 px-5 py-4">
|
||||
<button onClick={onClose} className="px-4 py-1.5 rounded-btn bg-elevated text-secondary text-xs">取消</button>
|
||||
<button onClick={() => save.mutate()} disabled={save.isPending} className="inline-flex items-center gap-1.5 px-4 py-1.5 rounded-btn bg-amber-500/90 text-base text-xs font-medium disabled:opacity-50">
|
||||
<button onClick={() => save.mutate()} disabled={save.isPending} className="inline-flex items-center gap-1.5 px-4 py-1.5 rounded-btn bg-amber-500/90 text-white text-xs font-medium disabled:opacity-50">
|
||||
<Save className="h-3.5 w-3.5" />保存
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -189,7 +189,7 @@ function AuctionView({ onOpenStock }: {
|
||||
</p>
|
||||
<Link
|
||||
to="/settings?tab=data-sources"
|
||||
className="mt-5 inline-flex h-9 items-center gap-2 rounded-btn bg-accent px-4 text-xs font-medium text-base transition-colors hover:bg-accent/90"
|
||||
className="mt-5 inline-flex h-9 items-center gap-2 rounded-btn bg-accent px-4 text-xs font-medium text-white transition-colors hover:bg-accent/90"
|
||||
>
|
||||
前往配置数据源
|
||||
<ChevronRight className="h-3.5 w-3.5" />
|
||||
@@ -711,7 +711,7 @@ function DeviationView({ onPreview }: {
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => toggleEnabled(true)}
|
||||
className="mt-5 inline-flex h-9 items-center gap-2 rounded-btn bg-accent px-4 text-xs font-medium text-base"
|
||||
className="mt-5 inline-flex h-9 items-center gap-2 rounded-btn bg-accent px-4 text-xs font-medium text-white"
|
||||
>
|
||||
<Power className="h-4 w-4" />
|
||||
开启监控
|
||||
|
||||
@@ -135,7 +135,7 @@ export function Analysis() {
|
||||
right={
|
||||
<button
|
||||
onClick={() => { resetForm(); setShowCreate(v => !v) }}
|
||||
className="inline-flex items-center gap-1.5 px-3 py-1.5 rounded-btn bg-accent/90 text-base text-xs font-medium hover:bg-accent transition-colors"
|
||||
className="inline-flex items-center gap-1.5 px-3 py-1.5 rounded-btn bg-accent/90 text-white text-xs font-medium hover:bg-accent transition-colors"
|
||||
>
|
||||
<Plus className="h-3.5 w-3.5" />
|
||||
新建菜单
|
||||
@@ -230,7 +230,7 @@ export function Analysis() {
|
||||
|
||||
<div className="flex justify-end gap-2">
|
||||
<button onClick={() => setShowCreate(false)} className="px-4 py-1.5 rounded-btn bg-elevated text-secondary text-xs">取消</button>
|
||||
<button onClick={() => save.mutate()} disabled={save.isPending} className="inline-flex items-center gap-1.5 px-4 py-1.5 rounded-btn bg-accent/90 text-base text-xs font-medium disabled:opacity-50">
|
||||
<button onClick={() => save.mutate()} disabled={save.isPending} className="inline-flex items-center gap-1.5 px-4 py-1.5 rounded-btn bg-accent/90 text-white text-xs font-medium disabled:opacity-50">
|
||||
<Save className="h-3.5 w-3.5" />保存
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -35,7 +35,7 @@ const VARIANTS: Variant[] = [
|
||||
hint: '脉冲星、雷达波纹 — 青绿强调色,字重黑体,中等字距',
|
||||
icon: RadioTower,
|
||||
iconAccent: 'text-[#3DD68C]',
|
||||
nameClass: 'font-sans font-black text-base tracking-[0.10em]',
|
||||
nameClass: 'font-sans font-black text-[16px] leading-6 tracking-[0.10em]',
|
||||
glow: '#3DD68C',
|
||||
},
|
||||
{
|
||||
@@ -45,7 +45,7 @@ const VARIANTS: Variant[] = [
|
||||
hint: 'Vantablack — 纯白单色,字重最重,字距最宽,monochrome 高级感',
|
||||
icon: Square,
|
||||
iconAccent: 'text-[#FAFAFA]',
|
||||
nameClass: 'font-sans font-black text-base tracking-[0.18em]',
|
||||
nameClass: 'font-sans font-black text-[16px] leading-6 tracking-[0.18em]',
|
||||
glow: '#FAFAFA',
|
||||
},
|
||||
{
|
||||
@@ -55,7 +55,7 @@ const VARIANTS: Variant[] = [
|
||||
hint: 'DNA 螺旋 — 紫色强调,等宽字体,赛博朋克经典意象',
|
||||
icon: GitFork,
|
||||
iconAccent: 'text-[#8B5CF6]',
|
||||
nameClass: 'font-mono font-bold text-base tracking-[0.08em]',
|
||||
nameClass: 'font-mono font-bold text-[16px] leading-6 tracking-[0.08em]',
|
||||
glow: '#8B5CF6',
|
||||
},
|
||||
{
|
||||
@@ -65,7 +65,7 @@ const VARIANTS: Variant[] = [
|
||||
hint: '极光 — 青色强调,细字优雅,适中字距,与涨跌语义色不冲突',
|
||||
icon: Sparkles,
|
||||
iconAccent: 'text-[#22D3EE]',
|
||||
nameClass: 'font-sans font-light text-base tracking-[0.12em]',
|
||||
nameClass: 'font-sans font-light text-[16px] leading-6 tracking-[0.12em]',
|
||||
glow: '#22D3EE',
|
||||
},
|
||||
]
|
||||
|
||||
@@ -718,7 +718,7 @@ export function Dashboard() {
|
||||
<div className="flex h-full items-center justify-center bg-base p-6">
|
||||
<div className="rounded-card border border-border bg-surface p-6 text-center">
|
||||
<div className="text-sm text-danger">看板加载失败</div>
|
||||
<button onClick={() => overview.refetch()} className="mt-3 rounded-btn bg-accent px-3 py-1.5 text-xs font-medium text-base">重试</button>
|
||||
<button onClick={() => overview.refetch()} className="mt-3 rounded-btn bg-accent px-3 py-1.5 text-xs font-medium text-white">重试</button>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
@@ -771,7 +771,7 @@ export function Dashboard() {
|
||||
<div className="pointer-events-none absolute left-0 top-0 h-full w-1 bg-gradient-to-b from-accent to-accent/20" aria-hidden />
|
||||
<div className="flex items-center gap-2">
|
||||
<Gauge className="h-4 w-4 text-accent" />
|
||||
<h1 className="text-base font-semibold text-foreground">市场看板</h1>
|
||||
<h1 className="text-[16px] leading-6 font-semibold text-foreground">市场看板</h1>
|
||||
<span
|
||||
className="rounded-full border px-2 py-0.5 text-[10px] font-medium"
|
||||
style={{
|
||||
@@ -1064,7 +1064,7 @@ function WelcomeFetchModal({
|
||||
>
|
||||
<Sparkles className="h-7 w-7 text-accent" />
|
||||
</motion.div>
|
||||
<h3 className="mt-4 text-base font-semibold text-foreground">首次使用,需先获取行情数据</h3>
|
||||
<h3 className="mt-4 text-[16px] leading-6 font-semibold text-foreground">首次使用,需先获取行情数据</h3>
|
||||
<p className="mt-2 text-xs text-secondary leading-relaxed">
|
||||
{isTickflowProvider
|
||||
? '可通过 TickFlow 免费服务器拉取近 1 年全 A 股日K'
|
||||
|
||||
@@ -1149,7 +1149,7 @@ export function Data() {
|
||||
<button
|
||||
onClick={() => syncIndexDaily.mutate()}
|
||||
disabled={!hasDailyBatchCap || !!activeJobId || syncIndexDaily.isPending}
|
||||
className="w-full inline-flex items-center justify-center gap-1.5 px-3 py-1.5 rounded-btn bg-accent/90 text-base text-xs font-medium hover:bg-accent disabled:opacity-40 disabled:pointer-events-none transition-colors duration-150"
|
||||
className="w-full inline-flex items-center justify-center gap-1.5 px-3 py-1.5 rounded-btn bg-accent/90 text-white text-xs font-medium hover:bg-accent disabled:opacity-40 disabled:pointer-events-none transition-colors duration-150"
|
||||
>
|
||||
{syncIndexDaily.isPending ? (
|
||||
<>
|
||||
@@ -1225,7 +1225,7 @@ export function Data() {
|
||||
<button
|
||||
onClick={() => stopSync.mutate()}
|
||||
disabled={stopSync.isPending}
|
||||
className="px-3 py-1.5 rounded-btn bg-danger/90 text-base text-sm font-medium hover:bg-danger disabled:opacity-50 transition-colors"
|
||||
className="px-3 py-1.5 rounded-btn bg-danger/90 text-white text-sm font-medium hover:bg-danger disabled:opacity-50 transition-colors"
|
||||
>
|
||||
{stopSync.isPending ? '停止中…' : '确认停止'}
|
||||
</button>
|
||||
@@ -1289,7 +1289,7 @@ export function Data() {
|
||||
<button
|
||||
onClick={() => clearData.mutate()}
|
||||
disabled={clearData.isPending}
|
||||
className="px-3 py-1.5 rounded-btn bg-danger/90 text-base text-sm font-medium hover:bg-danger disabled:opacity-50 transition-colors"
|
||||
className="px-3 py-1.5 rounded-btn bg-danger/90 text-white text-sm font-medium hover:bg-danger disabled:opacity-50 transition-colors"
|
||||
>
|
||||
{clearData.isPending ? '清除中…' : '清除数据'}
|
||||
</button>
|
||||
|
||||
@@ -96,7 +96,7 @@ function MinuteProbePanel() {
|
||||
<button
|
||||
onClick={runProbe}
|
||||
disabled={loading || !symbol.trim()}
|
||||
className="flex items-center gap-1.5 rounded-btn bg-accent px-4 py-1.5 text-sm font-medium text-base hover:bg-accent/90 disabled:opacity-50 cursor-pointer"
|
||||
className="flex items-center gap-1.5 rounded-btn bg-accent px-4 py-1.5 text-sm font-medium text-white hover:bg-accent/90 disabled:opacity-50 cursor-pointer"
|
||||
>
|
||||
{loading ? <Loader2 className="h-4 w-4 animate-spin" /> : <Search className="h-4 w-4" />}
|
||||
{loading ? '探测中…' : '开始探测'}
|
||||
@@ -263,7 +263,7 @@ function SeedPanel() {
|
||||
<button
|
||||
onClick={() => seedMut.mutate()}
|
||||
disabled={seedMut.isPending}
|
||||
className="flex items-center gap-1.5 rounded-btn bg-accent px-4 py-1.5 text-sm font-medium text-base hover:bg-accent/90 disabled:opacity-50 cursor-pointer"
|
||||
className="flex items-center gap-1.5 rounded-btn bg-accent px-4 py-1.5 text-sm font-medium text-white hover:bg-accent/90 disabled:opacity-50 cursor-pointer"
|
||||
>
|
||||
{seedMut.isPending ? <Loader2 className="h-4 w-4 animate-spin" /> : <FlaskConical className="h-4 w-4" />}
|
||||
生成演示数据
|
||||
@@ -295,7 +295,7 @@ function SeedPanel() {
|
||||
<button
|
||||
onClick={() => ruleSeedMut.mutate()}
|
||||
disabled={ruleSeedMut.isPending}
|
||||
className="flex items-center gap-1.5 rounded-btn bg-accent px-4 py-1.5 text-sm font-medium text-base hover:bg-accent/90 disabled:opacity-50 cursor-pointer"
|
||||
className="flex items-center gap-1.5 rounded-btn bg-accent px-4 py-1.5 text-sm font-medium text-white hover:bg-accent/90 disabled:opacity-50 cursor-pointer"
|
||||
>
|
||||
{ruleSeedMut.isPending ? <Loader2 className="h-4 w-4 animate-spin" /> : <FlaskConical className="h-4 w-4" />}
|
||||
生成演示规则
|
||||
@@ -359,7 +359,7 @@ function LadderTestPanel() {
|
||||
<button
|
||||
onClick={() => testMut.mutate()}
|
||||
disabled={testMut.isPending}
|
||||
className="flex items-center gap-1.5 rounded-btn bg-accent px-4 py-1.5 text-sm font-medium text-base hover:bg-accent/90 disabled:opacity-50 cursor-pointer"
|
||||
className="flex items-center gap-1.5 rounded-btn bg-accent px-4 py-1.5 text-sm font-medium text-white hover:bg-accent/90 disabled:opacity-50 cursor-pointer"
|
||||
>
|
||||
{testMut.isPending ? <Loader2 className="h-4 w-4 animate-spin" /> : <Bell className="h-4 w-4" />}
|
||||
模拟触发
|
||||
|
||||
@@ -74,13 +74,13 @@ export function Financials() {
|
||||
<div className="mx-auto flex h-12 w-12 items-center justify-center rounded-full bg-warning/10">
|
||||
<Lock className="h-6 w-6 text-warning" />
|
||||
</div>
|
||||
<h3 className="mt-4 text-base font-semibold text-foreground">财务数据不可用</h3>
|
||||
<h3 className="mt-4 text-[16px] leading-6 font-semibold text-foreground">财务数据不可用</h3>
|
||||
<p className="mt-2 text-xs leading-relaxed text-secondary">
|
||||
当前数据源未提供财务数据。配置提供财务数据的数据源后,此页自动显示财务数据面板。
|
||||
</p>
|
||||
<Link
|
||||
to="/settings?tab=data-sources"
|
||||
className="mt-4 inline-flex items-center gap-1.5 rounded-btn bg-accent/90 px-3.5 py-1.5 text-xs font-medium text-base hover:bg-accent transition-colors"
|
||||
className="mt-4 inline-flex items-center gap-1.5 rounded-btn bg-accent/90 px-3.5 py-1.5 text-xs font-medium text-white hover:bg-accent transition-colors"
|
||||
>
|
||||
前往数据源配置
|
||||
</Link>
|
||||
|
||||
@@ -184,7 +184,7 @@ export function Indices() {
|
||||
<button
|
||||
onClick={() => syncDaily.mutate()}
|
||||
disabled={syncDaily.isPending}
|
||||
className="inline-flex items-center gap-1.5 rounded-btn bg-accent px-3 py-1.5 text-xs font-medium text-base hover:bg-accent/90 disabled:opacity-50"
|
||||
className="inline-flex items-center gap-1.5 rounded-btn bg-accent px-3 py-1.5 text-xs font-medium text-white hover:bg-accent/90 disabled:opacity-50"
|
||||
>
|
||||
{syncDaily.isPending ? <Loader2 className="h-3.5 w-3.5 animate-spin" /> : <RefreshCw className="h-3.5 w-3.5" />}
|
||||
同步指数日K
|
||||
|
||||
@@ -1091,7 +1091,7 @@ function ConfirmDialog({ open, title, message, confirmText, danger, pending, onC
|
||||
disabled={pending}
|
||||
className={cn(
|
||||
'px-3 py-1.5 rounded-btn text-xs font-medium disabled:opacity-50 cursor-pointer',
|
||||
danger ? 'bg-danger text-base' : 'bg-accent text-base',
|
||||
danger ? 'bg-danger text-white' : 'bg-accent text-white',
|
||||
)}
|
||||
>
|
||||
{confirmText ?? '确定'}
|
||||
@@ -1163,7 +1163,7 @@ function MonitorExtConfigDialog({ open, fields, onClose }: {
|
||||
</div>
|
||||
<div className="mt-5 flex justify-end gap-2">
|
||||
<button onClick={onClose} className="px-3 py-1.5 rounded-btn text-xs text-secondary hover:text-foreground transition-colors cursor-pointer">取消</button>
|
||||
<button onClick={handleSave} className="px-3 py-1.5 rounded-btn text-xs font-medium bg-accent text-base cursor-pointer">保存</button>
|
||||
<button onClick={handleSave} className="px-3 py-1.5 rounded-btn text-xs font-medium bg-accent text-white cursor-pointer">保存</button>
|
||||
</div>
|
||||
</motion.div>
|
||||
</motion.div>
|
||||
|
||||
@@ -661,7 +661,7 @@ export function Regime() {
|
||||
<div className="absolute left-0 top-0 h-full w-1 bg-gradient-to-b from-accent to-accent/20" />
|
||||
<div className="flex items-center gap-3">
|
||||
<Activity className="h-5 w-5 text-accent" />
|
||||
<h1 className="text-base font-semibold text-foreground">市场环境</h1>
|
||||
<h1 className="text-[16px] leading-6 font-semibold text-foreground">市场环境</h1>
|
||||
<span className="text-xs text-muted">
|
||||
{view === 'phase' ? '涨停情绪 · 市场阶段 · 主线脉络' : '每日环境状态 · 赚钱效应 · 趋势分析'}
|
||||
</span>
|
||||
|
||||
@@ -756,7 +756,7 @@ function ReportPanel({
|
||||
<Sparkles className="absolute -right-1 -top-1 h-5 w-5 text-accent" />
|
||||
</div>
|
||||
<div className="text-center">
|
||||
<div className="text-base font-semibold text-foreground">AI 大盘复盘</div>
|
||||
<div className="text-[16px] leading-6 font-semibold text-foreground">AI 大盘复盘</div>
|
||||
<p className="mx-auto mt-2 max-w-sm text-xs leading-relaxed text-secondary">
|
||||
一键生成今日盘后复盘报告 —— 从一句话定调到明日交易计划,
|
||||
结构化输出可直接指导次日仓位与节奏。
|
||||
@@ -774,7 +774,7 @@ function ReportPanel({
|
||||
{ icon: '⚠️', label: '风险提示' },
|
||||
].map((s) => (
|
||||
<div key={s.label} className="flex flex-col items-center gap-1 rounded-btn bg-elevated/40 px-2 py-2">
|
||||
<span className="text-base">{s.icon}</span>
|
||||
<span className="text-[16px] leading-6">{s.icon}</span>
|
||||
<span className="text-[10px] text-secondary">{s.label}</span>
|
||||
</div>
|
||||
))}
|
||||
|
||||
@@ -990,7 +990,7 @@ export function Screener() {
|
||||
<Filter className="h-3 w-3" />
|
||||
筛选
|
||||
{filterActive(filter) && (
|
||||
<span className="bg-accent text-base rounded-full min-w-4 h-4 px-1 flex items-center justify-center text-[10px] font-bold leading-none">
|
||||
<span className="bg-accent text-white rounded-full min-w-4 h-4 px-1 flex items-center justify-center text-[10px] font-bold leading-none">
|
||||
{countActiveFilters(filter)}
|
||||
</span>
|
||||
)}
|
||||
|
||||
@@ -228,7 +228,7 @@ function StockAnalysisBoard({ symbol }: { symbol: string }) {
|
||||
<span className="text-[10px] text-muted">{rows.length} 个交易日</span>
|
||||
<span className="text-[10px] text-muted/60">·</span>
|
||||
<span className="text-[10px] text-muted">当前价</span>
|
||||
<span className={`text-base font-mono font-bold ${isUp ? 'text-bull' : 'text-bear'}`}>
|
||||
<span className={`text-[16px] leading-6 font-mono font-bold ${isUp ? 'text-bull' : 'text-bear'}`}>
|
||||
{curClose?.toFixed(2) ?? '—'}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@@ -185,7 +185,7 @@ export function AddFactorSignalDialog({
|
||||
type="button"
|
||||
onClick={() => save.mutate()}
|
||||
disabled={save.isPending || !selected || !thresholdValid || !name.trim()}
|
||||
className="inline-flex items-center gap-1.5 rounded-btn bg-amber-500/90 px-3 py-1.5 text-xs font-medium text-base transition-colors hover:bg-amber-500 disabled:cursor-not-allowed disabled:opacity-50"
|
||||
className="inline-flex items-center gap-1.5 rounded-btn bg-amber-500/90 px-3 py-1.5 text-xs font-medium text-white transition-colors hover:bg-amber-500 disabled:cursor-not-allowed disabled:opacity-50"
|
||||
>
|
||||
<Zap className="h-3.5 w-3.5" />
|
||||
{save.isPending ? '保存中…' : '保存信号'}
|
||||
|
||||
@@ -686,7 +686,7 @@ function Stat({ label, value, color }: { label: ReactNode; value: string; color?
|
||||
<div className="min-w-0 rounded-btn border border-border/70 bg-elevated/70 px-3 py-2">
|
||||
<div className="text-[11px] text-secondary">{label}</div>
|
||||
<div
|
||||
className={`mt-1 break-words font-mono font-semibold leading-tight tracking-tight num ${compact ? 'text-xs xl:text-sm' : 'text-sm xl:text-base'}`}
|
||||
className={`mt-1 break-words font-mono font-semibold leading-tight tracking-tight num ${compact ? 'text-xs xl:text-sm' : 'text-sm xl:text-[16px] xl:leading-6'}`}
|
||||
style={{ color: color ?? 'inherit' }}
|
||||
title={value}
|
||||
>
|
||||
|
||||
@@ -1015,7 +1015,7 @@ function PluginDetail({ plugin, isActive, matrixCaps, servingSet }: {
|
||||
</div>
|
||||
<div className="flex-1 min-w-0">
|
||||
<div className="flex items-center gap-2 mb-1 flex-wrap">
|
||||
<h3 className="text-base font-semibold text-foreground">{plugin.display_name}</h3>
|
||||
<h3 className="text-[16px] leading-6 font-semibold text-foreground">{plugin.display_name}</h3>
|
||||
<span className="text-[10px] text-muted/50 uppercase tracking-wider">插件 · {plugin.runtime}</span>
|
||||
<span className="rounded bg-warning/15 px-1 py-0.5 text-[9px] font-medium leading-none text-warning">第三方</span>
|
||||
{isActive && (
|
||||
@@ -1164,7 +1164,7 @@ function TickFlowDetail({ active, matrix }: { active: boolean; matrix?: Capabili
|
||||
</div>
|
||||
<div className="flex-1 min-w-0">
|
||||
<div className="flex items-center gap-2 flex-wrap">
|
||||
<h2 className="text-base font-semibold text-foreground">TickFlow</h2>
|
||||
<h2 className="text-[16px] leading-6 font-semibold text-foreground">TickFlow</h2>
|
||||
<span className="rounded bg-warning/15 px-1.5 py-0.5 text-[10px] font-medium text-warning">第三方</span>
|
||||
<AllTiersBadge />
|
||||
{active && (
|
||||
|
||||
@@ -141,7 +141,7 @@ export function SettingsExtPagesPanel() {
|
||||
</div>
|
||||
<button
|
||||
onClick={() => { resetForm(); setShowForm(true) }}
|
||||
className="inline-flex items-center justify-center gap-1.5 rounded-btn bg-accent/90 px-3 py-1.5 text-xs font-medium text-base hover:bg-accent transition-colors"
|
||||
className="inline-flex items-center justify-center gap-1.5 rounded-btn bg-accent/90 px-3 py-1.5 text-xs font-medium text-white hover:bg-accent transition-colors"
|
||||
>
|
||||
<Plus className="h-3.5 w-3.5" />
|
||||
新建页面
|
||||
@@ -241,7 +241,7 @@ export function SettingsExtPagesPanel() {
|
||||
|
||||
<div className="flex justify-end gap-2">
|
||||
<button onClick={() => { setShowForm(false); setError('') }} className="px-4 py-1.5 rounded-btn bg-elevated text-secondary text-xs">取消</button>
|
||||
<button onClick={() => save.mutate()} disabled={save.isPending} className="inline-flex items-center gap-1.5 px-4 py-1.5 rounded-btn bg-accent/90 text-base text-xs font-medium disabled:opacity-50">
|
||||
<button onClick={() => save.mutate()} disabled={save.isPending} className="inline-flex items-center gap-1.5 px-4 py-1.5 rounded-btn bg-accent/90 text-white text-xs font-medium disabled:opacity-50">
|
||||
<Save className="h-3.5 w-3.5" />保存
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -625,7 +625,7 @@ export function SettingsMonitoringPanel({ highlight }: { highlight?: string } =
|
||||
<button
|
||||
onClick={submitFeishu}
|
||||
disabled={saveFeishuWebhook.isPending || (feishuDraft.trim() === feishuWebhookUrl && feishuSecretDraft.trim() === feishuWebhookSecret)}
|
||||
className="px-3 py-1.5 rounded-btn bg-accent text-base text-xs font-medium disabled:opacity-50 cursor-pointer hover:bg-accent/90 transition-colors"
|
||||
className="px-3 py-1.5 rounded-btn bg-accent text-white text-xs font-medium disabled:opacity-50 cursor-pointer hover:bg-accent/90 transition-colors"
|
||||
>
|
||||
{saveFeishuWebhook.isPending ? '保存中…' : '保存'}
|
||||
</button>
|
||||
@@ -701,7 +701,7 @@ export function SettingsMonitoringPanel({ highlight }: { highlight?: string } =
|
||||
<button
|
||||
onClick={submitWecom}
|
||||
disabled={saveWecomWebhook.isPending || wecomDraft.trim() === wecomWebhookUrl}
|
||||
className="px-3 py-1.5 rounded-btn bg-accent text-base text-xs font-medium disabled:opacity-50 cursor-pointer hover:bg-accent/90 transition-colors"
|
||||
className="px-3 py-1.5 rounded-btn bg-accent text-white text-xs font-medium disabled:opacity-50 cursor-pointer hover:bg-accent/90 transition-colors"
|
||||
>
|
||||
{saveWecomWebhook.isPending ? '保存中…' : '保存'}
|
||||
</button>
|
||||
@@ -783,7 +783,7 @@ export function SettingsMonitoringPanel({ highlight }: { highlight?: string } =
|
||||
<button
|
||||
onClick={submitCustom}
|
||||
disabled={saveCustomWebhook.isPending || (customDraft.trim() === customWebhookUrl && !customSecretDraft)}
|
||||
className="px-3 py-1.5 rounded-btn bg-accent text-base text-xs font-medium disabled:opacity-50 cursor-pointer hover:bg-accent/90 transition-colors"
|
||||
className="px-3 py-1.5 rounded-btn bg-accent text-white text-xs font-medium disabled:opacity-50 cursor-pointer hover:bg-accent/90 transition-colors"
|
||||
>
|
||||
{saveCustomWebhook.isPending ? '保存中…' : '保存'}
|
||||
</button>
|
||||
@@ -866,7 +866,7 @@ export function SettingsMonitoringPanel({ highlight }: { highlight?: string } =
|
||||
</div>
|
||||
{emailError && <div className="mt-2 text-[11px] text-danger">{emailError}</div>}
|
||||
<div className="mt-2 flex items-center gap-2">
|
||||
<button onClick={submitEmail} disabled={saveEmailSmtp.isPending} className="px-3 py-1.5 rounded-btn bg-accent text-base text-xs font-medium disabled:opacity-50 cursor-pointer hover:bg-accent/90 transition-colors">
|
||||
<button onClick={submitEmail} disabled={saveEmailSmtp.isPending} className="px-3 py-1.5 rounded-btn bg-accent text-white text-xs font-medium disabled:opacity-50 cursor-pointer hover:bg-accent/90 transition-colors">
|
||||
{saveEmailSmtp.isPending ? '保存中…' : '保存'}
|
||||
</button>
|
||||
<TestSendButton test={testEmail} configured={emailConfigured} />
|
||||
@@ -938,7 +938,7 @@ export function SettingsMonitoringPanel({ highlight }: { highlight?: string } =
|
||||
<button
|
||||
onClick={submitBot}
|
||||
disabled={saveWecomBot.isPending || (botIdDraft.trim() === wecomBotId && botSecretDraft.trim() === wecomBotSecret)}
|
||||
className="px-3 py-1.5 rounded-btn bg-accent text-base text-xs font-medium disabled:opacity-50 cursor-pointer hover:bg-accent/90 transition-colors"
|
||||
className="px-3 py-1.5 rounded-btn bg-accent text-white text-xs font-medium disabled:opacity-50 cursor-pointer hover:bg-accent/90 transition-colors"
|
||||
>
|
||||
{saveWecomBot.isPending ? '保存中…' : '保存并连接'}
|
||||
</button>
|
||||
|
||||
@@ -10,6 +10,8 @@ export default {
|
||||
extend: {
|
||||
colors: {
|
||||
// §6.0.1 色板 — CSS variables 见 src/index.css
|
||||
// 注意: base 与字号 token 撞名, text-base 会生成 color 规则 (文字变背景色)。
|
||||
// 字号 16px 一律写 text-[16px] leading-6, 禁用 text-base。
|
||||
base: 'hsl(var(--base) / <alpha-value>)',
|
||||
surface: 'hsl(var(--surface) / <alpha-value>)',
|
||||
elevated: 'hsl(var(--elevated) / <alpha-value>)',
|
||||
|
||||
Reference in New Issue
Block a user