'use client'
import React from 'react'
import Link from 'next/link'
import { usePathname } from 'next/navigation'
import { useSDK, SDK_STEPS, getStepsForPhase, SDKPhase } from '@/lib/sdk'
// =============================================================================
// ICONS
// =============================================================================
const CheckIcon = () => (
)
const LockIcon = () => (
)
const WarningIcon = () => (
)
const ChevronDownIcon = ({ className = '' }: { className?: string }) => (
)
const CollapseIcon = ({ collapsed }: { collapsed: boolean }) => (
)
// =============================================================================
// PHASE INDICATOR
// =============================================================================
interface PhaseIndicatorProps {
phase: SDKPhase
title: string
completion: number
isActive: boolean
isExpanded: boolean
onToggle: () => void
collapsed: boolean
}
function PhaseIndicator({ phase, title, completion, isActive, isExpanded, onToggle, collapsed }: PhaseIndicatorProps) {
if (collapsed) {
return (
)
}
return (
)
}
// =============================================================================
// PROGRESS BAR
// =============================================================================
interface ProgressBarProps {
value: number
className?: string
}
function ProgressBar({ value, className = '' }: ProgressBarProps) {
return (
)
}
// =============================================================================
// STEP ITEM
// =============================================================================
interface StepItemProps {
step: (typeof SDK_STEPS)[number]
isActive: boolean
isCompleted: boolean
isLocked: boolean
checkpointStatus?: 'passed' | 'failed' | 'warning' | 'pending'
collapsed: boolean
}
function StepItem({ step, isActive, isCompleted, isLocked, checkpointStatus, collapsed }: StepItemProps) {
const content = (
{/* Step indicator */}
{isCompleted ? (
) : isLocked ? (
) : isActive ? (
) : (
)}
{/* Step name - hidden when collapsed */}
{!collapsed &&
{step.nameShort}}
{/* Checkpoint status - hidden when collapsed */}
{!collapsed && checkpointStatus && checkpointStatus !== 'pending' && (
{checkpointStatus === 'passed' ? (
) : checkpointStatus === 'failed' ? (
!
) : (
)}
)}
)
if (isLocked) {
return content
}
return (
{content}
)
}
// =============================================================================
// ADDITIONAL MODULE ITEM
// =============================================================================
interface AdditionalModuleItemProps {
href: string
icon: React.ReactNode
label: string
isActive: boolean
collapsed: boolean
}
function AdditionalModuleItem({ href, icon, label, isActive, collapsed }: AdditionalModuleItemProps) {
return (
{icon}
{!collapsed && {label}}
)
}
// =============================================================================
// MAIN SIDEBAR
// =============================================================================
interface SDKSidebarProps {
collapsed?: boolean
onCollapsedChange?: (collapsed: boolean) => void
}
export function SDKSidebar({ collapsed = false, onCollapsedChange }: SDKSidebarProps) {
const pathname = usePathname()
const { state, phase1Completion, phase2Completion, getCheckpointStatus } = useSDK()
const [expandedPhases, setExpandedPhases] = React.useState>({
1: true,
2: true,
})
const togglePhase = (phase: number) => {
setExpandedPhases(prev => ({ ...prev, [phase]: !prev[phase] }))
}
const phase1Steps = getStepsForPhase(1)
const phase2Steps = getStepsForPhase(2)
const isStepLocked = (step: (typeof SDK_STEPS)[number]): boolean => {
if (state.preferences?.allowParallelWork) return false
return step.prerequisiteSteps.some(prereq => !state.completedSteps.includes(prereq))
}
const getStepCheckpointStatus = (step: (typeof SDK_STEPS)[number]): 'passed' | 'failed' | 'warning' | 'pending' => {
const status = getCheckpointStatus(step.checkpointId)
if (!status) return 'pending'
if (status.passed) return 'passed'
if (status.errors.length > 0) return 'failed'
if (status.warnings.length > 0) return 'warning'
return 'pending'
}
return (
)
}