import { PlusIcon, XIcon } from "lucide-react"; import { emptyPlacement, PlacementLine, type Carrier, type Placement, } from "../lib/auth-placements"; import { Button } from "./button"; import { Input } from "./input"; import { Label } from "./label"; // --------------------------------------------------------------------------- // Placement editor — compact cards for where an API key is sent. // // Each card uses a segmented Header/Query choice, labeled name/prefix fields, // and an inline preview of the rendered credential placement. // --------------------------------------------------------------------------- const PLACEMENT_PRESETS: readonly { readonly label: string; readonly placements: readonly Placement[]; }[] = [ { label: "Bearer header", placements: [{ carrier: "header", name: "Authorization", prefix: "Bearer " }], }, { label: "API key header", placements: [{ carrier: "header", name: "X-API-Key", prefix: "" }], }, { label: "API key query", placements: [{ carrier: "query", name: "api_key", prefix: "" }], }, ]; export function PlacementEditor(props: { readonly placements: readonly Placement[]; readonly onChange: (placements: Placement[]) => void; }) { const { placements, onChange } = props; const set = (index: number, patch: Partial): void => onChange(placements.map((p: Placement, j: number) => (j === index ? { ...p, ...patch } : p))); const remove = (index: number): void => onChange(placements.filter((_p: Placement, j: number) => j !== index)); return (
{PLACEMENT_PRESETS.map((preset) => ( ))}
{placements.map((placement: Placement, index: number) => (

Send the value in a request header or query string.

{placements.length > 1 && ( )}
{(["header", "query"] as const).map((carrier: Carrier) => ( ))}
) => set(index, { name: e.target.value }) } />
) => set(index, { prefix: e.target.value }) } />
{placement.name ? (
Preview
) : null}
))}
); }