mirror of
https://github.com/hanzo-apps/hanzo.ai.git
synced 2026-10-29 07:20:43 +00:00
130 lines
4.0 KiB
TypeScript
130 lines
4.0 KiB
TypeScript
'use client'
|
|
|
|
import { useCallback, useEffect, useMemo, useState } from 'react'
|
|
import { api } from '@hanzo/app/lib/api'
|
|
import { scope, superAdmin } from '@hanzo/app/lib/session'
|
|
import { mine, updateCode, type Referee } from '@/lib/hanzo/referrals'
|
|
import { ask, getLocalRequestedBetas, standing } from '@/lib/hanzo/beta'
|
|
import { board, github, listing, me as read, setListing, type Board, type Connection, type Listing, type Me } from '@/lib/hanzo/rewards'
|
|
|
|
/**
|
|
* Everything the portal's four steps read about the member, once: their link
|
|
* and who came through it, their points and place, the betas asked for and the
|
|
* flags the cloud holds for them, and the board. `signed`
|
|
* is a full session: nothing is read before it.
|
|
*
|
|
* Points, place and the board are the rewards ledger's (GET /v1/rewards/me and
|
|
* GET /v1/rewards): the same figures /leaderboard draws. Nothing here adds a
|
|
* point of its own.
|
|
*/
|
|
export function useStanding(signed: boolean) {
|
|
const [code, setCode] = useState('')
|
|
const [link, setLink] = useState('')
|
|
const [referred, setReferred] = useState(0)
|
|
const [referees, setReferees] = useState<Referee[]>([])
|
|
|
|
const [me, setMe] = useState<Me | null>(null)
|
|
const [gh, setGh] = useState<Connection | null>(null)
|
|
|
|
const [asked, setAsked] = useState<string[]>(getLocalRequestedBetas)
|
|
const [flags, setFlags] = useState<Record<string, boolean>>({})
|
|
|
|
const staff = useMemo(() => (signed ? superAdmin() : false), [signed])
|
|
const [ranked, setRanked] = useState<Board | null>(null)
|
|
const [listed, setListed] = useState<Listing | null>(null)
|
|
|
|
useEffect(() => {
|
|
if (!signed) return
|
|
let live = true
|
|
mine()
|
|
.then((r) => {
|
|
if (!live) return
|
|
if (r.code) {
|
|
setCode(r.code)
|
|
setLink(`https://hanzo.ai/beta?ref=${r.code}`)
|
|
} else if (r.link) setLink(r.link)
|
|
setReferred(r.counts?.total ?? 0)
|
|
if (Array.isArray(r.referrals)) setReferees(r.referrals)
|
|
})
|
|
.catch(() => {})
|
|
read().then((m) => live && setMe(m))
|
|
board().then((b) => live && setRanked(b))
|
|
listing().then((l) => live && setListed(l))
|
|
github().then((c) => live && setGh(c))
|
|
return () => {
|
|
live = false
|
|
}
|
|
}, [signed])
|
|
|
|
// The record and the flags, and any request made signed out, sent now.
|
|
useEffect(() => {
|
|
if (!signed) return
|
|
let live = true
|
|
Promise.all([
|
|
standing(),
|
|
fetch(`${api()}/v1/flag/platform`, { headers: scope() })
|
|
.then((r) => (r.ok ? (r.json() as Promise<{ flags?: Record<string, boolean> }>) : null))
|
|
.catch(() => null),
|
|
]).then(async ([st, f]) => {
|
|
if (!live) return
|
|
if (f?.flags) setFlags(f.flags)
|
|
const kept = getLocalRequestedBetas()
|
|
if (!st) {
|
|
if (kept.length) await ask(kept)
|
|
return
|
|
}
|
|
setAsked(Array.from(new Set([...st.betas, ...kept])))
|
|
const unsent = kept.filter((id) => !st.betas.includes(id))
|
|
if (unsent.length) {
|
|
const sent = await ask(unsent)
|
|
if (live && sent) setAsked(sent.betas)
|
|
}
|
|
})
|
|
return () => {
|
|
live = false
|
|
}
|
|
}, [signed])
|
|
|
|
/** Ask for betas: the rows say so at once, and the cloud's answer settles them. */
|
|
const request = useCallback(async (ids: string[]) => {
|
|
setAsked((now) => Array.from(new Set([...now, ...ids])))
|
|
const sent = await ask(ids)
|
|
if (sent) setAsked(sent.betas)
|
|
}, [])
|
|
|
|
const rename = useCallback(async (next: string) => {
|
|
const r = await updateCode(next)
|
|
const saved = r.code || next.toUpperCase()
|
|
setCode(saved)
|
|
setLink(`https://hanzo.ai/beta?ref=${saved}`)
|
|
return saved
|
|
}, [])
|
|
|
|
const show = useCallback(async (on: boolean) => {
|
|
const l = await setListing(on)
|
|
if (!l) return
|
|
setListed(l)
|
|
board().then(setRanked)
|
|
}, [])
|
|
|
|
return {
|
|
code,
|
|
link,
|
|
referred,
|
|
referees,
|
|
rename,
|
|
me,
|
|
place: me?.rank ?? 0,
|
|
of: me?.of ?? 0,
|
|
total: me?.points ?? 0,
|
|
github: gh,
|
|
asked,
|
|
request,
|
|
flags,
|
|
staff,
|
|
ranked,
|
|
listed,
|
|
show,
|
|
}
|
|
}
|