Turnpike/frontend/src/components/SyncStatus.svelte
Pen Anderson d05b8dc7e0 Created Turnpike, event attendee and volunteer management
Built after prototype, Traverse, an attendee and volunteer list
maintainer.
2026-03-03 11:27:07 -06:00

46 lines
1.3 KiB
Svelte

<script>
import { onMount, onDestroy } from 'svelte'
import { getLastSync } from '../db.js'
import { syncPull } from '../sync.js'
let online = $state(navigator.onLine)
let syncing = $state(false)
let lastSync = $state('')
async function refresh() {
lastSync = await getLastSync()
}
async function manualSync() {
syncing = true
await syncPull()
await refresh()
syncing = false
}
function onOnline() { online = true; manualSync() }
function onOffline() { online = false }
onMount(() => {
refresh()
window.addEventListener('online', onOnline)
window.addEventListener('offline', onOffline)
})
onDestroy(() => {
window.removeEventListener('online', onOnline)
window.removeEventListener('offline', onOffline)
})
const dotClass = $derived(syncing ? 'syncing' : online ? 'online' : 'offline')
const label = $derived(syncing ? 'Syncing…' : online ? 'Online' : 'Offline')
const lastSyncLabel = $derived(lastSync ? new Date(lastSync).toLocaleTimeString() : 'Never')
</script>
<div class="sync-bar">
<div class="sync-dot {dotClass}"></div>
<span>{label}</span>
<span class="text-muted" style="margin-left:auto;font-size:0.72rem">Last sync: {lastSyncLabel}</span>
{#if online && !syncing}
<button class="btn btn-ghost btn-sm" onclick={manualSync}>↻</button>
{/if}
</div>