darroyo
10d0769071
feat!: complete visual redesign → 1.0.0
...
BREAKING: version bump to 1.0.0
New design system:
- Emerald/teal color palette with semantic tokens (success, warning, destructive)
- Light/dark mode toggle with localStorage persistence and anti-FOUC
- CSS custom properties via Tailwind darkMode: 'class'
- Zero new dependencies — all primitives hand-rolled
Foundation:
- 70+ inline SVG icons (no external icon library)
- ThemeProvider + useTheme hook
- cn() utility for conditional classes
UI primitives (web/src/components/ui/):
- Button (6 variants, 4 sizes)
- Input, Label, Card with slots, Badge (6 variants + sizes)
- Switch (animated), Checkbox, Separator
- Skeleton, Spinner, EmptyState
- Toast system with auto-dismiss (success/error/warning/info)
- Dialog with focus trap + escape/click-outside
- ConfirmDialog replacing native confirm()
- DropdownMenu with keyboard support
Layout & navigation:
- Sidebar with icon+label nav, active indicator, responsive drawer on mobile
- Topbar for <lg viewports with hamburger
- PageHeader with title/description/actions pattern
- UserMenu with avatar + dropdown (change password, logout)
- DirtyBanner redesigned with semantic styling
Pages redesigned:
- Login: centered card with gradient background
- Dashboard: 4 KPI tiles, disk usage bars, services grid, recent activity
- Users: table with search, empty state, edit modal
- Files: breadcrumbs, drag-drop upload zone, SVG file icons, rename/delete
- Samba: card list with badges, edit modal with PathField
- NFS: card list with client chips, client editor
- Storage: tabs (Mover/SnapRAID/Jobs), real-time job log streaming
- Log: timeline grouped by date with filters
- Settings: watched mounts, import actions, system info
- NotFound: friendly 404 page
Polish:
- Toast notifications replace all native alert()/confirm()
- Tailwind animations (dialog-enter, toast-enter/leave, dropdown-enter)
- Custom scrollbar styling
- Focus-visible rings
- Skeleton loading states across all pages
2026-07-08 01:24:51 -04:00
darroyo
d3d59b4e45
fix: nil slice -> empty slice in list API responses
...
Backend:
- ListStorageJobs, ListSambaShares, ListNFSExports, ListUsers,
ListDirty, ListApplyLog, ListWatchedMounts: initialize with
make([]T, 0) instead of var x []T to avoid JSON null on empty.
Fixes "Cannot read properties of null" crash on /storage.
Frontend:
- Storage.tsx: defensive setJobs(res.jobs ?? []) to guard against
API returning null.
Tests:
- Add TestListStorageJobsEmptyReturnsSlice.
Version: 0.7.1
2026-07-06 23:31:03 -04:00