Frame

tcmts.share.Frame · #nunyzhce · term · runs on the server

uses process

Every page's frame: the project's name, the finder, who's signed in, and the tabs with their counts. On a private server, with no token, it's the sign-in page instead. An app showing these pages as its own sets pageFrame.

import { at, NavTabs, pageFrame, projectNow, SearchBox, shareNow, SignIn, UserMenu } from "#codebase/tcmts/share";
import type { Tab } from "#codebase/tcmts/share";
import type { ReactNode } from "react";
import { Link } from "react-aria-components";

export function Frame({
  tab,
  title,
  children,
  always,
}: {
  tab: Tab | "";
  title: string;
  children: ReactNode;
  always?: boolean;
}) {
  if (pageFrame.current) return pageFrame.current({ tab, title, children });
  const s = shareNow();
  const project = projectNow(s);
  const open = s.cb.store.contributions("open").length;
  const tabs: { id: Tab; label: string; href: string; count?: number }[] = [
    { id: "code", label: "Code", href: at("/") },
    {
      id: "contributions",
      label: "Contributions",
      href: at("/contributions"),
      count: open || undefined,
    },
    { id: "history", label: "History", href: at("/history") },
    {
      id: "branches",
      label: "Branches",
      href: at("/branches"),
      count: s.cb.store.branches().length || undefined,
    },
    {
      id: "releases",
      label: "Releases",
      href: at("/releases"),
      count: s.cb.store.releases().length || undefined,
    },
    { id: "people", label: "People", href: at("/people") },
  ];
  const who =
    s.caller.role === "reader" ? (
      <Link
        className="who"
        href={at(
          `/sign-in?then=${encodeURIComponent(s.url.pathname.slice(at("").length) + s.url.search)}`,
        )}
      >
        Sign in
      </Link>
    ) : (
      <UserMenu
        who={s.caller.role === "contributor" ? `@${s.caller.handle}` : "the maintainer"}
        canSignOut={s.caller.role === "contributor" || !!process.env.TCM_SHARE_TOKEN}
      />
    );
  return (
    <>
      <title>{`${title} · ${project.name}`}</title>
      <header className="app">
        <div className="wrap">
          <div className="bar1">
            <a className="crumb" href={at("/")}>
              <b>{project.name}</b>
            </a>
            <span className="pill">{s.isPublic ? "Public" : "Private"}</span>
            {s.signedIn ? <SearchBox /> : <span style={{ flex: 1 }} />}
            {who}
          </div>
          {s.signedIn && <NavTabs label="Project" selected={tab} tabs={tabs} />}
        </div>
      </header>
      {s.signedIn || always ? (
        children
      ) : (
        <SignIn then={s.url.pathname.slice(at("").length) + s.url.search} />
      )}
    </>
  );
}

uses

used by