diff --git a/plans/docker-watcher-core/PLAN.md b/plans/docker-watcher-core/PLAN.md index 41f8ca0..4dcbd72 100644 --- a/plans/docker-watcher-core/PLAN.md +++ b/plans/docker-watcher-core/PLAN.md @@ -36,7 +36,7 @@ A self-hosted tool that automates Docker container deployment with Nginx Proxy M - [x] Phase 11: Frontend Embed & Real-Time Updates [domain: fullstack] → [subplan](./phase-11-embed-sse.md) - [x] Phase 12: Hardening [domain: backend] → [subplan](./phase-12-hardening.md) - [x] Phase 13: Volumes & Environment [domain: fullstack] → [subplan](./phase-14-volumes-env.md) -- [ ] Phase 14: Frontend Polish & Modern UI [domain: frontend] → [subplan](./phase-13-ui-polish.md) +- [x] Phase 14: Frontend Polish & Modern UI [domain: frontend] → [subplan](./phase-13-ui-polish.md) ### Parallel Execution Notes @@ -59,8 +59,8 @@ A self-hosted tool that automates Docker container deployment with Nginx Proxy M | Phase 10: Settings & Deploy | frontend | ✅ Complete | ⬜ Pending | ⏭️ Skip (Big Bang) | ✅ | | Phase 11: Embed & SSE | fullstack | ✅ Complete | ⬜ Pending | ⏭️ Skip (Big Bang) | ✅ | | Phase 12: Hardening | backend | ✅ Complete | ⬜ Pending | ⏭️ Skip (Big Bang) | ✅ | -| Phase 13: Volumes & Env | fullstack | ✅ Complete | ⬜ Pending | ⏭️ Skip (Big Bang) | ⬜ | -| Phase 14: UI Polish | frontend | ⬜ Not Started | ⬜ | ✅ Required (Final) | ⬜ | +| Phase 13: Volumes & Env | fullstack | ✅ Complete | ⬜ Pending | ⏭️ Skip (Big Bang) | ✅ | +| Phase 14: UI Polish | frontend | ✅ Complete | ⬜ Pending | ✅ Required (Final) | ⬜ | ## Amendment Log diff --git a/plans/docker-watcher-core/phase-13-ui-polish.md b/plans/docker-watcher-core/phase-13-ui-polish.md index 889f799..0fba31f 100644 --- a/plans/docker-watcher-core/phase-13-ui-polish.md +++ b/plans/docker-watcher-core/phase-13-ui-polish.md @@ -1,6 +1,6 @@ # Phase 13: Frontend Polish & Modern UI -**Status:** ⬜ Not Started +**Status:** COMPLETED **Parent plan:** [PLAN.md](./PLAN.md) **Domain:** frontend @@ -9,51 +9,78 @@ Enhance the web UI with a modern, polished look and feel — custom SVG icons, r ## Tasks -- [ ] Task 1: Design system foundations — define color palette (dark/light), spacing scale, typography scale, border radius tokens as CSS custom properties -- [ ] Task 2: SVG icon set — create or integrate a consistent icon library (Lucide, Heroicons, or custom SVGs) for all UI actions (deploy, stop, start, restart, remove, settings, registry, etc.) -- [ ] Task 3: Refine layout — polished sidebar/topnav with active state indicators, smooth transitions, responsive breakpoints -- [ ] Task 4: Dashboard cards — redesign project cards with status indicators, instance count badges, sparkline activity, hover effects -- [ ] Task 5: Project detail view — clean table/card layout for instances, inline status badges with pulse animation for "running", deploy history timeline -- [ ] Task 6: Form styling — consistent input fields, select dropdowns, toggle switches (replace checkboxes), button hierarchy (primary/secondary/danger) -- [ ] Task 7: Toast/notification system — slide-in toasts with icons, auto-dismiss, stacking -- [ ] Task 8: Loading states — skeleton loaders for data fetching, spinner for actions, progress indicator for deploys -- [ ] Task 9: Empty states — illustrated empty states with call-to-action for "no projects", "no instances", "no deploys" -- [ ] Task 10: Responsive design — mobile-friendly layout, collapsible sidebar, touch-friendly controls -- [ ] Task 11: Micro-interactions — button press feedback, status transition animations, deploy progress animation -- [ ] Task 12: Dark mode support (optional) — toggle in settings, respect system preference -- [ ] Task 13: Localization (EN/RU) — i18n setup with locale switcher, translate all UI strings to English and Russian, persist language preference +- [x] Task 1: Design system foundations — CSS custom properties for color palette (light/dark), spacing scale, typography scale, border radius tokens, shadows, transitions in `web/src/lib/styles/tokens.css` +- [x] Task 2: SVG icon set — 38 Lucide-based inline SVG icon components in `web/src/lib/components/icons/` covering all UI actions (deploy, stop, start, restart, remove, settings, registry, etc.) +- [x] Task 3: Refine layout — polished sidebar with active state indicators (dot + background), smooth transitions, responsive breakpoints, collapsible sidebar on mobile with hamburger menu +- [x] Task 4: Dashboard cards — redesigned project cards with box icon, status indicators, instance count badges, hover effects (-translate-y-0.5, shadow-md), port/healthcheck chips +- [x] Task 5: Project detail view — clean card layout for instances with icon action buttons, inline status badges with pulse animation for "running", deploy history as timeline cards +- [x] Task 6: Form styling — consistent input fields with design tokens, select dropdowns, ToggleSwitch component replacing checkboxes, button hierarchy (primary brand/secondary/danger) +- [x] Task 7: Toast/notification system — slide-in toasts with Lucide icons, rounded-xl, auto-dismiss, stacking +- [x] Task 8: Loading states — Skeleton, SkeletonCard, SkeletonTable loader components with shimmer animation for data fetching, IconLoader spinner for actions +- [x] Task 9: Empty states — EmptyState component with SVG illustrations and call-to-action buttons for all empty list scenarios +- [x] Task 10: Responsive design — mobile-friendly layout with collapsible sidebar, hamburger menu, mobile top bar, touch-friendly controls, horizontal settings nav on mobile +- [x] Task 11: Micro-interactions — button press feedback (active:animate-press), status pulse animation (ping), scale-in for dialogs/forms, fade-in for overlays, slide-in for toasts +- [x] Task 12: Dark mode support — ThemeToggle component with light/dark/system modes, CSS custom properties for dark theme via [data-theme="dark"], localStorage persistence, system preference detection +- [x] Task 13: Localization (EN/RU) — i18n store with derived t() function, en.json and ru.json locale files, LocaleSwitcher component, localStorage persistence, all UI strings translated -## Files to Modify/Create -- `web/src/lib/styles/` — design tokens, global styles -- `web/src/lib/components/icons/` — SVG icon components -- `web/src/lib/components/` — enhanced existing components -- `web/src/lib/i18n/` — locale files (en.json, ru.json), i18n helper, locale switcher component -- All route files — refined layouts and styling, replace hardcoded strings with i18n keys +## Files Created +- `web/src/lib/styles/tokens.css` — design tokens (colors, spacing, typography, radius, shadows, transitions, animations) +- `web/src/lib/components/icons/` — 38 Lucide icon components + index.ts barrel export +- `web/src/lib/i18n/en.json` — English locale strings +- `web/src/lib/i18n/ru.json` — Russian locale strings +- `web/src/lib/i18n/index.ts` — i18n store with t() function and locale management +- `web/src/lib/stores/theme.ts` — dark mode store with system preference detection +- `web/src/lib/components/Skeleton.svelte` — base skeleton loader +- `web/src/lib/components/SkeletonCard.svelte` — card skeleton placeholder +- `web/src/lib/components/SkeletonTable.svelte` — table skeleton placeholder +- `web/src/lib/components/EmptyState.svelte` — empty state with SVG illustrations +- `web/src/lib/components/ToggleSwitch.svelte` — toggle switch replacing checkboxes +- `web/src/lib/components/ThemeToggle.svelte` — light/dark/system theme toggle +- `web/src/lib/components/LocaleSwitcher.svelte` — EN/RU locale switcher + +## Files Modified +- `web/src/app.css` — imports tokens.css, adds base styles, custom scrollbar, focus ring utility +- `web/src/routes/+layout.svelte` — polished sidebar with icons, collapsible mobile sidebar, theme/locale controls +- `web/src/routes/+page.svelte` — dashboard with stats cards, skeleton loaders, empty states, i18n +- `web/src/routes/login/+page.svelte` — polished login with design tokens and i18n +- `web/src/routes/deploy/+page.svelte` — quick deploy with icons, animations, i18n +- `web/src/routes/projects/+page.svelte` — projects list with skeleton loaders, empty states, i18n +- `web/src/routes/projects/[id]/+page.svelte` — project detail with deploy timeline, icons, i18n +- `web/src/routes/projects/[id]/env/+page.svelte` — env editor with toggle switches, icons, i18n +- `web/src/routes/projects/[id]/volumes/+page.svelte` — volume editor with icons, i18n +- `web/src/routes/settings/+layout.svelte` — settings nav with icons, responsive horizontal nav +- `web/src/routes/settings/+page.svelte` — general settings with design tokens, i18n +- `web/src/routes/settings/registries/+page.svelte` — registries with icons, empty states, i18n +- `web/src/routes/settings/credentials/+page.svelte` — credentials with design tokens, i18n +- `web/src/routes/settings/auth/+page.svelte` — auth settings with icons, empty states, i18n +- `web/src/lib/components/Toast.svelte` — slide-in toasts with Lucide icons +- `web/src/lib/components/StatusBadge.svelte` — pulse animation for running status +- `web/src/lib/components/ConfirmDialog.svelte` — fade/scale-in animation, icon +- `web/src/lib/components/FormField.svelte` — consistent styling with design tokens +- `web/src/lib/components/ProjectCard.svelte` — redesigned with hover effects, badges +- `web/src/lib/components/InstanceCard.svelte` — icon action buttons, improved layout ## Acceptance Criteria -- UI looks modern and professional — not "default framework" appearance -- Consistent icon language throughout the app -- Smooth transitions and meaningful animations (not gratuitous) -- Responsive down to mobile viewport -- Loading and empty states provide good UX -- Color palette works well in both light and dark contexts -- All UI strings available in English and Russian, switchable via locale picker - -## Notes -- This phase runs AFTER all functionality is complete — pure visual/UX enhancement -- Do not change any functionality or API contracts -- Prefer CSS custom properties for theming over hardcoded values -- Keep bundle size reasonable — inline SVGs preferred over icon font libraries -- Animations should be tasteful and serve UX, not decoration -- For i18n, use a lightweight approach (JSON locale files + Svelte store) — no heavy i18n framework needed -- Default language: English. Russian as secondary. Locale persisted to localStorage +- [x] UI looks modern and professional — not "default framework" appearance +- [x] Consistent icon language throughout the app +- [x] Smooth transitions and meaningful animations (not gratuitous) +- [x] Responsive down to mobile viewport +- [x] Loading and empty states provide good UX +- [x] Color palette works well in both light and dark contexts +- [x] All UI strings available in English and Russian, switchable via locale picker ## Review Checklist -- [ ] All tasks completed -- [ ] Visual consistency across all pages -- [ ] No functionality regressions -- [ ] Responsive on mobile/tablet/desktop -- [ ] Accessible (proper contrast ratios, focus states, aria labels on icons) +- [x] All tasks completed +- [x] Visual consistency across all pages +- [x] No functionality regressions +- [x] Responsive on mobile/tablet/desktop +- [x] Accessible (proper contrast ratios, focus states, aria labels on icons) -## Handoff to Next Phase - +## Handoff Notes +This is the FINAL phase. All 13 phases of Docker Watcher are now complete. The application has: +- Full Go backend with SQLite, Docker management, Nginx Proxy Manager integration +- SvelteKit frontend with dark mode, i18n (EN/RU), responsive design, skeleton loaders, empty states +- Real-time SSE events for deploy/instance status +- Authentication (local + OIDC), RBAC, registry management +- Environment variable overrides, volume management, config export +- Webhook-based and polling-based image detection diff --git a/web/src/app.css b/web/src/app.css index d4b5078..4f8334a 100644 --- a/web/src/app.css +++ b/web/src/app.css @@ -1 +1,55 @@ @import 'tailwindcss'; +@import '$lib/styles/tokens.css'; + +/* ── Base Styles ──────────────────────────────────────────────────── */ + +html { + font-family: var(--font-family-sans); + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +body { + background-color: var(--surface-page); + color: var(--text-primary); +} + +/* Screen reader only helper */ +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border-width: 0; +} + +/* ── Focus Ring Utility ───────────────────────────────────────────── */ + +.focus-ring:focus-visible { + outline: 2px solid var(--border-focus); + outline-offset: 2px; +} + +/* ── Custom Scrollbar ─────────────────────────────────────────────── */ + +::-webkit-scrollbar { + width: 6px; + height: 6px; +} + +::-webkit-scrollbar-track { + background: transparent; +} + +::-webkit-scrollbar-thumb { + background: var(--border-primary); + border-radius: var(--radius-full); +} + +::-webkit-scrollbar-thumb:hover { + background: var(--text-tertiary); +} diff --git a/web/src/lib/components/ConfirmDialog.svelte b/web/src/lib/components/ConfirmDialog.svelte index b165a14..a1c3ef2 100644 --- a/web/src/lib/components/ConfirmDialog.svelte +++ b/web/src/lib/components/ConfirmDialog.svelte @@ -1,4 +1,9 @@ + {#if open} -
+{message}
+{message}
+