Skip to content

g1t/apps/web/app/routes/workspace/soon.tsx

47 lines1,985 bytesCodeBlame
1import { data, redirect } from "react-router";
2
3import type { Route } from "./+types/soon";
4import { page } from "../../lib/meta";
5import { roadmapItem } from "../../lib/roadmap";
6import { projects } from "../../lib/services.server";
7import { getViewer } from "../../lib/session.server";
8import { workspaceRedirect } from "../../lib/workspace-nav";
9import { SoonView } from "../repo/soon";
10
11export function meta({ params, ...args }: Route.MetaArgs) {
12 const item = roadmapItem(params.feature);
13 return page(args, {
14 title: `${item?.title ?? "Soon"} · ${params.owner} · g1t`,
15 description: item ? `Soon on g1t: ${item.summary}` : null,
16 version: item ? [item.title, item.summary] : undefined,
17 });
18}
19
20export async function loader({ params, context, request }: Route.LoaderArgs) {
21 // Teams and Insights are tabs of the workspace's page now.
22 const moved = workspaceRedirect(new URL(request.url).pathname);
23 if (moved) throw redirect(moved, 301);
24 const item = roadmapItem(params.feature);
25 // Only what spans projects lives under the workspace.
26 if (!item || item.section !== "Workspace") throw data(null, { status: 404 });
27 // What to use until then lives in each project, so list the projects.
28 const listed = item.today ? await projects.list(params.owner, getViewer(context)).catch(() => null) : null;
29 const inProjects = listed?.ok
30 ? listed.value.map((project) => ({ name: project.name || project.slug, to: `/${project.workspace}/${project.slug}` }))
31 : [];
32 return { item, inProjects };
33}
34
35/** What a workspace will have across its projects: boards, the roadmap, packages, the fleet. */
36export default function WorkspaceSoon({ loaderData, params }: Route.ComponentProps) {
37 return (
38 <div className="mx-auto max-w-5xl px-4 py-10 sm:px-8">
39 <SoonView
40 item={loaderData.item}
41 base={`/${params.owner}/-`}
42 inProjects={loaderData.inProjects}
43 newProject={`/new?workspace=${params.owner}`}
44 />
45 </div>
46 );
47}