docs: add UI improvement pass design spec
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,184 @@
|
||||
# UI Improvement Pass — Design Spec
|
||||
|
||||
**Date:** 2026-03-19
|
||||
**Scope:** All 6 pages — visual polish + UX usability, equal weight
|
||||
**Direction:** Darker, cooler blue-grey tone ("monitoring dashboard" feel), lifted nav branding
|
||||
|
||||
---
|
||||
|
||||
## Goals
|
||||
|
||||
1. Replace the generic default-Vuetify color palette with a distinctive monitoring-dashboard identity
|
||||
2. Give the nav drawer meaningful visual structure and branding
|
||||
3. Add a WebSocket connection indicator in the app bar
|
||||
4. Improve Dashboard information hierarchy and action bar layout
|
||||
5. Fix dark-mode-breaking hardcoded colour classes across all pages
|
||||
6. Consistent empty states and loading treatment throughout
|
||||
7. Per-page UX improvements (Downloads filter, Credentials visual state, Subscriptions dark mode)
|
||||
|
||||
---
|
||||
|
||||
## Section 1: Color System (`frontend/src/plugins/vuetify.js`)
|
||||
|
||||
Replace both theme palettes entirely.
|
||||
|
||||
### Dark theme (primary use case)
|
||||
```js
|
||||
dark: {
|
||||
dark: true,
|
||||
colors: {
|
||||
background: '#0F172A', // slate-900 — deep navy
|
||||
surface: '#1E293B', // slate-800 — card surfaces
|
||||
primary: '#60A5FA', // blue-400 — cooler accent
|
||||
secondary: '#94A3B8', // slate-400
|
||||
error: '#F87171', // red-400
|
||||
warning: '#FBBF24', // amber-400
|
||||
success: '#34D399', // emerald-400
|
||||
info: '#38BDF8', // sky-400
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
### Light theme
|
||||
```js
|
||||
light: {
|
||||
dark: false,
|
||||
colors: {
|
||||
background: '#F1F5F9', // slate-100 — cool grey workspace
|
||||
surface: '#FFFFFF',
|
||||
primary: '#2563EB', // blue-600 — deeper, more serious
|
||||
secondary: '#475569', // slate-600
|
||||
error: '#EF4444',
|
||||
warning: '#F59E0B',
|
||||
success: '#10B981',
|
||||
info: '#0EA5E9',
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
### Global component defaults (add to existing `defaults`)
|
||||
```js
|
||||
VCard: { elevation: 0, border: true },
|
||||
VBtn: { variant: 'flat' },
|
||||
VChip: { rounded: 'md' },
|
||||
```
|
||||
|
||||
Removing shadow elevation in favour of a subtle border gives cards a cleaner, more modern feel at both themes. The border adapts to theme colours automatically.
|
||||
|
||||
---
|
||||
|
||||
## Section 2: Nav Drawer & App Bar (`frontend/src/App.vue`)
|
||||
|
||||
### Nav drawer brand header
|
||||
Replace the plain `v-list-item` brand block with a styled header:
|
||||
- Container: `pa-4` padding, `bg-surface` background to visually separate from nav list
|
||||
- Icon: `mdi-download-network` at size 32, `color="primary"`
|
||||
- Title: `"GallerySubscriber"` in `font-weight-bold text-subtitle-1`
|
||||
- Subtitle: `"Download Manager"` in `text-caption text-medium-emphasis`
|
||||
- Followed by a `v-divider`
|
||||
|
||||
### Nav list items
|
||||
Change from `density="compact"` to `density="comfortable"`. Add `rounded="lg"` and `active-color="primary"` to each `v-list-item`. The built-in Vuetify active state renders a tinted pill highlight on the current route.
|
||||
|
||||
### App bar
|
||||
- Change `elevation="1"` to `elevation="0"` with `border="b"` — flat bar with bottom border
|
||||
- Add a WebSocket status indicator to the right of the title, before the theme toggle:
|
||||
- A `v-chip` or icon+dot combination showing three states:
|
||||
- **Connected:** small green dot (`color="success"`) + tooltip "Connected"
|
||||
- **Connecting:** amber dot with CSS pulse animation + tooltip "Connecting…"
|
||||
- **Disconnected:** red dot + tooltip "Disconnected — real-time updates paused"
|
||||
- Reads from `useWebSocketStore().status` (the store already tracks connection state)
|
||||
- `variant="text"` so it's unobtrusive
|
||||
|
||||
---
|
||||
|
||||
## Section 3: Dashboard (`frontend/src/views/Dashboard.vue`)
|
||||
|
||||
### Stat cards (number-forward layout)
|
||||
Replace the `v-avatar` + side-by-side number layout with a vertical number-forward design:
|
||||
- Large `text-h3 font-weight-bold` number at top
|
||||
- `text-caption text-medium-emphasis` label below
|
||||
- A 4px left border accent stripe using inline style `border-left: 4px solid <colour>` matching the card's semantic colour (primary, success, error, warning)
|
||||
- Remove the `v-avatar` entirely — the border provides the colour signal
|
||||
|
||||
### Action bar (split into two rows)
|
||||
**Row 1** (actions): The three action buttons unchanged — Check All Sources, Retry All Failed, Reset Stuck.
|
||||
|
||||
**Row 2** (status): Two groups separated by a `v-divider vertical`:
|
||||
- Left: credential status chips (the existing platform chips, unchanged)
|
||||
- Right: storage stats (existing display, unchanged)
|
||||
|
||||
Each row is its own `v-card-text`. This removes the single-line cramming.
|
||||
|
||||
### Active downloads list
|
||||
Running items get a subtle animated left border:
|
||||
```css
|
||||
.download-running {
|
||||
border-left: 3px solid rgb(var(--v-theme-primary));
|
||||
animation: pulse-border 2s ease-in-out infinite;
|
||||
}
|
||||
@keyframes pulse-border {
|
||||
0%, 100% { opacity: 1; }
|
||||
50% { opacity: 0.4; }
|
||||
}
|
||||
```
|
||||
|
||||
### Consistent empty states
|
||||
All three empty panels (active downloads, recent activity, sources needing attention) use the same pattern:
|
||||
```html
|
||||
<div class="text-center py-8">
|
||||
<v-icon size="48" color="medium-emphasis">mdi-[relevant-icon]</v-icon>
|
||||
<div class="text-body-1 mt-2">[Primary message]</div>
|
||||
<div class="text-caption text-medium-emphasis mt-1">[Helper text]</div>
|
||||
</div>
|
||||
```
|
||||
- Active downloads empty: icon `mdi-check-circle-outline`, "No active downloads", "All sources are idle"
|
||||
- Recent activity empty: icon `mdi-history`, "No recent activity", "Failures and new downloads appear here"
|
||||
- Sources needing attention empty: icon `mdi-check-all`, "All sources healthy", "No failures in the last 7 days"
|
||||
|
||||
---
|
||||
|
||||
## Section 4: Per-Page Fixes
|
||||
|
||||
### Subscriptions (`frontend/src/views/Subscriptions.vue`)
|
||||
- Replace `class="bg-grey-lighten-4"` on the expanded inner table with `class="bg-surface"`. This is the only dark-mode-breaking class in the file.
|
||||
- Add `class="border-t"` to the inner table container for visual separation.
|
||||
|
||||
### Downloads (`frontend/src/views/Downloads.vue`)
|
||||
- Add an `exclude_superseded` toggle to the filters row: a `v-switch` or `v-chip` labelled "Hide superseded failures" that adds `exclude_superseded: true` to the fetch params when active. Defaults to `true` (consistent with the dashboard behaviour).
|
||||
- No table layout changes.
|
||||
|
||||
### Credentials (`frontend/src/views/Credentials.vue`)
|
||||
Two visual states for platform cards:
|
||||
|
||||
**Configured:** Card gets `border-color` set to the success colour via inline style or a CSS class. Existing content unchanged.
|
||||
|
||||
**Not configured:** Card gets a dashed border (`border: 2px dashed`), the `v-alert` info block is replaced with a concise empty-state message, and the "Add Credentials" button is promoted to `color="primary" variant="flat"` (currently `variant="text"`), making the call to action visually prominent.
|
||||
|
||||
### Settings & Logs
|
||||
No structural changes — both pages inherit the new palette and card border style from the vuetify.js update automatically.
|
||||
|
||||
---
|
||||
|
||||
## Files Changed
|
||||
|
||||
| File | Change |
|
||||
|------|--------|
|
||||
| `frontend/src/plugins/vuetify.js` | Full palette replacement, component defaults update |
|
||||
| `frontend/src/App.vue` | Nav branding, nav item density/rounding, app bar border+ws indicator |
|
||||
| `frontend/src/views/Dashboard.vue` | Stat card layout, action bar split, running item pulse, empty states |
|
||||
| `frontend/src/views/Subscriptions.vue` | Replace `bg-grey-lighten-4` with `bg-surface` |
|
||||
| `frontend/src/views/Downloads.vue` | Add `exclude_superseded` filter toggle |
|
||||
| `frontend/src/views/Credentials.vue` | Configured/unconfigured card visual states |
|
||||
|
||||
Settings.vue and Logs.vue are **not modified** — they benefit from the theme update without code changes.
|
||||
|
||||
---
|
||||
|
||||
## Non-Goals
|
||||
|
||||
- No new pages or routes
|
||||
- No layout restructuring (grid columns, page structure unchanged)
|
||||
- No new API endpoints
|
||||
- No component extraction / shared component library
|
||||
- Settings.vue and Logs.vue: no structural changes
|
||||
Reference in New Issue
Block a user