| | import React from 'react' |
| |
|
| | function ProcessingOverlay({ stems, progress }) { |
| | |
| | const allSteps = [...stems, '_mix'] |
| | const doneCount = Object.values(progress).filter(s => s === 'done').length |
| | const totalSteps = allSteps.length |
| |
|
| | |
| | const currentlyProcessing = Object.entries(progress).find(([_, status]) => status === 'processing')?.[0] |
| |
|
| | return ( |
| | <div className="fixed inset-0 bg-black/70 backdrop-blur-sm flex items-center justify-center z-50 animate-fade-in"> |
| | <div className="glass rounded-2xl p-8 max-w-md w-full mx-4"> |
| | <div className="text-center mb-6"> |
| | <div className="inline-block animate-spin-slow text-5xl mb-4"> |
| | βοΈ |
| | </div> |
| | <h2 className="text-xl font-semibold text-white">Processing Audio</h2> |
| | <p className="text-gray-400 text-sm mt-1"> |
| | {currentlyProcessing === '_mix' |
| | ? 'Mixing stems together...' |
| | : currentlyProcessing |
| | ? `Processing ${currentlyProcessing.replace(/_/g, ' ')}...` |
| | : 'Please wait while we shift the pitch and tempo...'} |
| | </p> |
| | </div> |
| | |
| | {/* Progress list */} |
| | <div className="space-y-3"> |
| | {allSteps.map((stem) => { |
| | const status = progress[stem] || 'waiting' |
| | const displayName = stem === '_mix' ? 'Final Mix' : stem.replace(/_/g, ' ') |
| | |
| | return ( |
| | <div |
| | key={stem} |
| | className={`flex items-center justify-between py-2 px-3 rounded-lg transition-all ${ |
| | status === 'processing' |
| | ? 'bg-yellow-500/10 border border-yellow-500/30' |
| | : 'bg-white/5' |
| | }`} |
| | > |
| | <span className="capitalize text-sm flex items-center gap-2"> |
| | {stem === '_mix' && <span>π΅</span>} |
| | {displayName} |
| | </span> |
| | <span className={`text-xs px-2 py-1 rounded ${ |
| | status === 'done' |
| | ? 'bg-green-500/20 text-green-400' |
| | : status === 'processing' |
| | ? 'bg-yellow-500/20 text-yellow-400 animate-pulse' |
| | : status.startsWith('error') |
| | ? 'bg-red-500/20 text-red-400' |
| | : 'bg-gray-500/20 text-gray-400' |
| | }`}> |
| | {status === 'done' && 'β Done'} |
| | {status === 'processing' && 'β³ Processing...'} |
| | {status === 'waiting' && 'β Waiting'} |
| | {status.startsWith('error') && 'β Error'} |
| | </span> |
| | </div> |
| | ) |
| | })} |
| | </div> |
| | |
| | {/* Progress bar */} |
| | <div className="mt-6"> |
| | <div className="h-2 bg-gray-700 rounded-full overflow-hidden"> |
| | <div |
| | className="h-full bg-gradient-to-r from-primary-500 to-accent-500 transition-all duration-300" |
| | style={{ |
| | width: `${(doneCount / Math.max(totalSteps, 1)) * 100}%` |
| | }} |
| | /> |
| | </div> |
| | <p className="text-center text-xs text-gray-500 mt-2"> |
| | {doneCount} of {totalSteps} complete |
| | </p> |
| | </div> |
| | </div> |
| | </div> |
| | ) |
| | } |
| |
|
| | export default ProcessingOverlay |
| |
|