Same core, React bindings
The library is a plain async function with no framework dependency. A
binding owns three things: the responder list the page renders (resolved
from a policy), the one call, and its state. This page's
useCheckin hook is all of it; the
Angular example is the same as a service.
The whole binding
export function useCheckin(request, policy) {
const [responders, setResponders] = useState([]);
const [state, setState] = useState({ status: "idle" });
// who may answer in this browser — availability and the default come back in the list
useEffect(() => { void resolveResponders(policy).then(setResponders); }, [policy]);
const start = useCallback(async (responder = responders.find((r) => r.isDefault)) => {
setState({ status: "waiting" });
try {
const response = await requestCheckin(request, {
getCredential: credentialGetterFor(responder, { origin: policy.origin }),
});
setState({ status: "done", response });
} catch (e) {
setState(e instanceof CheckinFlowError && e.outcome.status === "declined"
? { status: "declined" }
: { status: "error", error: String(e) });
}
}, [request, policy, responders]);
return { ...state, responders, start };
}
// …and the component renders the list: one button per responder, the default leading
{responders.map((r) => ( className={r.isDefault ? "smart-btn primary" : "smart-btn"}
disabled={!r.available} title={r.reason} onClick={() => start(r)}>
{r.name}
</button>
))}