import { useEffect, useState } from "react"; import { useNavigate } from "react-router-dom"; import { useAuth } from "../App"; import { ArrowRight, ChevronRight, Plus } from "../components/icons"; import { SideRail } from "../components/SideRail"; import { Button, EmptyState, Field, InlineAlert } from "../components/ui"; import { ApiError, api } from "../lib/client"; import type { Workspace } from "../lib/types"; function roleLabel(role: string): string { return { owner: "所有者", admin: "管理员", member: "成员", guest: "访客" }[role] ?? role; } function greeting() { const h = new Date().getHours(); if (h < 6) return "夜深了"; if (h < 11) return "早上好"; if (h < 14) return "中午好"; if (h < 18) return "下午好"; return "晚上好"; } /** * 首页 = 工作区总览。 * * 壳和工作区里完全一样(同样的侧栏、同样的通栏内容区), * 这样"点进工作区"只是换内容,宽度和导航位置都不跳。 */ export function HomePage() { const { user, workspaces, loading, reload } = useAuth(); const navigate = useNavigate(); const [name, setName] = useState(""); const [creating, setCreating] = useState(false); const [error, setError] = useState(null); const [busy, setBusy] = useState(false); useEffect(() => { if (!loading && !user) navigate("/login", { replace: true }); }, [loading, user, navigate]); async function createWorkspace(event: React.FormEvent) { event.preventDefault(); if (!name.trim()) return; setBusy(true); setError(null); try { const ws = await api.post("/workspaces", { name: name.trim() }); setName(""); setCreating(false); await reload(); navigate(`/w/${ws.id}`); } catch (err) { setError(err instanceof ApiError ? err.message : "创建失败"); } finally { setBusy(false); } } return (

{new Date().toLocaleDateString("zh-CN", { month: "long", day: "numeric", weekday: "long", })}

{greeting()},{user?.nickname ?? ""}

选一个工作区继续。任务、工单、知识都在里面,他们是同一件事的三个阶段。

我的工作区

{workspaces.length} 个 {!creating ? ( ) : null}
{loading ? (
{[0, 1, 2].map((i) => (
))}
) : (
{workspaces.map((ws) => ( ))} {creating ? (
新建工作区
setName(e.target.value)} /> {error && {error}}
) : ( )} {workspaces.length === 0 && !creating ? (
} title="还没有工作区" hint="个人用也一样:先建一个,把「任务」放进去。需要别人帮忙时再升级成工单。" />
) : null}
)}

收到邀请链接(/join/…)直接打开即可加入,不需要别人手动拉你。

); }