banatie-service/apps/landing/src/components/docs/blocks/ResponseBlock.tsx

245 lines
7.3 KiB
TypeScript

'use client';
/**
* ResponseBlock Component
*
* A semantic display block for API response examples with status indicators.
* Visually differentiates success and error responses through color psychology.
*
* ## Design Principles
*
* 1. **Status Communication**: Color instantly conveys response type
* - Green = Success (2xx responses, positive outcomes)
* - Red = Error (4xx/5xx responses, failures)
* - Consistent with universal traffic light conventions
*
* 2. **Information Layering**: Progressive disclosure of details
* - Status badge in top-right for immediate recognition
* - Optional title provides context
* - Content area for actual response data
* - Layered styling adds depth without clutter
*
* 3. **Visual Feedback**: Subtle effects reinforce status
* - Background tint matches status color
* - Border emphasis adds structure
* - Soft shadow/glow creates depth
* - All at low opacity to avoid overwhelming
*
* ## Status Semantics
*
* @param {'success'} success - Successful API responses (2xx status codes)
* - Visual: Green color palette (green-500)
* - Psychology: Positive, correct, achieved
* - Use cases: 200 OK, 201 Created, 204 No Content
* - Styling: bg-green-500/5, border-green-500/30, shadow-green-500/10
* - Badge: "✓ 200 Success", "✓ 201 Created"
*
* @param {'error'} error - Error API responses (4xx/5xx status codes)
* - Visual: Red color palette (red-500)
* - Psychology: Warning, problem, attention needed
* - Use cases: 400 Bad Request, 401 Unauthorized, 500 Server Error
* - Styling: bg-red-500/5, border-red-500/30, shadow-red-500/10
* - Badge: "✗ 400 Error", "✗ 500 Error"
*
* ## Opacity Strategy
*
* Three-tier opacity system:
* - Background: /5 (5% opacity) - Subtle tint, doesn't obscure content
* - Border: /30 (30% opacity) - Clear definition, visible structure
* - Shadow: /10 (10% opacity) - Soft depth, enhances without distraction
*
* This creates:
* - Cohesive visual grouping
* - Clear status communication
* - Maintains content readability
* - Professional, polished appearance
*
* ## Layout Structure
*
* ```
* ┌─────────────────────────────────────┐
* │ [STATUS BADGE] ←──┤ Absolute positioned
* │ Optional Title │
* │ (if provided) │
* │ │
* │ <pre><code> │
* │ Response content │
* │ ... │
* │ </code></pre> │
* └─────────────────────────────────────┘
* ```
*
* Positioning Strategy:
* - Container: relative positioning context
* - Badge: absolute top-3 right-3 (float in top-right)
* - Content: mt-6 when badge present (clear space for badge)
* - Title: mb-3 if provided (separate from content)
*
* ## Typography & Content
*
* Title (optional):
* - text-sm: Small, not competing with main content
* - font-semibold: Subtle emphasis
* - text-gray-300: Readable but secondary
* - Purpose: Labels response type, adds context
*
* Response Content:
* - text-xs: Appropriate for code samples
* - text-gray-300: High contrast on dark background
* - font-mono (implicit in <code>): Code appearance
* - overflow-x-auto: Handles long lines gracefully
*
* ## Usage Examples
*
* ```tsx
* // Success response with title
* <ResponseBlock
* status="success"
* statusCode={200}
* title="Expected Response:"
* content={`{
* "success": true,
* "data": { ... }
* }`}
* />
*
* // Error response without title
* <ResponseBlock
* status="error"
* statusCode={401}
* content={`{
* "error": "Unauthorized",
* "message": "Invalid API key"
* }`}
* />
*
* // Custom status label
* <ResponseBlock
* status="success"
* statusCode={201}
* statusLabel="✓ 201 Created"
* content="{ ... }"
* />
* ```
*
* ## Content Guidelines
*
* Response Content:
* - Use actual JSON/text from your API
* - Format with proper indentation (2 or 4 spaces)
* - Include realistic data (not just placeholders)
* - Show relevant fields (omit excessive detail)
* - Keep under 20-30 lines for readability
*
* Status Labels:
* - Include status code (200, 400, etc.)
* - Add descriptive text (Success, Error, Created)
* - Use checkmark (✓) for success
* - Use X (✗) for errors
* - Keep concise (2-3 words max)
*
* ## Accessibility
*
* - Semantic HTML structure (<pre><code>)
* - Color is supplementary (text + symbols)
* - High contrast text colors
* - StatusBadge includes aria-label
* - Proper heading hierarchy if title used
* - Scrollable overflow for long content
*
* ## Visual Language
*
* The ResponseBlock creates:
* - Immediate status recognition through color
* - Professional code presentation
* - Clear example/documentation relationship
* - Consistent pattern across all API docs
* - Supports learn-by-example documentation style
*
* @component
* @example
* <ResponseBlock
* status="success"
* statusCode={200}
* title="Success Response"
* content={jsonString}
* />
*/
import { StatusBadge, StatusType } from './StatusBadge';
/**
* Props for the ResponseBlock component
*/
export interface ResponseBlockProps {
/** Status type determining color scheme */
status: Extract<StatusType, 'success' | 'error'>;
/** HTTP status code (e.g., 200, 400, 500) */
statusCode: number;
/** The response content to display (typically JSON) */
content: string;
/** Optional title above the response */
title?: string;
/** Optional custom status label (default: auto-generated from statusCode) */
statusLabel?: string;
/** Optional CSS class name for additional styling */
className?: string;
}
/**
* Status styles mapping status type to background, border, and shadow colors
*/
const statusStyles = {
success: 'bg-green-500/5 border-green-500/30 shadow-lg shadow-green-500/10',
error: 'bg-red-500/5 border-red-500/30 shadow-lg shadow-red-500/10',
};
/**
* Generate default status label from code and status
*/
const getDefaultStatusLabel = (code: number, status: 'success' | 'error'): string => {
const symbol = status === 'success' ? '✓' : '✗';
const text = status === 'success' ? 'Success' : 'Error';
return `${symbol} ${code} ${text}`;
};
export const ResponseBlock = ({
status,
statusCode,
content,
title,
statusLabel,
className = '',
}: ResponseBlockProps) => {
const label = statusLabel || getDefaultStatusLabel(statusCode, status);
return (
<div
className={`
relative
p-4
border rounded-xl
${statusStyles[status]}
${className}
`}
>
{/* Status Badge - Floating Top Right */}
<div className="absolute top-3 right-3">
<StatusBadge status={status} size="sm">
{label}
</StatusBadge>
</div>
{/* Optional Title */}
{title && (
<p className="text-sm font-semibold text-gray-300 mb-3">{title}</p>
)}
{/* Response Content */}
<pre className={`text-xs text-gray-300 overflow-x-auto ${title || statusLabel ? 'mt-6' : ''}`}>
<code>{content}</code>
</pre>
</div>
);
};