45 lines
1.5 KiB
TypeScript
45 lines
1.5 KiB
TypeScript
// SPDX-License-Identifier: LicenseRef-ConusAI-Template-1.0
|
|
// The entry page: the organizations this user belongs to, or the way in (spec §7).
|
|
|
|
import { meGet } from "@conusai-kit/tenancy"
|
|
import type { ReactElement } from "react"
|
|
import { orFallback } from "../src/server/guard"
|
|
import { pageContext } from "../src/server/page"
|
|
|
|
export const dynamic = "force-dynamic"
|
|
|
|
export default async function Home(): Promise<ReactElement> {
|
|
const { caller, signedIn, i18n, path } = await pageContext()
|
|
if (!signedIn) {
|
|
return (
|
|
<main>
|
|
<h1>{i18n.message("app.title")}</h1>
|
|
<p>{i18n.message("app.needsSignIn")}</p>
|
|
<a href="/auth/sign-in">{i18n.message("app.signIn")}</a>
|
|
</main>
|
|
)
|
|
}
|
|
|
|
// The typed in-process client: the contract decides the input and the output types, and the
|
|
// same procedure answers a browser, a CLI and a partner (spec §6.2).
|
|
const me = await orFallback(path, () => caller.call(meGet, undefined))
|
|
return (
|
|
<main>
|
|
<h1>{i18n.message("app.organizations")}</h1>
|
|
{me.organizations.length === 0 ? (
|
|
<p>{i18n.message("app.noOrganizations")}</p>
|
|
) : (
|
|
<ul>
|
|
{me.organizations.map((organization) => (
|
|
<li key={organization.slug}>
|
|
<a href={`/${organization.slug}`}>{organization.name}</a>{" "}
|
|
<span>{i18n.message(`roles.${organization.role}`)}</span>
|
|
</li>
|
|
))}
|
|
</ul>
|
|
)}
|
|
<a href="/onboarding">{i18n.message("app.createOrganization")}</a>
|
|
</main>
|
|
)
|
|
}
|