| 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 |
|
|