mirror of
https://github.com/PR0M3TH3AN/TORCH.git
synced 2026-11-05 12:21:56 +00:00
feat: add completed task filter and styling to dashboard
- Adds a "Completed only" option to the dashboard status filter. - Updates filtering logic to distinguish between "Active" (running) and "Completed" (finished) tasks. - Adds new utility classes `.bg-success/5` and `.border-success` to `styles.css`. - Applies green tint and success border to completed task cards. Co-authored-by: PR0M3TH3AN <[email protected]>
This commit is contained in:
1 parent
3124cd33e9
commit
adaeac5273
2 files changed
+30
-5
No files matched your search
+27
-5
@@ -65,6 +65,7 @@
|
|||||||
class="rounded-md border border-border bg-surface px-3 py-1.5 text-sm text-text focus:outline-none focus:ring-2 focus:ring-accent"
|
class="rounded-md border border-border bg-surface px-3 py-1.5 text-sm text-text focus:outline-none focus:ring-2 focus:ring-accent"
|
||||||
>
|
>
|
||||||
<option value="active" selected>Active only</option>
|
<option value="active" selected>Active only</option>
|
||||||
|
<option value="completed">Completed only</option>
|
||||||
<option value="all">All (incl. expired)</option>
|
<option value="all">All (incl. expired)</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
@@ -175,7 +176,7 @@
|
|||||||
|
|
||||||
function normalizeStatus(value) {
|
function normalizeStatus(value) {
|
||||||
const normalized = String(value || '').trim().toLowerCase();
|
const normalized = String(value || '').trim().toLowerCase();
|
||||||
return normalized === 'active' || normalized === 'all'
|
return ['active', 'completed', 'all'].includes(normalized)
|
||||||
? normalized
|
? normalized
|
||||||
: DASHBOARD_DEFAULTS.defaultStatusView;
|
: DASHBOARD_DEFAULTS.defaultStatusView;
|
||||||
}
|
}
|
||||||
@@ -401,13 +402,25 @@
|
|||||||
// -----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
||||||
function getFilteredLocks() {
|
function getFilteredLocks() {
|
||||||
const cadence = cadenceFilter.value;
|
const cadence = cadenceFilter.value;
|
||||||
const showExpired = statusFilter.value === 'all';
|
const statusMode = statusFilter.value;
|
||||||
const now = nowUnix();
|
const now = nowUnix();
|
||||||
|
|
||||||
return [...lockStore.values()]
|
return [...lockStore.values()]
|
||||||
.filter((l) => {
|
.filter((l) => {
|
||||||
if (cadence !== 'all' && l.cadence !== cadence) return false;
|
if (cadence !== 'all' && l.cadence !== cadence) return false;
|
||||||
if (!showExpired && isExpired(l)) return false;
|
|
||||||
|
if (statusMode === 'completed') {
|
||||||
|
return l.status === 'completed';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (statusMode === 'active') {
|
||||||
|
// Active means not expired AND not completed
|
||||||
|
if (isExpired(l)) return false;
|
||||||
|
if (l.status === 'completed') return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If 'all', show everything (expired, completed, started)
|
||||||
return true;
|
return true;
|
||||||
})
|
})
|
||||||
.sort((a, b) => b.createdAt - a.createdAt);
|
.sort((a, b) => b.createdAt - a.createdAt);
|
||||||
@@ -479,6 +492,7 @@
|
|||||||
lockGrid.innerHTML = locks
|
lockGrid.innerHTML = locks
|
||||||
.map((lock) => {
|
.map((lock) => {
|
||||||
const expired = isExpired(lock);
|
const expired = isExpired(lock);
|
||||||
|
const isCompleted = lock.status === 'completed';
|
||||||
const ps = platformStyle(lock.platform);
|
const ps = platformStyle(lock.platform);
|
||||||
const age = now - lock.createdAt;
|
const age = now - lock.createdAt;
|
||||||
const remaining = lock.expiresAt ? lock.expiresAt - now : 0;
|
const remaining = lock.expiresAt ? lock.expiresAt - now : 0;
|
||||||
@@ -489,11 +503,19 @@
|
|||||||
? 0
|
? 0
|
||||||
: Math.max(0, Math.min(100, (remaining / ttlTotal) * 100));
|
: Math.max(0, Math.min(100, (remaining / ttlTotal) * 100));
|
||||||
|
|
||||||
|
let cardBg = 'bg-surface-alt';
|
||||||
|
let cardBorder = expired ? 'border-border/50 opacity-60' : 'border-border';
|
||||||
|
|
||||||
|
if (isCompleted) {
|
||||||
|
cardBg = 'bg-success/5';
|
||||||
|
cardBorder = 'border-success/30';
|
||||||
|
}
|
||||||
|
|
||||||
return `
|
return `
|
||||||
<div class="rounded-lg border ${expired ? 'border-border/50 opacity-60' : 'border-border'} bg-surface-alt p-4 flex flex-col gap-3">
|
<div class="rounded-lg border ${cardBorder} ${cardBg} p-4 flex flex-col gap-3">
|
||||||
<div class="flex items-start justify-between">
|
<div class="flex items-start justify-between">
|
||||||
<div class="flex items-center gap-2">
|
<div class="flex items-center gap-2">
|
||||||
${expired ? '' : '<span class="pulse-dot bg-success mt-1 shrink-0"></span>'}
|
${expired || isCompleted ? '' : '<span class="pulse-dot bg-success mt-1 shrink-0"></span>'}
|
||||||
<div>
|
<div>
|
||||||
<div class="font-medium text-text-strong text-sm">${lock.agent}</div>
|
<div class="font-medium text-text-strong text-sm">${lock.agent}</div>
|
||||||
<div class="text-xs text-muted">${lock.cadence} · ${lock.date}</div>
|
<div class="text-xs text-muted">${lock.cadence} · ${lock.date}</div>
|
||||||
|
|||||||
@@ -63,6 +63,7 @@ a { color: inherit; }
|
|||||||
.bg-accent-strong { background-color: var(--accent-strong); }
|
.bg-accent-strong { background-color: var(--accent-strong); }
|
||||||
.bg-success { background-color: var(--success); }
|
.bg-success { background-color: var(--success); }
|
||||||
.bg-success\/10 { background-color: rgb(53 196 124 / 0.1); }
|
.bg-success\/10 { background-color: rgb(53 196 124 / 0.1); }
|
||||||
|
.bg-success\/5 { background-color: rgb(53 196 124 / 0.05); }
|
||||||
.bg-warning { background-color: var(--warning); }
|
.bg-warning { background-color: var(--warning); }
|
||||||
.bg-warning\/10 { background-color: rgb(245 184 75 / 0.1); }
|
.bg-warning\/10 { background-color: rgb(245 184 75 / 0.1); }
|
||||||
.bg-danger { background-color: var(--danger); }
|
.bg-danger { background-color: var(--danger); }
|
||||||
@@ -87,6 +88,8 @@ a { color: inherit; }
|
|||||||
.border-border { border-color: var(--border); }
|
.border-border { border-color: var(--border); }
|
||||||
.border-border\/50 { border-color: rgb(42 52 86 / 0.5); }
|
.border-border\/50 { border-color: rgb(42 52 86 / 0.5); }
|
||||||
.border-border\/30 { border-color: rgb(42 52 86 / 0.3); }
|
.border-border\/30 { border-color: rgb(42 52 86 / 0.3); }
|
||||||
|
.border-success { border-color: var(--success); }
|
||||||
|
.border-success\/30 { border-color: rgb(53 196 124 / 0.3); }
|
||||||
|
|
||||||
.rounded-md { border-radius: 0.375rem; }
|
.rounded-md { border-radius: 0.375rem; }
|
||||||
.rounded-lg { border-radius: 0.5rem; }
|
.rounded-lg { border-radius: 0.5rem; }
|
||||||
|
|||||||
Reference in new issue
Block a user