Files

54 lines
2.1 KiB
TypeScript

// SPDX-License-Identifier: LicenseRef-ConusAI-Template-1.0
// A project's home: what it is, and the pages of the modules that work in it (spec §3.1, §4.1).
// The entries come from the modules' manifests (src/ui/projects.ts), so a module added tomorrow
// appears here with no edit to this file.
import { projectGet, workspaceList } from "@conusai-kit/tenancy"
import type { ReactElement } from "react"
import { orFallback } from "../../../../src/server/guard"
import { pageContext } from "../../../../src/server/page"
import { Breadcrumb } from "../../../../src/ui/breadcrumb"
import { PROJECT_ENTRIES, projectHref } from "../../../../src/ui/projects"
export const dynamic = "force-dynamic"
export default async function ProjectHome({
params,
}: {
params: Promise<{ org: string; workspace: string; project: string }>
}): Promise<ReactElement> {
const { org, workspace, project } = await params
const { caller, i18n, path } = await pageContext()
const { found, workspaceName } = await orFallback(path, async () => {
const [found, { workspaces }] = await Promise.all([
caller.call(projectGet, { org, workspace, project }),
caller.call(workspaceList, { org }),
])
return { found, workspaceName: workspaces.find((entry) => entry.slug === workspace)?.name ?? workspace }
})
return (
<>
<Breadcrumb
label={i18n.message("shell.breadcrumb")}
crumbs={[
{ text: i18n.message("app.workspaces"), href: `/${org}/workspaces` },
{ text: workspaceName, href: `/${org}/${workspace}` },
{ text: found.name, href: projectHref(org, workspace, project) },
]}
/>
<h1>{i18n.message("project.title", { name: found.name })}</h1>
<p>{i18n.message("project.module", { module: found.moduleKey })}</p>
{found.archived ? <p role="status">{i18n.message("project.archived")}</p> : null}
<h2>{i18n.message("project.work")}</h2>
<ul>
{PROJECT_ENTRIES.map((entry) => (
<li key={entry.href}>
<a href={projectHref(org, workspace, project, entry)}>{i18n.message(entry.label)}</a>
</li>
))}
</ul>
</>
)
}