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
@@ -41,11 +41,9 @@ function sendWsCommand(
return false;
}
export function useAudioTransmit(
socketRef: {
readonly current: WebSocket | null;
},
): {
export function useAudioTransmit(socketRef: {
readonly current: WebSocket | null;
}): {
isStreaming: boolean;
micError: string | null;
micLevel: number;
@@ -195,5 +193,14 @@ export function useAudioTransmit(
}
}, [isStreaming, startTransmit, stopTransmit, start]);
return { isStreaming, micError, micLevel, toggle, stopTransmit, startTransmit, stop, start };
return {
isStreaming,
micError,
micLevel,
toggle,
stopTransmit,
startTransmit,
stop,
start,
};
}