rafmacalaba commited on
Commit
dceb63f
·
1 Parent(s): 03cc8ff

refactor: make progress bar contextual - shows current PDF/page/mentions position

Browse files
Files changed (3) hide show
  1. app/components/ProgressBar.js +37 -71
  2. app/globals.css +20 -67
  3. app/page.js +7 -1
app/components/ProgressBar.js CHANGED
@@ -1,83 +1,49 @@
1
  "use client";
2
 
3
- import { useState, useEffect } from 'react';
 
 
 
 
 
 
 
4
 
5
- export default function ProgressBar() {
6
- const [progress, setProgress] = useState(null);
7
- const [expanded, setExpanded] = useState(false);
8
- const [loading, setLoading] = useState(true);
9
 
10
- useEffect(() => {
11
- fetch('/api/progress')
12
- .then(res => res.json())
13
- .then(data => {
14
- setProgress(data);
15
- setLoading(false);
16
- })
17
- .catch(() => setLoading(false));
18
- }, []);
19
 
20
- if (loading || !progress) {
21
- return null; // Don't show anything while loading
22
- }
23
-
24
- const docPct = progress.totalDocs > 0
25
- ? Math.round((progress.completedDocs / progress.totalDocs) * 100) : 0;
26
- const pagePct = progress.totalPages > 0
27
- ? Math.round((progress.completedPages / progress.totalPages) * 100) : 0;
28
- const mentionPct = progress.totalMentions > 0
29
- ? Math.round((progress.verifiedMentions / progress.totalMentions) * 100) : 0;
30
 
31
  return (
32
  <div className="progress-container">
33
- <button
34
- className="progress-toggle"
35
- onClick={() => setExpanded(!expanded)}
36
- >
37
- <span className="progress-summary">
38
- 📊 Progress: {progress.verifiedMentions}/{progress.totalMentions} mentions verified ({mentionPct}%)
39
- </span>
40
- <span className="progress-chevron">{expanded ? '▲' : '▼'}</span>
41
- </button>
42
-
43
- {expanded && (
44
- <div className="progress-details">
45
- <div className="progress-row">
46
- <span className="progress-label">📄 Documents</span>
47
- <div className="progress-bar-track">
48
- <div
49
- className="progress-bar-fill docs-fill"
50
- style={{ width: `${docPct}%` }}
51
- />
52
- </div>
53
- <span className="progress-stat">{progress.completedDocs}/{progress.totalDocs} ({docPct}%)</span>
54
- </div>
55
- <div className="progress-row">
56
- <span className="progress-label">📑 Pages</span>
57
- <div className="progress-bar-track">
58
- <div
59
- className="progress-bar-fill pages-fill"
60
- style={{ width: `${pagePct}%` }}
61
- />
62
- </div>
63
- <span className="progress-stat">{progress.completedPages}/{progress.totalPages} ({pagePct}%)</span>
64
- </div>
65
- <div className="progress-row">
66
- <span className="progress-label">🏷️ Mentions</span>
67
- <div className="progress-bar-track">
68
- <div
69
- className="progress-bar-fill mentions-fill"
70
- style={{ width: `${mentionPct}%` }}
71
- />
72
- </div>
73
- <span className="progress-stat">{progress.verifiedMentions}/{progress.totalMentions} ({mentionPct}%)</span>
74
- </div>
75
- <div className="progress-row">
76
- <span className="progress-label">✍️ Human annotations</span>
77
- <span className="progress-stat highlight">{progress.humanAnnotations}</span>
78
- </div>
79
  </div>
80
- )}
81
  </div>
82
  );
83
  }
 
1
  "use client";
2
 
3
+ export default function ProgressBar({
4
+ documents,
5
+ selectedDocIndex,
6
+ currentDoc,
7
+ pageIdx,
8
+ currentPageDatasets,
9
+ }) {
10
+ if (!documents || documents.length === 0) return null;
11
 
12
+ // 1. PDF progress: which doc out of total
13
+ const docPosition = documents.findIndex(d => d.index === selectedDocIndex) + 1;
14
+ const totalDocs = documents.length;
 
15
 
16
+ // 2. Page progress: which page out of annotatable pages in current doc
17
+ const totalPages = currentDoc?.annotatable_pages?.length ?? 0;
18
+ const currentPage = totalPages > 0 ? pageIdx + 1 : 0;
 
 
 
 
 
 
19
 
20
+ // 3. Mentions progress: verified vs total on current page
21
+ const totalMentions = currentPageDatasets?.length ?? 0;
22
+ const verifiedMentions = currentPageDatasets?.filter(ds => ds.human_validated === true).length ?? 0;
 
 
 
 
 
 
 
23
 
24
  return (
25
  <div className="progress-container">
26
+ <div className="progress-pills">
27
+ <div className="progress-pill">
28
+ <span className="pill-icon">📄</span>
29
+ <span className="pill-label">PDF</span>
30
+ <span className="pill-value">{docPosition}/{totalDocs}</span>
31
+ </div>
32
+ <div className="pill-divider" />
33
+ <div className="progress-pill">
34
+ <span className="pill-icon">📑</span>
35
+ <span className="pill-label">Page</span>
36
+ <span className="pill-value">{currentPage}/{totalPages}</span>
37
+ </div>
38
+ <div className="pill-divider" />
39
+ <div className="progress-pill">
40
+ <span className="pill-icon">🏷️</span>
41
+ <span className="pill-label">Verified</span>
42
+ <span className={`pill-value ${verifiedMentions === totalMentions && totalMentions > 0 ? 'pill-complete' : ''}`}>
43
+ {verifiedMentions}/{totalMentions}
44
+ </span>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
45
  </div>
46
+ </div>
47
  </div>
48
  );
49
  }
