Skip to content

Commit b1ca7df

Browse files
whhjdiBowl42whhjdi
authored
Feat/theme: update some styles (#7)
* feat(dialog): 添加对话框组件及相关功能 style(console): 优化日志显示样式 style(requests): 调整请求标签样式 style(index): 更新全局样式以支持新间距变量 * feat(requests): add detailed request view with sidebar, header, and diff functionality - Implemented RequestDetailView component to display request details, including request, response, and metadata tabs. - Created RequestHeader component for displaying request summary and stats. - Added RequestSidebar for navigating between main request and upstream attempts. - Introduced CopyButton and DiffButton components for copying content and viewing differences between client and upstream responses. - Developed DiffModal for displaying the differences in a user-friendly format. - Added EmptyState component for handling empty data scenarios. - Organized components into a dedicated directory for better structure and maintainability. * refactor: improve styling and structure in Requests, Retry Configs, and Sessions pages - Updated class names for consistent styling in Requests and Retry Configs pages. - Replaced `flex-shrink-0` with `shrink-0` for better readability. - Simplified icon class names in RequestStatusBadge for clarity. - Enhanced readability by formatting JSX elements in Retry Configs and Sessions pages. - Improved loading and empty state messages for better user experience. - Refactored event handling and state management in SessionDetailModal for clarity. * fix(layout): 添加 h-full 类以确保主容器高度填充 * fix: 使用构建标签分离 Wails 依赖,修复 Docker 构建问题 - 将 wails_broadcaster.go 拆分为两个文件: - wails_broadcaster_desktop.go (//go:build desktop) - 包含 Wails runtime - wails_broadcaster_http.go (//go:build !desktop) - 纯转发,无 Wails 依赖 - 更新 wails.json 添加 "tags": "desktop" 确保桌面构建使用正确标签 - 优化前端 Transport 检测:HTTP 模式直接创建 HttpTransport,跳过 Wails 等待 * refactor: 更新组件样式,替换原生按钮和输入框为自定义组件,优化布局和样式 * refactor: 更新组件样式,优化布局,替换原生按钮为自定义组件 --------- Co-authored-by: Bowl42 <tribowl42@gmail.com> Co-authored-by: whhjdi <wanghandi95@gamil.com>
1 parent 626b87b commit b1ca7df

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+3760
-3072
lines changed

web/package-lock.json

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

web/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
"postcss": "^8.5.6",
3030
"react": "^19.2.0",
3131
"react-dom": "^19.2.0",
32+
"react-resizable-panels": "^2.1.7",
3233
"react-router-dom": "^7.11.0",
3334
"recharts": "^3.6.0",
3435
"shadcn": "^3.6.3",
Lines changed: 116 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { useEffect, useCallback, useState } from 'react';
2-
import { createPortal } from 'react-dom';
1+
import { useEffect, useCallback, useState } from 'react'
2+
import { createPortal } from 'react-dom'
33
import {
44
Snowflake,
55
Clock,
@@ -12,23 +12,32 @@ import {
1212
X,
1313
Thermometer,
1414
Calendar,
15-
Activity
16-
} from 'lucide-react';
17-
import type { Cooldown, CooldownReason } from '@/lib/transport/types';
18-
import { useCooldowns } from '@/hooks/use-cooldowns';
15+
Activity,
16+
} from 'lucide-react'
17+
import type { Cooldown, CooldownReason } from '@/lib/transport/types'
18+
import { useCooldowns } from '@/hooks/use-cooldowns'
1919

2020
interface CooldownDetailsDialogProps {
21-
cooldown: Cooldown | null;
22-
open: boolean;
23-
onOpenChange: (open: boolean) => void;
24-
onClear: () => void;
25-
isClearing: boolean;
26-
onDisable: () => void;
27-
isDisabling: boolean;
21+
cooldown: Cooldown | null
22+
open: boolean
23+
onOpenChange: (open: boolean) => void
24+
onClear: () => void
25+
isClearing: boolean
26+
onDisable: () => void
27+
isDisabling: boolean
2828
}
2929

3030
// Reason 中文说明和图标
31-
const REASON_INFO: Record<CooldownReason, { label: string; description: string; icon: typeof Server; color: string; bgColor: string }> = {
31+
const REASON_INFO: Record<
32+
CooldownReason,
33+
{
34+
label: string
35+
description: string
36+
icon: typeof Server
37+
color: string
38+
bgColor: string
39+
}
40+
> = {
3241
server_error: {
3342
label: '服务器错误',
3443
description: '上游服务器返回 5xx 错误,系统自动进入冷却保护',
@@ -71,7 +80,7 @@ const REASON_INFO: Record<CooldownReason, { label: string; description: string;
7180
color: 'text-text-muted',
7281
bgColor: 'bg-surface-secondary border-border',
7382
},
74-
};
83+
}
7584

7685
export function CooldownDetailsDialog({
7786
cooldown,
@@ -83,66 +92,69 @@ export function CooldownDetailsDialog({
8392
isDisabling,
8493
}: CooldownDetailsDialogProps) {
8594
// 获取 formatRemaining 函数用于实时倒计时
86-
const { formatRemaining } = useCooldowns();
95+
const { formatRemaining } = useCooldowns()
8796

8897
// 实时倒计时状态
89-
const [liveCountdown, setLiveCountdown] = useState<string>('');
98+
const [liveCountdown, setLiveCountdown] = useState<string>('')
9099

91100
// Handle ESC key
92-
const handleKeyDown = useCallback((e: KeyboardEvent) => {
93-
if (e.key === 'Escape') {
94-
onOpenChange(false);
95-
}
96-
}, [onOpenChange]);
101+
const handleKeyDown = useCallback(
102+
(e: KeyboardEvent) => {
103+
if (e.key === 'Escape') {
104+
onOpenChange(false)
105+
}
106+
},
107+
[onOpenChange]
108+
)
97109

98110
useEffect(() => {
99111
if (open) {
100-
document.addEventListener('keydown', handleKeyDown);
101-
document.body.style.overflow = 'hidden';
112+
document.addEventListener('keydown', handleKeyDown)
113+
document.body.style.overflow = 'hidden'
102114
return () => {
103-
document.removeEventListener('keydown', handleKeyDown);
104-
document.body.style.overflow = '';
105-
};
115+
document.removeEventListener('keydown', handleKeyDown)
116+
document.body.style.overflow = ''
117+
}
106118
}
107-
}, [open, handleKeyDown]);
119+
}, [open, handleKeyDown])
108120

109121
// 每秒更新倒计时
110122
useEffect(() => {
111123
if (!cooldown) {
112-
setLiveCountdown('');
113-
return;
124+
setLiveCountdown('')
125+
return
114126
}
115127

116128
// 立即更新一次
117-
setLiveCountdown(formatRemaining(cooldown));
129+
setLiveCountdown(formatRemaining(cooldown))
118130

119131
// 每秒更新
120132
const interval = setInterval(() => {
121-
setLiveCountdown(formatRemaining(cooldown));
122-
}, 1000);
133+
setLiveCountdown(formatRemaining(cooldown))
134+
}, 1000)
123135

124-
return () => clearInterval(interval);
125-
}, [cooldown, formatRemaining]);
136+
return () => clearInterval(interval)
137+
}, [cooldown, formatRemaining])
126138

