From 0c042ac89fc0822fcbe09c48702857faa5494ae1 Mon Sep 17 00:00:00 2001 From: nsfisis Date: Sun, 7 Dec 2025 23:34:03 +0900 Subject: feat(client): add sync status indicator component MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add SyncStatusIndicator component to display current sync state in the UI header. The component shows online/offline status, syncing progress, pending changes count, and sync errors. - Create SyncProvider context to wrap SyncManager for React components - Add SyncStatusIndicator component with visual status indicators - Integrate indicator into HomePage header - Add comprehensive tests for SyncStatusIndicator and SyncProvider - Update existing tests to include SyncProvider wrapper 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- src/client/components/SyncStatusIndicator.tsx | 82 +++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 src/client/components/SyncStatusIndicator.tsx (limited to 'src/client/components/SyncStatusIndicator.tsx') diff --git a/src/client/components/SyncStatusIndicator.tsx b/src/client/components/SyncStatusIndicator.tsx new file mode 100644 index 0000000..23e3ec6 --- /dev/null +++ b/src/client/components/SyncStatusIndicator.tsx @@ -0,0 +1,82 @@ +import { useSync } from "../stores"; +import { SyncStatus } from "../sync"; + +export function SyncStatusIndicator() { + const { isOnline, isSyncing, pendingCount, lastError, status } = useSync(); + + const getStatusText = (): string => { + if (!isOnline) { + return "Offline"; + } + if (isSyncing) { + return "Syncing..."; + } + if (status === SyncStatus.Error && lastError) { + return "Sync error"; + } + if (pendingCount > 0) { + return `${pendingCount} pending`; + } + return "Synced"; + }; + + const getStatusColor = (): string => { + if (!isOnline) { + return "#6c757d"; // gray + } + if (isSyncing) { + return "#007bff"; // blue + } + if (status === SyncStatus.Error) { + return "#dc3545"; // red + } + if (pendingCount > 0) { + return "#ffc107"; // yellow + } + return "#28a745"; // green + }; + + const getStatusIcon = (): string => { + if (!isOnline) { + return "\u25CB"; // hollow circle + } + if (isSyncing) { + return "\u21BB"; // rotating arrows + } + if (status === SyncStatus.Error) { + return "\u2717"; // cross mark + } + if (pendingCount > 0) { + return "\u25D4"; // partial circle + } + return "\u2713"; // check mark + }; + + return ( +
+ + {getStatusText()} +
+ ); +} -- cgit v1.2.3-70-g09d2