AI insights now fetches the Claude API key from the central settings service instead of storing its own encrypted copy, so wages and other apps can share the same key. Also wires up the update-available banner using the existing version-check hook pattern. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
43 lines
1.1 KiB
TypeScript
43 lines
1.1 KiB
TypeScript
import { useEffect, useState } from 'react'
|
|
|
|
const POLL_MS = 2 * 60 * 1000
|
|
|
|
export function useVersionCheck(healthUrl: string) {
|
|
const [updateAvailable, setUpdateAvailable] = useState(false)
|
|
|
|
useEffect(() => {
|
|
let seenVersion: string | null = null
|
|
|
|
async function check() {
|
|
try {
|
|
const res = await fetch(healthUrl, { cache: 'no-store' })
|
|
if (!res.ok) return
|
|
const data = await res.json()
|
|
const v: string | undefined = data.version
|
|
if (!v) return
|
|
if (seenVersion === null) {
|
|
seenVersion = v
|
|
} else if (v !== seenVersion) {
|
|
setUpdateAvailable(true)
|
|
}
|
|
} catch {
|
|
// network error — skip silently
|
|
}
|
|
}
|
|
|
|
check()
|
|
const interval = setInterval(check, POLL_MS)
|
|
|
|
function onVisible() {
|
|
if (document.visibilityState === 'visible') check()
|
|
}
|
|
document.addEventListener('visibilitychange', onVisible)
|
|
|
|
return () => {
|
|
clearInterval(interval)
|
|
document.removeEventListener('visibilitychange', onVisible)
|
|
}
|
|
}, [healthUrl])
|
|
|
|
return updateAvailable
|
|
}
|