127-
if (!open || !cooldown) return null;
139+
if (!open || !cooldown) return null
128140

129-
const reasonInfo = REASON_INFO[cooldown.reason] || REASON_INFO.unknown;
130-
const Icon = reasonInfo.icon;
141+
const reasonInfo = REASON_INFO[cooldown.reason] || REASON_INFO.unknown
142+
const Icon = reasonInfo.icon
131143

132144
const formatUntilTime = (until: string) => {
133-
const date = new Date(until);
145+
const date = new Date(until)
134146
return date.toLocaleString('zh-CN', {
135147
month: '2-digit',
136148
day: '2-digit',
137149
hour: '2-digit',
138150
minute: '2-digit',
139151
second: '2-digit',
140152
hour12: false,
141-
});
142-
};
153+
})
154+
}
143155

144-
const untilDateStr = formatUntilTime(cooldown.untilTime);
145-
const [datePart, timePart] = untilDateStr.split(' ');
156+
const untilDateStr = formatUntilTime(cooldown.untilTime)
157+
const [datePart, timePart] = untilDateStr.split(' ')
146158

147159
return createPortal(
148160
<>
@@ -163,7 +175,7 @@ export function CooldownDetailsDialog({
163175
padding: 0,
164176
background: 'var(--color-surface-primary)',
165177
}}
166-
onClick={(e) => e.stopPropagation()}
178+
onClick={e => e.stopPropagation()}
167179
>
168180
{/* Header with Gradient */}
169181
<div className="relative bg-gradient-to-b from-cyan-900/20 to-transparent p-6 pb-4">
@@ -176,10 +188,15 @@ export function CooldownDetailsDialog({
176188

177189
<div className="flex flex-col items-center text-center space-y-3">
178190
<div className="p-3 rounded-2xl bg-cyan-500/10 border border-cyan-400/20 shadow-[0_0_15px_-3px_rgba(6,182,212,0.2)]">
179-
<Snowflake size={28} className="text-cyan-400 animate-spin-slow" />
191+
<Snowflake
192+
size={28}
193+
className="text-cyan-400 animate-spin-slow"
194+
/>
180195
</div>
181196
<div>
182-
<h2 className="text-xl font-bold text-text-primary">冷却保护中</h2>
197+
<h2 className="text-xl font-bold text-text-primary">
198+
冷却保护中
199+
</h2>
183200
<p className="text-xs text-cyan-500/80 font-medium uppercase tracking-wider mt-1">
184201
Frozen Protocol Active
185202
</p>
@@ -189,28 +206,29 @@ export function CooldownDetailsDialog({
189206

190207
{/* Body Content */}
191208
<div className="px-6 pb-6 space-y-5">
192-
193209
{/* Provider Card */}
194210
<div className="flex items-center gap-4 p-3 rounded-xl bg-surface-secondary border border-border">
195211
<div className="flex-1 min-w-0">
196-
<div className="flex items-center gap-2 mb-1">
197-
<span className="text-[10px] font-bold text-text-muted uppercase tracking-wider">Target Provider</span>
198-
{cooldown.clientType && (
199-
<span className="px-1.5 py-0.5 rounded text-[10px] font-mono bg-surface-hover text-text-secondary">
200-
{cooldown.clientType}
201-
</span>
202-
)}
203-
</div>
204-
<div className="font-semibold text-text-primary truncate">
205-
Provider #{cooldown.providerID}
206-
</div>
212+
<div className="flex items-center gap-2 mb-1">
213+
<span className="text-[10px] font-bold text-text-muted uppercase tracking-wider">
214+
Target Provider
215+
</span>
216+
{cooldown.clientType && (
217+
<span className="px-1.5 py-0.5 rounded text-[10px] font-mono bg-surface-hover text-text-secondary">
218+
{cooldown.clientType}
219+
</span>
220+
)}
221+
</div>
222+
<div className="font-semibold text-text-primary truncate">
223+
Provider #{cooldown.providerID}
224+
</div>
207225
</div>
208226
</div>
209227

210228
{/* Reason Section */}
211229
<div className={`rounded-xl border p-4 ${reasonInfo.bgColor}`}>
212230
<div className="flex gap-4">
213-
<div className={`mt-0.5 flex-shrink-0 ${reasonInfo.color}`}>
231+
<div className={`mt-0.5 shrink-0 ${reasonInfo.color}`}>
214232
<Icon size={20} />
215233
</div>
216234
<div>
@@ -226,35 +244,37 @@ export function CooldownDetailsDialog({
226244

227245
{/* Timer Section */}
228246
<div className="grid grid-cols-2 gap-3">
229-
{/* Countdown */}
247+
{/* Countdown */}
230248
<div className="col-span-2 relative overflow-hidden rounded-xl bg-gradient-to-br from-cyan-950/30 to-transparent border border-cyan-500/20 p-5 flex flex-col items-center justify-center group">
231-
<div className="absolute inset-0 bg-cyan-400/5 opacity-50 group-hover:opacity-100 transition-opacity" />
232-
<div className="relative flex items-center gap-1.5 text-cyan-500 mb-1">
233-
<Thermometer size={14} />
234-
<span className="text-[10px] font-bold uppercase tracking-widest">Remaining</span>
235-
</div>
236-
<div className="relative font-mono text-4xl font-bold text-cyan-400 tracking-widest tabular-nums drop-shadow-[0_0_8px_rgba(34,211,238,0.3)]">
237-
{liveCountdown}
238-
</div>
249+
<div className="absolute inset-0 bg-cyan-400/5 opacity-50 group-hover:opacity-100 transition-opacity" />
250+
<div className="relative flex items-center gap-1.5 text-cyan-500 mb-1">
251+
<Thermometer size={14} />
252+
<span className="text-[10px] font-bold uppercase tracking-widest">
253+
Remaining
254+
</span>
255+
</div>
256+
<div className="relative font-mono text-4xl font-bold text-cyan-400 tracking-widest tabular-nums drop-shadow-[0_0_8px_rgba(34,211,238,0.3)]">
257+
{liveCountdown}
258+
</div>
239259
</div>
240260

241261
{/* Time Details */}
242262
<div className="p-3 rounded-xl bg-surface-secondary border border-border flex flex-col items-center justify-center gap-1">
243-
<span className="text-[10px] text-text-muted uppercase tracking-wider font-bold flex items-center gap-1.5">
244-
<Clock size={10} /> Resume
245-
</span>
246-
<div className="font-mono text-sm font-semibold text-text-primary">
247-
{timePart}
248-
</div>
263+
<span className="text-[10px] text-text-muted uppercase tracking-wider font-bold flex items-center gap-1.5">
264+
<Clock size={10} /> Resume
265+
</span>
266+
<div className="font-mono text-sm font-semibold text-text-primary">
267+
{timePart}
268+
</div>
249269
</div>
250270

251271
<div className="p-3 rounded-xl bg-surface-secondary border border-border flex flex-col items-center justify-center gap-1">
252-
<span className="text-[10px] text-text-muted uppercase tracking-wider font-bold flex items-center gap-1.5">
253-
<Calendar size={10} /> Date
254-
</span>
255-
<div className="font-mono text-sm font-semibold text-text-primary">
256-
{datePart}
257-
</div>
272+
<span className="text-[10px] text-text-muted uppercase tracking-wider font-bold flex items-center gap-1.5">
273+
<Calendar size={10} /> Date
274+
</span>
275+
<div className="font-mono text-sm font-semibold text-text-primary">
276+
{datePart}
277+
</div>
258278
</div>
259279
</div>
260280

@@ -268,14 +288,21 @@ export function CooldownDetailsDialog({
268288
<span className="absolute inset-0 bg-gradient-to-r from-cyan-500 to-blue-600 rounded-xl" />
269289
<div className="relative flex items-center justify-center gap-2 rounded-[11px] bg-surface-primary group-hover:bg-transparent px-4 py-3 transition-colors">
270290
{isClearing ? (
271-
<>
272-
<div className="h-4 w-4 animate-spin rounded-full border-2 border-white/30 border-t-white" />
273-
<span className="text-sm font-bold text-white">Thawing...</span>
274-
</>
291+
<>
292+
<div className="h-4 w-4 animate-spin rounded-full border-2 border-white/30 border-t-white" />
293+
<span className="text-sm font-bold text-white">
294+
Thawing...
295+
</span>
296+
</>
275297
) : (
276298
<>
277-
<Zap size={16} className="text-cyan-400 group-hover:text-white transition-colors" />
278-
<span className="text-sm font-bold text-cyan-400 group-hover:text-white transition-colors">立即解冻 (Force Thaw)</span>
299+
<Zap
300+
size={16}
301+
className="text-cyan-400 group-hover:text-white transition-colors"
302+
/>
303+
<span className="text-sm font-bold text-cyan-400 group-hover:text-white transition-colors">
304+
立即解冻 (Force Thaw)
305+
</span>
279306
</>
280307
)}
281308
</div>
@@ -287,13 +314,13 @@ export function CooldownDetailsDialog({
287314
className="w-full flex items-center justify-center gap-2 rounded-xl border border-border bg-surface-secondary hover:bg-surface-hover px-4 py-3 text-sm font-medium text-text-secondary transition-colors disabled:opacity-50"
288315
>
289316
{isDisabling ? (
290-
<div className="h-3 w-3 animate-spin rounded-full border-2 border-current/30 border-t-current" />
317+
<div className="h-3 w-3 animate-spin rounded-full border-2 border-current/30 border-t-current" />
291318
) : (
292319
<Ban size={16} />
293320
)}
294321
{isDisabling ? 'Disabling...' : '禁用此路由 (Disable Route)'}
295322
</button>
296-
323+
297324
<div className="flex items-start gap-2 rounded-lg bg-surface-secondary/50 p-2.5 text-[11px] text-text-muted">
298325
<Activity size={12} className="mt-0.5 shrink-0" />
299326
<p>强制解冻可能导致请求因根本原因未解决而再次失败。</p>
@@ -303,5 +330,5 @@ export function CooldownDetailsDialog({
303330
</div>
304331
</>,
305332
document.body
306-
);
333+
)
307334
}

0 commit comments

Comments
 (0)