40 lines
1.4 KiB
TypeScript
40 lines
1.4 KiB
TypeScript
/* How many edit requests wait for an admin. The sidebar wears this number on
|
|
the door to the review desk, so the waiting pile shows without opening it.
|
|
Shared state rather than a ref: the sidebar draws the count, and the desk —
|
|
which already holds every request — lays the honest number on it each time
|
|
it loads or a request is decided. */
|
|
export function usePendingRequests() {
|
|
const api = `${useRuntimeConfig().public.apiBase}/api`
|
|
const { isAdmin, authHeaders } = useAuth()
|
|
|
|
const pending = useState<number>('proposals:pending', () => 0)
|
|
|
|
/* Ask the API how many wait. Only an admin is answered, so nobody else
|
|
carries a count — and a request that never got through (the backend is
|
|
restarting) leaves the last number standing rather than emptying the door. */
|
|
async function refresh() {
|
|
if (!isAdmin.value) {
|
|
pending.value = 0
|
|
return
|
|
}
|
|
try {
|
|
const { pending: waiting } = await $fetch<{ pending: number }>(
|
|
`${api}/admin/proposals/count`,
|
|
{ headers: authHeaders() }
|
|
)
|
|
pending.value = waiting
|
|
} catch {
|
|
/* keep what the door already said */
|
|
}
|
|
}
|
|
|
|
/* The desk counts its own loaded pile — same fetch that brought the requests
|
|
answers the door too, so approving or refusing keeps the number in step
|
|
without asking the API twice. */
|
|
function report(count: number) {
|
|
pending.value = count
|
|
}
|
|
|
|
return { pending, refresh, report }
|
|
}
|