'use client'; import { Check, Play, Sparkles } from 'lucide-react'; import React, { useCallback, useMemo, useState } from 'react'; import { Button } from '@djangocfg/ui-core/components'; import { MarkdownMessage } from '../../../../../../code/MarkdownMessage'; import type { ApiEndpoint } from '../../../../types'; import { endpointToMarkdown } from '../../../../utils/schemaExport'; import type { SectionId } from '../types'; import { MetaActions } from './MetaActions'; import { MethodBadge } from './MethodBadge'; import { PathDisplay } from './PathDisplay'; interface EndpointHeaderProps { endpoint: ApiEndpoint; anchor: string; isLoadedInPlayground: boolean; onTryIt: () => void; /** Sections actually rendered on this endpoint — drives the * expand/collapse-all icon in the meta row. */ presentSections: readonly SectionId[]; } /** Card header, three stacked rows: * 1. Meta — small utility strip: method badge · inline actions · Try-it. * 2. Path — large monospace, the visual focus of the card. * 3. Description — prose, aligned to the left edge under path. * * Splitting metadata from the path lets the path itself become the * focal point — readers scan paths when scrolling, not badges. The * meta row stays compact so it reads as "info about this endpoint" * rather than "toolbar that competes for attention". */ export function EndpointHeader({ endpoint, anchor, isLoadedInPlayground, onTryIt, presentSections, }: EndpointHeaderProps) { // Memoise the markdown dump — only recomputes when the endpoint // reference changes, not on unrelated re-renders of the subtree. const endpointMd = useMemo(() => endpointToMarkdown(endpoint), [endpoint]); const [aiCopied, setAiCopied] = useState(false); const onAiCopy = useCallback(() => { if (typeof window === 'undefined') return; void navigator.clipboard?.writeText(endpointMd).then(() => { setAiCopied(true); setTimeout(() => setAiCopied(false), 1200); }); }, [endpointMd]); const tryItLabel = isLoadedInPlayground ? 'Loaded' : 'Try it'; const aiCopyIcon = aiCopied ? ( ) : ( ); const aiCopyLabel = aiCopied ? 'Copied' : 'AI Copy'; const descriptionNode = endpoint.description ? (
) : null; return (
{/* Row 1 — meta strip. Badge + inline icon actions on the left, primary CTAs on the right. Kept tight (24px tall) so it doesn't visually compete with the path row below. */}
{/* Row 2 — path as the visual focal point. Larger and more prominent than it was when competing with the badge and action icons inline. */}
{/* Row 3 — description, aligned to the left edge under the path. Text-sm so it reads as subtitle, not body copy. */} {descriptionNode}
); }