'use client'; import { useState } from 'react'; import { ChevronDown, Lock } from 'lucide-react'; export interface EndpointParam { name: string; type: string; required: boolean; description: string; default?: string; } export interface EndpointDef { method: 'GET' | 'POST' | 'DELETE'; path: string; description: string; auth: boolean; rateLimit?: string; cacheTTL?: string; params?: EndpointParam[]; bodyParams?: EndpointParam[]; responseExample?: string; notes?: string; } interface ApiEndpointSectionProps { title: string; description: string; endpoints: EndpointDef[]; labels: { parameters: string; requestBody: string; required: string; optional: string; default: string; responseExample: string; rateLimit: string; cache: string; authRequired: string; notes: string; }; } const METHOD_STYLES: Record = { GET: 'bg-success/20 text-success', POST: 'bg-primary-100 text-primary-600', DELETE: 'bg-red-100 text-red-600', }; export function ApiEndpointSection({ title, description, endpoints, labels }: ApiEndpointSectionProps) { const [expandedIndexes, setExpandedIndexes] = useState>(new Set()); const toggle = (index: number) => { setExpandedIndexes(prev => { const next = new Set(prev); if (next.has(index)) { next.delete(index); } else { next.add(index); } return next; }); }; return (

{title}

{description}

{endpoints.map((ep, index) => { const expanded = expandedIndexes.has(index); const hasDetails = ep.params?.length || ep.bodyParams?.length || ep.responseExample || ep.notes; return (
{/* Description visible on mobile (below sm) */}

{ep.description}

{expanded && hasDetails && (
{/* Rate limit & cache badges */} {(ep.rateLimit || ep.cacheTTL) && (
{ep.rateLimit && ( {labels.rateLimit}: {ep.rateLimit} )} {ep.cacheTTL && ( {labels.cache}: {ep.cacheTTL} )}
)} {/* Query parameters */} {ep.params && ep.params.length > 0 && (

{labels.parameters}

{ep.params.map((p) => ( ))}
Name Type Description
{p.name} {p.type} {p.required ? labels.required : labels.optional} {p.description} {p.default && (default: {p.default})}
)} {/* Body parameters */} {ep.bodyParams && ep.bodyParams.length > 0 && (

{labels.requestBody}

{ep.bodyParams.map((p) => ( ))}
Name Type Description
{p.name} {p.type} {p.required ? labels.required : labels.optional} {p.description}
)} {/* Response example */} {ep.responseExample && (

{labels.responseExample}

{ep.responseExample}
)} {/* Notes */} {ep.notes && (
{labels.notes}: {ep.notes}
)}
)}
); })}
); }