import { useState } from "react";
import {
BookOpen,
Bot,
Check,
ChevronDown,
CircleDot,
Command as CommandIcon,
DollarSign,
Hexagon,
History,
Inbox,
LayoutDashboard,
ListTodo,
Mail,
Plus,
Search,
Settings,
Target,
Trash2,
Upload,
User,
Zap,
} from "lucide-react";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { Input } from "@/components/ui/input";
import { Textarea } from "@/components/ui/textarea";
import { Checkbox } from "@/components/ui/checkbox";
import { Label } from "@/components/ui/label";
import { Separator } from "@/components/ui/separator";
import { Skeleton } from "@/components/ui/skeleton";
import { Tabs, TabsList, TabsTrigger, TabsContent } from "@/components/ui/tabs";
import {
Card,
CardHeader,
CardTitle,
CardDescription,
CardContent,
CardFooter,
} from "@/components/ui/card";
import {
Dialog,
DialogTrigger,
DialogContent,
DialogHeader,
DialogTitle,
DialogDescription,
DialogFooter,
} from "@/components/ui/dialog";
import {
Tooltip,
TooltipTrigger,
TooltipContent,
} from "@/components/ui/tooltip";
import {
Select,
SelectTrigger,
SelectValue,
SelectContent,
SelectItem,
} from "@/components/ui/select";
import {
DropdownMenu,
DropdownMenuTrigger,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuSeparator,
DropdownMenuCheckboxItem,
DropdownMenuShortcut,
} from "@/components/ui/dropdown-menu";
import {
Popover,
PopoverTrigger,
PopoverContent,
} from "@/components/ui/popover";
import {
Sheet,
SheetTrigger,
SheetContent,
SheetHeader,
SheetTitle,
SheetDescription,
SheetFooter,
} from "@/components/ui/sheet";
import {
Collapsible,
CollapsibleTrigger,
CollapsibleContent,
} from "@/components/ui/collapsible";
import { ScrollArea } from "@/components/ui/scroll-area";
import {
Command,
CommandInput,
CommandList,
CommandGroup,
CommandItem,
CommandEmpty,
CommandSeparator,
} from "@/components/ui/command";
import {
Breadcrumb,
BreadcrumbItem,
BreadcrumbLink,
BreadcrumbList,
BreadcrumbPage,
BreadcrumbSeparator,
} from "@/components/ui/breadcrumb";
import {
Avatar,
AvatarFallback,
AvatarGroup,
AvatarGroupCount,
} from "@/components/ui/avatar";
import { StatusBadge, AgentStatusBadge, AgentStatusCapsule } from "@/components/StatusBadge";
import { StatusIcon } from "@/components/StatusIcon";
import { PriorityIcon } from "@/components/PriorityIcon";
import { EntityRow } from "@/components/EntityRow";
import { EmptyState } from "@/components/EmptyState";
import { MetricCard } from "@/components/MetricCard";
import { FilterBar, type FilterValue } from "@/components/FilterBar";
import { InlineEditor } from "@/components/InlineEditor";
import { PageSkeleton } from "@/components/PageSkeleton";
import { Identity } from "@/components/Identity";
import { IssueReferencePill } from "@/components/IssueReferencePill";
import { MembershipAction } from "@/components/MembershipAction";
import { IssueOutputSection } from "@/components/issue-output/IssueOutputSection";
import {
EnvInputsList,
ExternalSourcesList,
RequiredSkillsList,
StepSkillPlan,
StepSourcePolicy,
TeamCard,
TeamHierarchyPreview,
TeamRow,
} from "@/pages/TeamCatalog";
import {
currentInstalledState,
onboardingTeams,
optionalTeam,
outOfDateInstalledState,
sampleSkillPreparations,
sampleTeam,
warnTeam,
} from "@/pages/TeamCatalog.fixtures";
import type { IssueWorkProduct } from "@paperclipai/shared";
/* ------------------------------------------------------------------ */
/* Sample data for the Issue Output surface showcase */
/* ------------------------------------------------------------------ */
function sampleOutput(
id: string,
attachmentId: string,
contentType: string,
filename: string,
opts: { byteSize: number; isPrimary?: boolean; createdAt: string },
): IssueWorkProduct {
const contentPath = `/api/attachments/${attachmentId}/content`;
return {
id,
companyId: "demo-company",
projectId: null,
issueId: "demo-issue",
executionWorkspaceId: null,
runtimeServiceId: null,
type: "artifact",
provider: "paperclip",
externalId: null,
title: filename,
url: null,
status: "active",
reviewState: "none",
isPrimary: Boolean(opts.isPrimary),
healthStatus: "unknown",
summary: null,
createdByRunId: null,
createdAt: new Date(opts.createdAt),
updatedAt: new Date(opts.createdAt),
metadata: {
attachmentId,
contentType,
byteSize: opts.byteSize,
contentPath,
openPath: contentPath,
downloadPath: `${contentPath}?download=1`,
originalFilename: filename,
},
} as IssueWorkProduct;
}
const DESIGN_GUIDE_OUTPUTS: IssueWorkProduct[] = [
sampleOutput("wp-vid", "aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa", "video/mp4", "q3-summary.mp4", {
byteSize: 19_293_798,
isPrimary: true,
createdAt: "2026-05-30T12:00:00Z",
}),
sampleOutput("wp-pdf", "bbbbbbbb-bbbb-4bbb-8bbb-bbbbbbbbbbbb", "application/pdf", "talking-points.pdf", {
byteSize: 421_888,
createdAt: "2026-05-30T11:52:00Z",
}),
];
const DESIGN_GUIDE_DEGRADED_OUTPUTS: IssueWorkProduct[] = [
{
...sampleOutput("wp-broken", "cccccccc-cccc-4ccc-8ccc-cccccccccccc", "video/mp4", "corrupt-output.mp4", {
byteSize: 0,
isPrimary: true,
createdAt: "2026-05-30T12:01:00Z",
}),
// Strip the path metadata so it fails the shared artifact schema.
metadata: { attachmentId: "cccccccc-cccc-4ccc-8ccc-cccccccccccc", contentType: "video/mp4" },
} as IssueWorkProduct,
];
/* ------------------------------------------------------------------ */
/* Section wrapper */
/* ------------------------------------------------------------------ */
function Section({ title, children }: { title: string; children: React.ReactNode }) {
return (
{title}
{children}
);
}
function SubSection({ title, children }: { title: string; children: React.ReactNode }) {
return (
{title}
{children}
);
}
// Onboarding seam (design §6 + §12.5): the TeamCard tile in its "Pick a starter
// team" 3-col grid, with the first defaultInstall tile selected.
function TeamCardShowcase() {
const [selectedId, setSelectedId] = useState(onboardingTeams[0]?.id ?? null);
return (
The agents section uses a brand heartbeat capsule (8×16) plus a brand
.task-chip. Four states only: idle (gray),
running (blue, pulses), paused (amber), error (red, blinks). Motion
honors prefers-reduced-motion.
{(["idle", "running", "paused", "error"] as const).map((label) => (
Used wherever a task is referenced — in markdown, the Related Work tab, and activity summaries.
Pass status to show the target issue's state at a glance.
Use strikethrough for "removed" contexts.
{/* ============================================================ */}
{/* FORM ELEMENTS */}
{/* ============================================================ */}