({
+ queryKey: ['syncStatus', lastSyncedUid],
+ queryFn: () => fetchSyncStatus(lastSyncedUid!),
+ enabled: lastSyncedUid !== null,
+ // refetchInterval: active (3000ms) only while pending; disabled once terminal
+ refetchInterval: (query) => {
+ const status = query.state.data?.status
+ return status === 'pending' || status === undefined ? 3000 : false
+ },
+ staleTime: 0,
+ gcTime: 0,
+ })
+
+ const status = data?.status
+ const isConflict = status === 'failed' && data?.error?.includes('412')
+ const isPersistent = status === 'failed' || status === 'dead'
+
+ // Invalidate events on done OR on conflict (D-06/D-08)
+ useEffect(() => {
+ if (!lastSyncedUid) return
+ if (invalidatedRef.current === lastSyncedUid) return
+
+ if (status === 'done' || isConflict) {
+ invalidatedRef.current = lastSyncedUid
+ void queryClient.invalidateQueries({ queryKey: ['events'] })
+ }
+ }, [status, isConflict, lastSyncedUid, queryClient])
+
+ // Auto-dismiss after 2s on done
+ useEffect(() => {
+ if (status !== 'done') return
+ const timer = setTimeout(() => {
+ setLastSyncedUid(null)
+ }, 2000)
+ return () => clearTimeout(timer)
+ }, [status, setLastSyncedUid])
+
+ // Reset invalidation guard when uid changes (new write)
+ useEffect(() => {
+ if (lastSyncedUid === null) {
+ invalidatedRef.current = null
+ }
+ }, [lastSyncedUid])
+
+ // Nothing to show
+ if (!lastSyncedUid || (!isLoading && !data)) return null
+
+ // ── State-specific content ─────────────────────────────────────────────────
+
+ const dismiss = () => setLastSyncedUid(null)
+
+ // Determine ARIA role: status (polite) for pending/done; alert (assertive) for failed/dead
+ const ariaRole: 'status' | 'alert' =
+ status === 'failed' || status === 'dead' ? 'alert' : 'status'
+
+ // Toast copy (exact strings from UI-SPEC §Copywriting)
+ let copy: string
+ let icon: React.ReactNode
+
+ if (status === 'done') {
+ copy = 'Saved'
+ icon = (
+
+ )
+ } else if (isConflict) {
+ copy = 'This event changed elsewhere — review the latest version'
+ icon = (
+
+ )
+ } else if (status === 'failed') {
+ copy = "Didn't save. Try again."
+ icon = (
+
+ )
+ } else if (status === 'dead') {
+ copy = 'Not saved. Check your connection.'
+ icon = (
+
+ )
+ } else {
+ // pending (or loading)
+ copy = 'Syncing…'
+ icon = (
+
+ )
+ }
+
+ return (
+
+ {icon}
+ {/* Plain text — XSS guard */}
+ {copy}
+ {/* Dismiss button — only for persistent states (failed/dead) */}
+ {isPersistent && (
+
+ )}
+
+ )
+}