feat(ui): number-forward stat cards and split action bar on Dashboard

This commit is contained in:
2026-03-19 18:29:19 -04:00
parent f132c115c9
commit b419ee8b32
+39 -55
View File
@@ -1,72 +1,52 @@
<template>
<div>
<v-row>
<!-- Stats Cards -->
<v-col cols="12" md="3">
<v-card>
<v-card-text class="d-flex align-center">
<v-avatar color="primary" size="48" class="mr-4">
<v-icon>mdi-account-multiple</v-icon>
</v-avatar>
<div>
<div class="text-h4">{{ sourcesStore.sources.length }}</div>
<div class="text-caption">Total Sources</div>
</div>
<v-card-text style="border-left: 4px solid rgb(var(--v-theme-primary)); padding-left: 20px">
<div class="text-h3 font-weight-bold">{{ sourcesStore.sources.length }}</div>
<div class="text-caption text-medium-emphasis">Total Sources</div>
</v-card-text>
</v-card>
</v-col>
<v-col cols="12" md="3">
<v-card>
<v-card-text class="d-flex align-center">
<v-avatar color="success" size="48" class="mr-4">
<v-icon>mdi-check-circle</v-icon>
</v-avatar>
<div>
<div class="text-h4">{{ stats?.completed || 0 }}</div>
<div class="text-caption">Completed Downloads</div>
</div>
<v-card-text style="border-left: 4px solid rgb(var(--v-theme-success)); padding-left: 20px">
<div class="text-h3 font-weight-bold">{{ stats?.completed || 0 }}</div>
<div class="text-caption text-medium-emphasis">Completed Downloads</div>
</v-card-text>
</v-card>
</v-col>
<v-col cols="12" md="3">
<v-card>
<v-card-text class="d-flex align-center">
<v-avatar color="error" size="48" class="mr-4">
<v-icon>mdi-alert-circle</v-icon>
</v-avatar>
<div>
<div class="text-h4">{{ stats?.active_failed || 0 }}</div>
<div class="text-caption">Failed Downloads</div>
</div>
<v-card-text style="border-left: 4px solid rgb(var(--v-theme-error)); padding-left: 20px">
<div class="text-h3 font-weight-bold">{{ stats?.active_failed || 0 }}</div>
<div class="text-caption text-medium-emphasis">Failed Downloads</div>
</v-card-text>
</v-card>
</v-col>
<v-col cols="12" md="3">
<v-card>
<v-card-text class="d-flex align-center">
<v-avatar color="warning" size="48" class="mr-4">
<v-icon>mdi-clock-outline</v-icon>
</v-avatar>
<div>
<div class="text-h4">{{ activeDownloadsCount }}</div>
<div class="text-caption">Active Downloads</div>
<div class="text-caption text-grey" v-if="stats?.queued || stats?.running">
{{ stats?.queued || 0 }} queued, {{ stats?.running || 0 }} running
</div>
<v-card-text style="border-left: 4px solid rgb(var(--v-theme-warning)); padding-left: 20px">
<div class="text-h3 font-weight-bold">{{ activeDownloadsCount }}</div>
<div class="text-caption text-medium-emphasis">Active Downloads</div>
<div class="text-caption text-medium-emphasis" v-if="stats?.queued || stats?.running">
{{ stats?.queued || 0 }} queued · {{ stats?.running || 0 }} running
</div>
</v-card-text>
</v-card>
</v-col>
</v-row>
<!-- Quick Actions -->
<!-- Quick Actions & Status -->
<v-row class="mt-4">
<v-col cols="12">
<v-card>
<v-card-text class="d-flex align-center ga-4 flex-wrap">
<!-- Row 1: Action buttons -->
<v-card-text class="d-flex align-center ga-3 flex-wrap pb-3">
<v-btn
color="primary"
prepend-icon="mdi-refresh"
@@ -94,25 +74,29 @@
>
Reset Stuck ({{ stuckRunningCount }})
</v-btn>
<v-spacer />
<!-- Credential Status -->
<div class="d-flex align-center ga-2">
<v-icon size="small" class="mr-1">mdi-key</v-icon>
<span class="text-body-2 text-grey mr-2">Auth:</span>
<v-chip
v-for="platform in supportedPlatforms"
:key="platform"
:color="credentialsStore.hasPlatformCredentials(platform) ? 'success' : 'grey'"
:variant="credentialsStore.hasPlatformCredentials(platform) ? 'tonal' : 'outlined'"
size="x-small"
:to="credentialsStore.hasPlatformCredentials(platform) ? undefined : '/credentials'"
>
<v-icon start size="x-small">{{ getPlatformIcon(platform) }}</v-icon>
{{ platform }}
</v-chip>
</div>
</v-card-text>
<v-divider />
<!-- Row 2: Status info -->
<v-card-text class="d-flex align-center ga-2 flex-wrap pt-3">
<v-icon size="small">mdi-key</v-icon>
<span class="text-body-2 text-medium-emphasis mr-1">Auth:</span>
<v-chip
v-for="platform in supportedPlatforms"
:key="platform"
:color="credentialsStore.hasPlatformCredentials(platform) ? 'success' : 'grey'"
:variant="credentialsStore.hasPlatformCredentials(platform) ? 'tonal' : 'outlined'"
size="x-small"
:to="credentialsStore.hasPlatformCredentials(platform) ? undefined : '/credentials'"
>
<v-icon start size="x-small">{{ getPlatformIcon(platform) }}</v-icon>
{{ platform }}
</v-chip>
<v-divider vertical class="mx-2" />
<div class="text-body-2 text-grey d-flex align-center">
<div class="text-body-2 text-medium-emphasis d-flex align-center">
<v-icon size="small" class="mr-1">mdi-harddisk</v-icon>
Storage: {{ storageStats?.total_size_formatted || 'Calculating...' }}
<span v-if="storageStats?.file_count" class="ml-2">