/** * ReconstructionStatus - Shows processing progress with animated 3D cube. */ import { useRef } from 'react'; import { Canvas, useFrame } from '@react-three/fiber'; import { motion } from 'framer-motion'; import * as THREE from 'three'; import { STEPS_CONFIG } from '../types'; import type { QueueStatus } from '../types'; interface ReconstructionStatusProps { currentStep: string; progress: number; message: string; error?: string | null; queueStatus?: QueueStatus | null; } function RotatingCube() { const meshRef = useRef(null); useFrame((_, delta) => { if (meshRef.current) { meshRef.current.rotation.x += delta * 0.5; meshRef.current.rotation.y += delta * 0.7; } }); return ( ); } const steps = [ { key: 'queued', ...STEPS_CONFIG.queued }, { key: 'shape', ...STEPS_CONFIG.shape }, { key: 'paint', ...STEPS_CONFIG.paint }, { key: 'optimize', ...STEPS_CONFIG.optimize }, { key: 'done', ...STEPS_CONFIG.done }, ]; export default function ReconstructionStatus({ currentStep, progress, message, error, queueStatus, }: ReconstructionStatusProps) { const activeIndex = steps.findIndex((s) => s.key === currentStep); const normalizedActiveIndex = activeIndex < 0 ? 0 : activeIndex; const queueEta = queueStatus?.etaSeconds !== null && queueStatus?.etaSeconds !== undefined ? Math.max(1, Math.round(queueStatus.etaSeconds)) : null; return (

{error ? 'Generation Failed' : 'Generating Your 3D Asset'}

{queueStatus?.stage === 'pending' && (

ZeroGPU Queue Status

{queueStatus.rank !== null ? `Position ${queueStatus.rank}` : 'Waiting for queue assignment'} {queueStatus.queueSize !== null ? ` of ${queueStatus.queueSize}` : ''} {queueEta !== null ? `, ETA ~${queueEta}s` : ''}

)}
{error ? (

{error}

Tips: Try adding more images with overlapping views, ensure consistent lighting, avoid reflective surfaces.

) : ( <>
{message} {progress}%
{steps.slice(0, -1).map((step, index) => { const isActive = index === normalizedActiveIndex; const isComplete = index < normalizedActiveIndex; const isPending = index > normalizedActiveIndex; return (
{isComplete ? ( ) : isActive ? ( ) : ( {index + 1} )}
{step.label}
); })}
)}
); }