UX polish pass 2: toasts, optimistic updates, mod update detection

- Install sonner; <Toaster> mounted in Providers, auto-tracks theme.
- Toasts replace inline result Alerts across ServerControls, PlayerManager,
  BackupManager, ModManager (install/remove/restore/delete/start/stop).
- PlayerManager: optimistic op/deop/whitelist/ban/pardon via onMutate +
  rollback; UI updates instantly before RCON round-trip.
- Modrinth search results now show author + "updated Xd ago" with full
  timestamp on hover; downloads on its own row.
- New /api/mods/updates endpoint: per-installed-mod Modrinth latest-version
  lookup (parallel, 30min memo). Amber "Update available" badge rendered
  next to installed mod rows when filenames differ.
- PlayerAvatar + Modrinth icons migrated to next/image (unoptimized, size
  hints) — fewer layout shifts.
- Login page surfaces ?error= + NextAuth error codes (CredentialsSignin,
  SessionRequired, etc.), preserves callbackUrl, adds autocomplete hints
  and role="alert". Wrapped in Suspense per Next 16 requirement.
- Snapshots + backups show relative "Xh ago" with exact timestamp on hover
  via new lib/time.ts helper.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
hurkicorgi 2026-04-13 05:11:17 -06:00
parent 6c91f7fef0
commit f9ae1afac1
12 changed files with 334 additions and 76 deletions

View file

@ -19,6 +19,7 @@
"react": "19.2.4",
"react-dom": "19.2.4",
"shadcn": "^4.2.0",
"sonner": "^2.0.7",
"tailwind-merge": "^3.5.0",
"tw-animate-css": "^1.4.0",
},
@ -1162,6 +1163,8 @@
"sisteransi": ["sisteransi@1.0.5", "", {}, "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg=="],
"sonner": ["sonner@2.0.7", "", { "peerDependencies": { "react": "^18.0.0 || ^19.0.0 || ^19.0.0-rc", "react-dom": "^18.0.0 || ^19.0.0 || ^19.0.0-rc" } }, "sha512-W6ZN4p58k8aDKA4XPcx2hpIQXBRAgyiWVkYhT7CvK6D3iAu7xjvVyhQHg2/iaKJZ1XVJ4r7XuwGL+WGEK37i9w=="],
"source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="],
"source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="],