// Гостевая страница /g/<токен>: имя → сессия гостя (без прав модератора) → звонок. import { useCallback, useEffect, useState } from "react"; import { api } from "./api"; import { CallWithSession } from "./Call"; import { Icon } from "./Icon"; const NAME_KEY = "calls_guest_name_v1"; export function GuestPage({ token }: { token: string }) { const sessionKey = "calls_guest_session_v1:" + token.slice(0, 12); const [state, setState] = useState<"checking" | "ok" | "bad">("checking"); const [name, setName] = useState(() => { try { return localStorage.getItem(NAME_KEY) ?? ""; } catch { return ""; } }); const [session, setSession] = useState(() => sessionStorage.getItem(sessionKey)); const [err, setErr] = useState(""); const [busy, setBusy] = useState(false); useEffect(() => { if (session) return; api.guestCheck(token).then(() => setState("ok")).catch(() => setState("bad")); }, [token, session]); const join = async () => { const n = name.trim(); if (!n) { setErr("Вкажіть ім'я"); return; } setBusy(true); setErr(""); try { const r = await api.guestJoin(token, n); try { localStorage.setItem(NAME_KEY, n); } catch { /* без сховища */ } sessionStorage.setItem(sessionKey, r.session); setSession(r.session); } catch (e) { if ((e as { status?: number }).status === 404) setState("bad"); else setErr((e as Error).message); } finally { setBusy(false); } }; const lost = useCallback((m: string) => { sessionStorage.removeItem(sessionKey); setSession(null); setErr(m); }, [sessionKey]); if (session) return ; return (

Дзвінок

Запрошення від CRM Tvorymo
{state === "checking" &&
Перевірка посилання…
} {state === "bad" &&
Посилання недійсне або застаріло.Попросіть того, хто вас запросив, надіслати нове посилання.
} {state === "ok" &&
setName(e.target.value)} onKeyDown={(e) => { if (e.key === "Enter") void join(); }} />
{err &&
{err}
}
}
); }