import { useEffect, useRef, useState } from "react"; import { useNavigate, useParams } from "react-router-dom"; import { useAuth } from "../App"; import { Check, Logo, Spinner } from "../components/icons"; import { Button, InlineAlert } from "../components/ui"; import { ApiError, api, session } from "../lib/client"; import type { Workspace } from "../lib/types"; /** 邀请链接落地页:/join/:wsId/:code。未登录先去登录,登录后再回来。 */ export function JoinPage() { const { wsId, code } = useParams<{ wsId: string; code: string }>(); const { user, loading, reload } = useAuth(); const navigate = useNavigate(); const [message, setMessage] = useState("正在加入工作区…"); const [done, setDone] = useState(false); const [failed, setFailed] = useState(false); const started = useRef(false); useEffect(() => { if (loading) return; if (!session.access) { navigate(`/login?next=${encodeURIComponent(`/join/${wsId}/${code}`)}`, { replace: true }); return; } if (!user || started.current || !wsId || !code) return; started.current = true; void (async () => { try { const ws = await api.post(`/workspaces/${wsId}/join`, { code }); await reload(); setDone(true); setMessage(`已加入「${ws.name}」,正在跳转…`); window.setTimeout(() => navigate(`/w/${wsId}`, { replace: true }), 700); } catch (err) { setFailed(true); setMessage(err instanceof ApiError ? err.message : "加入失败"); } })(); }, [loading, user, wsId, code, navigate, reload]); return (
{failed ? ( ! ) : done ? ( ) : ( )}

{message}

{failed ? "链接可能已失效,或你已经加入过了。" : "邀请码一次有效"}

{failed && ( <>
可以把邀请码发给同事,让他重新生成一条链接。
)}
); }