feat(exam): log time spent per scenario in exam report
Signed-off-by: Abhinav Sinha <[email protected]>
This commit is contained in:
@@ -22,6 +22,14 @@ function formatDate(iso) {
|
||||
})
|
||||
}
|
||||
|
||||
function formatRowTime(secs) {
|
||||
if (!secs || secs === 0) return '—'
|
||||
const m = Math.floor(secs / 60)
|
||||
const s = secs % 60
|
||||
if (m > 0) return `${m}m ${s > 0 ? s + 's' : ''}`.trim()
|
||||
return `${s}s`
|
||||
}
|
||||
|
||||
function ScoreRing({ pct, passed, size = 72 }) {
|
||||
const r = (size / 2) - 7
|
||||
const circ = 2 * Math.PI * r
|
||||
@@ -169,6 +177,15 @@ function AttemptDetail({ attempt }) {
|
||||
{s.attempts > 0 && (
|
||||
<span className={styles.rowAttempts}>{s.attempts} attempt{s.attempts > 1 ? 's' : ''}</span>
|
||||
)}
|
||||
<span className={styles.rowTime}>
|
||||
{(s.time_spent_seconds > 0) && (
|
||||
<svg viewBox="0 0 24 24" width="10" height="10" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" style={{ marginRight: 3, verticalAlign: 'middle', opacity: 0.6 }}>
|
||||
<circle cx="12" cy="12" r="10" />
|
||||
<polyline points="12 6 12 12 16 14" />
|
||||
</svg>
|
||||
)}
|
||||
{formatRowTime(s.time_spent_seconds)}
|
||||
</span>
|
||||
<span className={styles.rowPts}>
|
||||
{s.status === 'completed' ? s.weight : 0}/{s.weight} pts
|
||||
</span>
|
||||
|
||||
@@ -430,6 +430,15 @@
|
||||
border-radius: 3px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.rowTime {
|
||||
font-family: var(--mono);
|
||||
font-size: 11px;
|
||||
color: var(--text-3);
|
||||
flex-shrink: 0;
|
||||
min-width: 52px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.rowPts {
|
||||
font-family: var(--mono);
|
||||
font-size: 11px;
|
||||
|
||||
@@ -10,6 +10,14 @@ function formatDuration(secs) {
|
||||
return `${s}s`
|
||||
}
|
||||
|
||||
function formatRowTime(secs) {
|
||||
if (!secs || secs === 0) return '—'
|
||||
const m = Math.floor(secs / 60)
|
||||
const s = secs % 60
|
||||
if (m > 0) return `${m}m ${s > 0 ? s + 's' : ''}`.trim()
|
||||
return `${s}s`
|
||||
}
|
||||
|
||||
const DIFF_COLOR = { Easy: 'var(--green)', Medium: 'var(--amber)', Hard: 'var(--red)' }
|
||||
|
||||
export default function ExamReport({ report, bundle, onClose, onRetry }) {
|
||||
@@ -86,6 +94,15 @@ export default function ExamReport({ report, bundle, onClose, onRetry }) {
|
||||
<span className={styles.rowDiff} style={{ color: DIFF_COLOR[s.difficulty] }}>
|
||||
{s.difficulty}
|
||||
</span>
|
||||
<span className={styles.rowTime}>
|
||||
{s.time_spent_seconds > 0 && (
|
||||
<svg viewBox="0 0 24 24" width="10" height="10" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" style={{ marginRight: 3, verticalAlign: 'middle', opacity: 0.6 }}>
|
||||
<circle cx="12" cy="12" r="10" />
|
||||
<polyline points="12 6 12 12 16 14" />
|
||||
</svg>
|
||||
)}
|
||||
{formatRowTime(s.time_spent_seconds)}
|
||||
</span>
|
||||
<span className={styles.rowPts}>{s.status === 'completed' ? s.weight : 0}/{s.weight} pts</span>
|
||||
</div>
|
||||
))}
|
||||
|
||||
@@ -101,6 +101,15 @@
|
||||
.rowIcon { font-size: 14px; flex-shrink: 0; }
|
||||
.rowTitle { flex: 1; }
|
||||
.rowDiff { font-size: 11px; font-weight: 600; flex-shrink: 0; }
|
||||
.rowTime {
|
||||
font-family: var(--mono);
|
||||
font-size: 11px;
|
||||
color: var(--text-3);
|
||||
flex-shrink: 0;
|
||||
min-width: 52px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.rowPts { font-family: var(--mono); font-size: 12px; color: var(--text-3); flex-shrink: 0; min-width: 60px; text-align: right; }
|
||||
|
||||
/* Actions */
|
||||
|
||||
Reference in New Issue
Block a user