import { useState, useEffect } from 'react' import { X, Star, Copy, Check, HelpCircle, Zap, CheckCircle, User, Calendar, GitBranch } from 'lucide-react' import { cn } from '@/lib/utils' import { MarkdownContent } from '@/components/ui/MarkdownContent' import { stepsApi } from '@/api/steps' import type { Step, Review } from '@/types/step' interface StepDetailModalProps { stepId: string onClose: () => void onInsert: (step: Step) => void } const stepTypeIcons = { decision: HelpCircle, action: Zap, solution: CheckCircle } const stepTypeColors = { decision: 'bg-blue-400/10 text-blue-400 border-blue-400/20', action: 'bg-yellow-400/10 text-yellow-400 border-yellow-400/20', solution: 'bg-emerald-400/10 text-emerald-400 border-emerald-400/20' } export function StepDetailModal({ stepId, onClose, onInsert }: StepDetailModalProps) { const [step, setStep] = useState(null) const [reviews, setReviews] = useState([]) const [isLoading, setIsLoading] = useState(true) const [error, setError] = useState(null) const [copiedCommandIndex, setCopiedCommandIndex] = useState(null) useEffect(() => { const loadStepDetails = async () => { setIsLoading(true) setError(null) try { const [stepData, reviewsData] = await Promise.all([ stepsApi.get(stepId), stepsApi.getReviews(stepId) ]) setStep(stepData) setReviews(reviewsData) } catch (err) { console.error('Failed to load step details:', err) setError('Failed to load step details') } finally { setIsLoading(false) } } loadStepDetails() }, [stepId]) const handleCopyCommand = async (command: string, index: number) => { await navigator.clipboard.writeText(command) setCopiedCommandIndex(index) setTimeout(() => setCopiedCommandIndex(null), 2000) } const handleInsert = () => { if (step) { onInsert(step) } } const Icon = step ? stepTypeIcons[step.step_type as keyof typeof stepTypeIcons] : HelpCircle const hasRating = step && step.rating_count > 0 const topReviews = reviews.filter(r => r.review_text).slice(0, 3) return (
{/* Header */}
{isLoading ? (
) : error ? (

{error}

) : step ? (
{step.step_type} {step.category_name && ( {step.category_name} )} {step.is_featured && ( Featured )} {step.is_verified && ( Verified )}

{step.title}

) : null}
{/* Body - Scrollable */}
{isLoading ? (
) : error ? (

{error}

) : step ? (
{/* Rating */} {hasRating && (

Rating

{[1, 2, 3, 4, 5].map(i => ( ))}
{step.rating_average.toFixed(1)} ({step.rating_count} {step.rating_count === 1 ? 'rating' : 'ratings'})
)} {/* Tags */} {step.tags.length > 0 && (

Tags

{step.tags.map(tag => ( {tag} ))}
)} {/* Instructions */}

Instructions

{/* Help Text */} {step.content.help_text && (

Help Text

)} {/* Commands */} {step.content.commands && step.content.commands.length > 0 && (

Commands

{step.content.commands.map((cmd, index) => (
{cmd.label}
                          {cmd.command}
                        
))}
)} {/* Reviews */} {topReviews.length > 0 && (

Reviews

{reviews.length > 3 && ( )}
{topReviews.map(review => (
{review.user_name || 'Anonymous'} {review.verified_use && ( Verified Use )}
{[1, 2, 3, 4, 5].map(i => ( ))}

{review.review_text}

{new Date(review.created_at).toLocaleDateString()}
))}
)} {/* Metadata */}
Author: {step.author_name || 'Unknown'}
{step.is_flow_synced && step.source_tree_name && (
Sourced from {step.source_tree_name}
)}
Usage Count: {step.usage_count}
Created: {new Date(step.created_at).toLocaleDateString()}
Visibility: {step.visibility}
) : null}
{/* Footer - Actions */}
) }