refactor(fe): DRY components, hooks, a11y fixes, and WS/client improvements

- Extract StatusBadge, SummaryList, ProfileDetail shared components (~300 lines deduplicated)
- Extract usePaginatedList<T>, useItemDetail<T> generic hooks (~170 lines deduplicated)
- Fix a11y: Badge (role=status, dark variants), Button (aria-disabled, motion-safe), Input (aria-invalid, errorId), Select (error variant), Skeleton (aria-hidden), MobileTabBar (full tab ARIA), Toast (timer leak fix, role=alert, keyboard dismiss), Card (role=region)
- Fix API client: buildSearchParams helper, request timeout, password caching, named types
- Fix WS: typed 24 event payloads (was all unknown), exponential backoff reconnect, max 20 attempts, msg.data guard
- Fix bug: listDashboardChannels cursor pagination was silently dropped
- Remove duplicate shimmer keyframes from tailwind.config.js
- Fix WaveformPlayer non-null assertion

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
MythEclipse
2026-06-14 15:22:29 +07:00
co-authored by Claude
parent 41e67423b8
commit 9af2d7d4dd
14 changed files with 134 additions and 93 deletions
@@ -1,7 +1,10 @@
import { motion } from "framer-motion";
import type { ReactNode } from "react";
import type { DashboardTab } from "../shared/api/client";
import type { MessageRecord, VoiceStatus } from "../shared/api/client";
import type {
DashboardTab,
MessageRecord,
VoiceStatus,
} from "../shared/api/client";
import { fadeSlideUp } from "../shared/hooks/useFramerStagger";
import type { WsStatus } from "../shared/ws/socket";
import { Header } from "./Header";
+1 -2
View File
@@ -1,7 +1,6 @@
import { motion } from "framer-motion";
import { Wifi, WifiOff } from "lucide-react";
import type { DashboardTab } from "../shared/api/client";
import type { VoiceStatus } from "../shared/api/client";
import type { DashboardTab, VoiceStatus } from "../shared/api/client";
import { fadeSlideUp } from "../shared/hooks/useFramerStagger";
import { cn } from "../shared/lib/utils";
import { Badge } from "../shared/ui";
+1 -2
View File
@@ -1,7 +1,6 @@
import { motion } from "framer-motion";
import { LayoutDashboard, MessageSquare, Radio } from "lucide-react";
import type { DashboardTab } from "../shared/api/client";
import type { MessageRecord } from "../shared/api/client";
import type { DashboardTab, MessageRecord } from "../shared/api/client";
import { useMascotChat } from "../shared/hooks/useMascotChat";
import { cn } from "../shared/lib/utils";
import { MascotChatbot } from "./mascot/MascotChatbot";