app/globals.css CHANGED
@@ -164,92 +164,45 @@ h4 {
164
  border-bottom: 1px solid var(--border-color);
165
  background: var(--pane-bg);
166
  flex-shrink: 0;
 
167
  }
168
 
169
- .progress-toggle {
170
  display: flex;
171
  align-items: center;
172
- justify-content: space-between;
173
- width: 100%;
174
- padding: 5px 20px;
175
- background: none;
176
- border: none;
177
- color: var(--text-color);
178
- cursor: pointer;
179
- font-size: 0.78rem;
180
- }
181
-
182
- .progress-toggle:hover {
183
- background: rgba(255, 255, 255, 0.03);
184
- }
185
-
186
- .progress-summary {
187
- font-weight: 600;
188
- }
189
-
190
- .progress-chevron {
191
- font-size: 0.6rem;
192
- color: #64748b;
193
- }
194
-
195
- .progress-details {
196
- padding: 8px 20px 10px;
197
- display: flex;
198
- flex-direction: column;
199
- gap: 6px;
200
- border-top: 1px solid var(--border-color);
201
  }
202
 
203
- .progress-row {
204
  display: flex;
205
  align-items: center;
206
- gap: 10px;
207
  font-size: 0.75rem;
208
  }
209
 
210
- .progress-label {
211
- width: 130px;
212
- flex-shrink: 0;
213
- color: #94a3b8;
214
- }
215
-
216
- .progress-bar-track {
217
- flex: 1;
218
- height: 6px;
219
- background: var(--surface);
220
- border-radius: 3px;
221
- overflow: hidden;
222
- }
223
-
224
- .progress-bar-fill {
225
- height: 100%;
226
- border-radius: 3px;
227
- transition: width 0.5s ease;
228
- }
229
-
230
- .docs-fill {
231
- background: var(--success);
232
  }
233
 
234
- .pages-fill {
235
- background: var(--accent);
 
236
  }
237
 
238
- .mentions-fill {
239
- background: #f59e0b;
 
 
240
  }
241
 
242
- .progress-stat {
243
- font-size: 0.72rem;
244
- color: #94a3b8;
245
- white-space: nowrap;
246
- min-width: 80px;
247
- text-align: right;
248
  }
249
 
250
- .progress-stat.highlight {
251
- color: var(--success);
252
- font-weight: 600;
 
253
  }
254
 
255
  .pane {
 
164
  border-bottom: 1px solid var(--border-color);
165
  background: var(--pane-bg);
166
  flex-shrink: 0;
167
+ padding: 4px 20px;
168
  }
169
 
170
+ .progress-pills {
171
  display: flex;
172
  align-items: center;
173
+ gap: 12px;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
174
  }
175
 
176
+ .progress-pill {
177
  display: flex;
178
  align-items: center;
179
+ gap: 5px;
180
  font-size: 0.75rem;
181
  }
182
 
183
+ .pill-icon {
184
+ font-size: 0.7rem;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
185
  }
186
 
187
+ .pill-label {
188
+ color: #64748b;
189
+ font-weight: 500;
190
  }
191
 
192
+ .pill-value {
193
+ color: var(--text-color);
194
+ font-weight: 700;
195
+ font-variant-numeric: tabular-nums;
196
  }
197
 
198
+ .pill-value.pill-complete {
199
+ color: var(--success);
 
 
 
 
200
  }
201
 
202
+ .pill-divider {
203
+ width: 1px;
204
+ height: 14px;
205
+ background: var(--border-color);
206
  }
207
 
208
  .pane {
app/page.js CHANGED
@@ -431,7 +431,13 @@ export default function Home() {
431
  )}
432
  </div>
433
  </div>
434
- <ProgressBar />
 
 
 
 
 
 
435
  <div className="container">
436
  <div className="pane left-pane">
437
  <div className="pane-header">
 
431
  )}
432
  </div>
433
  </div>
434
+ <ProgressBar
435
+ documents={documents}
436
+ selectedDocIndex={selectedDocIndex}
437
+ currentDoc={currentDoc}
438
+ pageIdx={pageIdx}
439
+ currentPageDatasets={currentPageDatasets}
440
+ />
441
  <div className="container">
442
  <div className="pane left-pane">
443
  <div className="pane-header">