jam-tracks / frontend /src /components /ProcessingOverlay.jsx
Mina Emadi
updated the MVP-Initial upload
a0fcd39
import React from 'react'
function ProcessingOverlay({ stems, progress }) {
// Include mixing step in the progress display
const allSteps = [...stems, '_mix']
const doneCount = Object.values(progress).filter(s => s === 'done').length
const totalSteps = allSteps.length
// Check if currently processing any stem
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