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 <noreply@anthropic.com>
This commit is contained in:
2025-11-12 07:54:51 +00:00
parent c50cf86263
commit 97f8aa5548
3 changed files with 39 additions and 10 deletions

View File

@@ -36,6 +36,8 @@ export function BibleReaderApp() {
const [booksLoading, setBooksLoading] = useState(true)
const [highlights, setHighlights] = useState<Map<string, BibleHighlight>>(new Map())
const syncManager = useRef<HighlightSyncManager | null>(null)
const [syncStatus, setSyncStatus] = useState<'synced' | 'syncing' | 'pending' | 'error'>('synced')
const [syncError, setSyncError] = useState<string | null>(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 */}

View File

@@ -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({
<Divider sx={{ my: 2 }} />
{syncStatus && (
<Box sx={{ mt: 2 }}>
<Typography variant="subtitle2" sx={{ mb: 1 }}>
Sync Status
</Typography>
<SyncStatusIndicator
status={syncStatus}
errorMessage={syncErrorMessage}
/>
</Box>
)}
<Typography variant="body2" color="textSecondary">
You can highlight the same verse multiple times with different colors.
</Typography>

View File

@@ -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}
/>
)}