From 97f8aa554810f9f6a483879bd6d42e1b5854680d Mon Sep 17 00:00:00 2001 From: Andrei Date: Wed, 12 Nov 2025 07:54:51 +0000 Subject: [PATCH] feat: integrate sync status indicator into highlights panel - Updated HighlightsTab to accept syncStatus and syncErrorMessage props - Added SyncStatusIndicator component import and display in highlights panel - Enhanced BibleReaderApp with sync status tracking state (synced/syncing/pending/error) - Modified performSync function to update sync status based on result - Updated VersDetailsPanel to pass sync status props through to HighlightsTab - Sync status now visible to users in the Highlights tab with real-time updates Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- components/bible/bible-reader-app.tsx | 24 +++++++++++++++--------- components/bible/highlights-tab.tsx | 19 ++++++++++++++++++- components/bible/verse-details-panel.tsx | 6 ++++++ 3 files changed, 39 insertions(+), 10 deletions(-) diff --git a/components/bible/bible-reader-app.tsx b/components/bible/bible-reader-app.tsx index 396cd5b..c911d6d 100644 --- a/components/bible/bible-reader-app.tsx +++ b/components/bible/bible-reader-app.tsx @@ -36,6 +36,8 @@ export function BibleReaderApp() { const [booksLoading, setBooksLoading] = useState(true) const [highlights, setHighlights] = useState>(new Map()) const syncManager = useRef(null) + const [syncStatus, setSyncStatus] = useState<'synced' | 'syncing' | 'pending' | 'error'>('synced') + const [syncError, setSyncError] = useState(null) // Load books on mount or when locale changes useEffect(() => { @@ -281,17 +283,19 @@ export function BibleReaderApp() { if (!syncManager.current) return try { - const pending = await syncManager.current.getPendingSyncItems() - if (pending.length === 0) return + setSyncStatus('syncing') + const result = await syncManager.current.performSync() - await syncManager.current.markSyncing(pending.map(h => h.id)) - - // TODO: POST to /api/highlights/bulk in Phase 2.1B - - await syncManager.current.markSynced(pending.map(h => h.id)) + if (result.errors > 0) { + setSyncStatus('error') + setSyncError(`Failed to sync ${result.errors} highlights`) + } else { + setSyncStatus('synced') + setSyncError(null) + } } catch (error) { - console.error('Sync failed:', error) - // Mark items with error status + setSyncStatus('error') + setSyncError(error instanceof Error ? error.message : 'Unknown error') } } @@ -370,6 +374,8 @@ export function BibleReaderApp() { onHighlightVerse={handleHighlightVerse} onChangeHighlightColor={handleChangeHighlightColor} onRemoveHighlight={handleRemoveHighlight} + syncStatus={syncStatus} + syncErrorMessage={syncError || undefined} /> {/* Settings panel */} diff --git a/components/bible/highlights-tab.tsx b/components/bible/highlights-tab.tsx index ff91040..bac57b4 100644 --- a/components/bible/highlights-tab.tsx +++ b/components/bible/highlights-tab.tsx @@ -1,6 +1,7 @@ 'use client' import { Box, Button, Typography, Divider } from '@mui/material' import { BibleVerse, HighlightColor } from '@/types' +import { SyncStatusIndicator } from './sync-status-indicator' const HIGHLIGHT_COLORS: HighlightColor[] = ['yellow', 'orange', 'pink', 'blue'] @@ -17,6 +18,8 @@ interface HighlightsTabProps { currentColor: HighlightColor | null onToggleHighlight: () => void onColorChange: (color: HighlightColor) => void + syncStatus?: 'synced' | 'syncing' | 'pending' | 'error' + syncErrorMessage?: string } export function HighlightsTab({ @@ -24,7 +27,9 @@ export function HighlightsTab({ isHighlighted, currentColor, onToggleHighlight, - onColorChange + onColorChange, + syncStatus, + syncErrorMessage }: HighlightsTabProps) { if (!verse) return null @@ -80,6 +85,18 @@ export function HighlightsTab({ + {syncStatus && ( + + + Sync Status + + + + )} + You can highlight the same verse multiple times with different colors. diff --git a/components/bible/verse-details-panel.tsx b/components/bible/verse-details-panel.tsx index 543baaa..0cdf2ba 100644 --- a/components/bible/verse-details-panel.tsx +++ b/components/bible/verse-details-panel.tsx @@ -17,6 +17,8 @@ interface VersDetailsPanelProps { onHighlightVerse?: (color: HighlightColor) => void onChangeHighlightColor?: (color: HighlightColor) => void onRemoveHighlight?: () => void + syncStatus?: 'synced' | 'syncing' | 'pending' | 'error' + syncErrorMessage?: string } export function VersDetailsPanel({ @@ -31,6 +33,8 @@ export function VersDetailsPanel({ onHighlightVerse, onChangeHighlightColor, onRemoveHighlight, + syncStatus, + syncErrorMessage, }: VersDetailsPanelProps) { const theme = useTheme() const isMobile = useMediaQuery(theme.breakpoints.down('sm')) @@ -141,6 +145,8 @@ export function VersDetailsPanel({ } }} onColorChange={(color) => onChangeHighlightColor?.(color)} + syncStatus={syncStatus} + syncErrorMessage={syncErrorMessage} /> )}