import type { ReactNode } from "react";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import { CompanyPatternIcon } from "@/components/CompanyPatternIcon";
import { cn } from "@/lib/utils";
import {
ArrowRight,
Check,
Clock3,
ExternalLink,
FlaskConical,
KeyRound,
Link2,
Loader2,
MailPlus,
ShieldCheck,
UserPlus,
Users,
} from "lucide-react";
const inviteRoleOptions = [
{
value: "viewer",
label: "Viewer",
description: "Can view company work and follow along without operational permissions.",
gets: "No built-in grants.",
},
{
value: "operator",
label: "Operator",
description: "Recommended for people who need to help run work without managing access.",
gets: "Can assign tasks.",
},
{
value: "admin",
label: "Admin",
description: "Recommended for operators who need to invite people, create agents, and approve joins.",
gets: "Can create agents, invite users, assign tasks, and approve join requests.",
},
{
value: "owner",
label: "Owner",
description: "Full company access, including membership and permission management.",
gets: "Everything in Admin, plus managing members and permission grants.",
},
] as const;
const inviteHistory = [
{
id: "invite-active",
state: "Active",
humanRole: "operator",
invitedBy: "Board User 25",
email: "board25@paperclip.local",
createdAt: "Apr 25, 2026, 9:00 AM",
action: "Revoke",
relatedLabel: "Review request",
},
{
id: "invite-accepted",
state: "Accepted",
humanRole: "viewer",
invitedBy: "Board User 24",
email: "board24@paperclip.local",
createdAt: "Apr 24, 2026, 8:15 AM",
action: "Inactive",
relatedLabel: "—",
},
{
id: "invite-revoked",
state: "Revoked",
humanRole: "admin",
invitedBy: "Board User 20",
email: "board20@paperclip.local",
createdAt: "Apr 20, 2026, 2:45 PM",
action: "Inactive",
relatedLabel: "—",
},
{
id: "invite-expired",
state: "Expired",
humanRole: "owner",
invitedBy: "Board User 19",
email: "board19@paperclip.local",
createdAt: "Apr 19, 2026, 7:10 PM",
action: "Inactive",
relatedLabel: "—",
},
] as const;
const fieldClassName =
"w-full border border-zinc-800 bg-zinc-950 px-3 py-2 text-sm text-zinc-100 outline-none focus:border-zinc-500";
const panelClassName = "border border-zinc-800 bg-zinc-950/95 p-6";
function LabSection({
eyebrow,
title,
description,
accentClassName,
children,
}: {
eyebrow: string;
title: string;
description: string;
accentClassName?: string;
children: ReactNode;
}) {
return (
{description}{title}
You've been invited to join Paperclip
{description}
{inviteMessage}
{mode === "sign_up" ? "Start with a Paperclip account. After that, you'll come right back here to accept the invite for Acme Robotics." : "Use the Paperclip account that already matches this invite. If you do not have one yet, switch back to create account."}
{mode === "sign_up" ? "Already signed up before? Use the existing-account option instead so the invite lands on the right Paperclip user." : "No account yet? Switch back to create account so you can accept the invite with a new login."}
This invite will create an approval request for a new agent in Acme Robotics.
{autoAccept ? "Submitting your join request for Acme Robotics." : isCurrentMember ? "This account already belongs to Acme Robotics." : "This will submit or complete your join request for Acme Robotics."}
{error}
: null} {autoAccept ? ({description}
{joinedNow ? ( ) : ( <>Approval page
Company Settings → AccessRefresh this page after you've been approved — you'll be redirected automatically.
> )} {claimSecret ? ({mode === "sign_in" ? "Use your email and password to access this instance." : "Create an account for this instance. Email confirmation is not required in v1."}
{error}
: null}This frame mirrors the production auth surface so spacing, label density, button treatments, and desktop composition are easy to compare.
| State | Role | Invited by | Created | Join request | Action |
|---|---|---|---|---|---|
| {invite.state} | {invite.humanRole} |
{invite.invitedBy}
{invite.email}
|
{invite.createdAt} | {invite.relatedLabel === "Review request" ? ( {invite.relatedLabel} ) : ( {invite.relatedLabel} )} | {invite.action === "Revoke" ? ( ) : ( Inactive )} |
This page collects the current invite landing, signup, approval-result, and company invite-management states in one place so styling changes can be reviewed without recreating each backend condition by hand.