Skip to content

Commit d11a6d1

Browse files
committed
feat: Improve layout
1 parent a2b1648 commit d11a6d1

3 files changed

Lines changed: 104 additions & 57 deletions

File tree

src/LogPort.UI/src/App.tsx

Lines changed: 19 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,7 @@ function App() {
5252
const handleScroll = () => {
5353
if (loadingRef.current || !hasMore) return
5454
const nearBottom = window.innerHeight + window.scrollY >= document.body.offsetHeight - 300
55-
if (nearBottom) {
56-
console.log('Reached bottom, fetching next page...')
57-
fetchLogsPage()
58-
}
55+
if (nearBottom) fetchLogsPage()
5956
}
6057
window.addEventListener('scroll', handleScroll)
6158
return () => window.removeEventListener('scroll', handleScroll)
@@ -74,12 +71,10 @@ function App() {
7471

7572
const newLogs = await getLogs(params)
7673
if (!newLogs || newLogs.length === 0) {
77-
console.log('No more logs available')
7874
setHasMore(false)
7975
return
8076
}
8177

82-
console.log(`Fetched ${newLogs.length} logs (page ${pageRef.current})`)
8378
setLogs(prev => [...prev, ...newLogs])
8479
setPage(prev => prev + 1)
8580

@@ -156,7 +151,6 @@ function App() {
156151
try {
157152
const rawLogs: any[] = JSON.parse(event.data)
158153
const newLogs: LogEntry[] = rawLogs.map(normalizeLog).reverse()
159-
console.log(`Received ${newLogs.length} live logs via WebSocket`)
160154
setLogs(prev => [...newLogs, ...prev])
161155
} catch (err) {
162156
console.error('Failed to parse log', err)
@@ -167,11 +161,8 @@ function App() {
167161
}
168162

169163
return (
170-
<div>
171-
<div
172-
className="filter-bar"
173-
style={{ display: 'flex', gap: '8px', marginBottom: '12px', flexWrap: 'wrap' }}
174-
>
164+
<div className="logs-page">
165+
<div className="filter-bar">
175166
<input
176167
type="text"
177168
placeholder="Search logs..."
@@ -224,24 +215,29 @@ function App() {
224215
</button>
225216
</div>
226217

227-
<div style={{ display: 'flex', alignItems: 'center', marginBottom: '8px' }}>
228-
<button onClick={fetchLatestLogs} disabled={loading} style={{ marginRight: '12px' }}>
229-
{loading ? 'Loading...' : 'Fetch New Logs'}
218+
<div className="controls-bar">
219+
<button className="btn btn-primary" onClick={fetchLatestLogs} disabled={loading}>
220+
{loading ? 'Refreshing...' : 'Fetch Latest Logs'}
230221
</button>
231-
<button onClick={enableTailing} disabled={tailing}>
232-
{tailing ? 'Tailing Enabled' : 'Enable Tailing'}
222+
223+
<button
224+
className={`btn ${tailing ? 'btn-active' : 'btn-secondary'}`}
225+
onClick={enableTailing}
226+
disabled={tailing}
227+
>
228+
{tailing ? '🟢 Live Tailing Active' : '▶ Enable Live Tailing'}
233229
</button>
234-
{lastUpdatedRef.current && (
235-
<span style={{ marginLeft: '12px' }}>
236-
Last updated: {lastUpdatedRef.current.toLocaleString()}
237-
</span>
238-
)}
239230
</div>
240231

241232
<div className="log-container">
242233
<HistogramChart data={histogram} />
234+
{lastUpdatedRef.current && (
235+
<span className="last-updated">
236+
Last updated: {lastUpdatedRef.current.toLocaleString()}
237+
</span>
238+
)}
243239
<LogViewer logs={logs} />
244-
{loading && <div style={{ textAlign: 'center', margin: '10px' }}>Loading more logs...</div>}
240+
{loading && <div className="loading-text">Loading more logs...</div>}
245241
</div>
246242
</div>
247243
)

src/LogPort.UI/src/components/histogram.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ export const HistogramChart = ({ data }: HistogramChartProps) => {
5858
x: {
5959
type: 'time' as const,
6060
time: {
61-
unit: 'minute' as 'minute',
61+
unit: 'hour' as 'hour',
6262
tooltipFormat: 'HH:mm',
6363
displayFormats: { hour: 'HH:mm' },
6464
},
Lines changed: 84 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,113 @@
1-
.log-container {
2-
border: 2px solid var(--color-surface-alt);
1+
.logs-page {
32
display: flex;
43
flex-direction: column;
5-
gap: 8px;
4+
gap: 16px;
5+
padding: 16px;
6+
color: var(--text-main);
7+
background-color: var(--color-background);
8+
min-height: 100vh;
69
}
710

811
.filter-bar {
912
display: flex;
1013
flex-wrap: wrap;
11-
gap: 8px;
12-
margin-bottom: 12px;
13-
align-items: center;
14-
justify-content: flex-start;
14+
gap: 10px;
15+
background-color: var(--color-surface);
16+
padding: 12px;
17+
border-radius: 10px;
18+
box-shadow: var(--shadow-small);
1519
}
1620

17-
.filter-bar input[type="text"],
21+
.filter-bar input,
1822
.filter-bar select {
19-
padding: 6px 10px;
20-
border-radius: 6px;
21-
border: 1px solid var(--border-color);
22-
background-color: var(--color-surface);
23+
background-color: var(--color-surface-alt);
2324
color: var(--text-main);
24-
font-size: 14px;
25-
outline: none;
26-
transition: border-color 0.15s ease, background-color 0.15s ease;
27-
min-width: 140px;
25+
border: 1px solid var(--border-color);
26+
border-radius: 6px;
27+
padding: 8px;
28+
font-size: 0.9rem;
2829
}
2930

30-
.filter-bar input[type="text"]:focus,
31-
.filter-bar select:focus {
32-
border-color: var(--color-primary-light);
33-
background-color: var(--color-surface-alt);
31+
.filter-bar button {
32+
background-color: var(--color-primary);
33+
color: var(--text-inverse);
34+
border: none;
35+
border-radius: 6px;
36+
padding: 8px 14px;
37+
font-size: 0.9rem;
38+
font-weight: 500;
39+
cursor: pointer;
40+
transition: 0.2s ease;
41+
box-shadow: var(--shadow-small);
3442
}
3543

36-
.filter-bar input[type="text"]:hover,
37-
.filter-bar select:hover {
38-
border-color: var(--color-secondary);
44+
.filter-bar button:hover:not(:disabled) {
45+
background-color: var(--color-primary-light);
3946
}
4047

41-
.filter-bar button {
42-
padding: 6px 14px;
48+
.controls-bar {
49+
display: flex;
50+
justify-content: center;
51+
align-items: center;
52+
gap: 14px;
53+
padding: 14px;
54+
background-color: var(--color-surface);
55+
border-radius: 10px;
56+
box-shadow: var(--shadow-medium);
57+
}
58+
59+
.btn {
4360
border: none;
44-
border-radius: 6px;
45-
background-color: var(--color-primary);
46-
color: var(--text-main);
47-
font-size: 14px;
61+
padding: 10px 18px;
62+
font-size: 0.95rem;
63+
font-weight: 500;
64+
border-radius: 8px;
4865
cursor: pointer;
66+
transition: all 0.2s ease;
4967
box-shadow: var(--shadow-small);
50-
transition: background-color 0.15s ease, box-shadow 0.15s ease, opacity 0.15s ease;
5168
}
5269

53-
.filter-bar button:hover {
70+
.btn-primary {
71+
background-color: var(--color-primary);
72+
color: var(--text-inverse);
73+
}
74+
75+
.btn-primary:hover:not(:disabled) {
5476
background-color: var(--color-primary-light);
77+
transform: translateY(-1px);
78+
}
79+
80+
.btn-secondary {
81+
background-color: var(--color-secondary-dark);
82+
color: var(--text-main);
83+
}
84+
85+
.btn-secondary:hover:not(:disabled) {
86+
background-color: var(--color-secondary);
87+
}
88+
89+
.btn-active {
90+
background-color: var(--accent-success);
91+
color: var(--text-inverse);
92+
font-weight: 600;
5593
box-shadow: var(--shadow-medium);
5694
}
5795

58-
.filter-bar button:disabled {
96+
.btn:disabled {
5997
opacity: 0.6;
6098
cursor: not-allowed;
61-
background-color: var(--color-surface-alt);
99+
}
100+
101+
.loading-text {
102+
text-align: center;
103+
margin: 10px;
104+
color: var(--text-tertiary);
105+
}
106+
107+
.last-updated {
108+
display: block;
109+
text-align: right;
110+
color: var(--text-tertiary);
111+
font-size: var(--font-size-small);
112+
margin-bottom: 10px;
62113
}

0 commit comments

Comments
 (0)