Skip to content

Where people and agents ship software together. The open-source git platform for the whole job: issues, agents, checks and deploys to the edge.

32 linesCodeBlameRaw
1import { ShieldAlert } from "lucide-react";
2import { Link } from "react-router";
3
4import type { PolicyHold } from "@g1t/contracts";
5
6/**
7 * The notice across the top for someone a workspace holds out until they
8 * meet its policy, such as one that requires two-factor authentication or
9 * single sign-on: they keep their place and cannot use it until they do.
10 */
11export function PolicyNotice({ held }: { held: PolicyHold[] }) {
12 if (held.length === 0) return null;
13 const twoFactor = held.some((hold) => hold.gap === "two_factor");
14 // Single sign-on is one workspace's at a time: the first that asks for it.
15 const sso = held.find((hold) => hold.gap === "sso");
16 return (
17 <div role="alert" className="flex flex-wrap items-center justify-center gap-x-3 gap-y-1 border-b border-warn/30 bg-warn/10 px-4 py-2 text-center text-sm">
18 <ShieldAlert size={15} aria-hidden="true" className="hidden shrink-0 text-warn sm:block" />
19 <span>{held.map((hold) => hold.reason).join(" ")}</span>
20 {twoFactor && (
21 <Link to="/settings/two-factor" className="font-medium underline underline-offset-4">
22 Turn on two-factor authentication
23 </Link>
24 )}
25 {sso && (
26 <Link to={`/auth/sso/${sso.slug}?next=${encodeURIComponent(`/${sso.slug}`)}`} className="font-medium underline underline-offset-4">
27 Sign in with {sso.slug}&apos;s single sign-on
28 </Link>
29 )}
30 </div>
31 );
32}