import { useState } from 'react'; import { ChevronDown, Lock, Layers, AlertCircle } from 'lucide-react'; import type { AnalyzerResult } from '@/lib/blueprintsApi'; interface BlueprintClassificationBannerProps { analysis: AnalyzerResult | null; /** When true, render an even more compact strip suitable for inline detail sheets. */ compact?: boolean; } const COPY: Record<'stateless' | 'stateful' | 'unknown', { kicker: string; message: string }> = { stateless: { kicker: 'Stateless · portable', message: 'No persistent volumes detected. Sencho can deploy and evict freely across nodes.', }, stateful: { kicker: 'Stateful · pins to data', message: 'Persistent volumes detected. Each node holds its own data; eviction requires explicit operator confirmation.', }, unknown: { kicker: 'State unknown', message: 'External or unanalyzable volumes detected. Treated as stateful for safety.', }, }; export function BlueprintClassificationBanner({ analysis, compact = false }: BlueprintClassificationBannerProps) { const [showDetails, setShowDetails] = useState(false); if (!analysis) { return (
Compose not analyzed yet
); } const { classification, reasons, parseError } = analysis; const tone = classification === 'stateless' ? 'success' : classification === 'unknown' ? 'muted' : 'warning'; const Icon = classification === 'stateless' ? Layers : classification === 'unknown' ? AlertCircle : Lock; const dotColor = tone === 'success' ? 'bg-success' : tone === 'warning' ? 'bg-warning' : 'bg-muted-foreground'; return (
{COPY[classification].kicker} {!compact && ( {parseError ? `Could not parse compose: ${parseError}` : COPY[classification].message} )}
{reasons.length > 0 && ( )}
{showDetails && reasons.length > 0 && ( )}
); }