90 lines
3.3 KiB
TypeScript
90 lines
3.3 KiB
TypeScript
|
|
import { Card } from '@/components/ui/card';
|
||
|
|
import { Button } from '@/components/ui/button';
|
||
|
|
import { FileUpload } from '@/components/ui/input';
|
||
|
|
import { CheckCircle, Music, Play, Download } from 'lucide-react';
|
||
|
|
import { UploadProgressBar } from '@/components/upload/UploadProgressBar';
|
||
|
|
import type { ProcessingResult } from './types';
|
||
|
|
|
||
|
|
interface AIToolsViewWorkspaceProps {
|
||
|
|
isProcessing: boolean;
|
||
|
|
progress: number;
|
||
|
|
result: ProcessingResult | null;
|
||
|
|
onUpload: (files: FileList) => void;
|
||
|
|
onReset: () => void;
|
||
|
|
}
|
||
|
|
|
||
|
|
export function AIToolsViewWorkspace({
|
||
|
|
isProcessing,
|
||
|
|
progress,
|
||
|
|
result,
|
||
|
|
onUpload,
|
||
|
|
onReset,
|
||
|
|
}: AIToolsViewWorkspaceProps) {
|
||
|
|
return (
|
||
|
|
<Card
|
||
|
|
variant="default"
|
||
|
|
className="flex-1 flex flex-col justify-center items-center min-h-layout-page-sm"
|
||
|
|
>
|
||
|
|
{!isProcessing && !result && (
|
||
|
|
<div className="w-full max-w-md">
|
||
|
|
<FileUpload onUpload={onUpload} />
|
||
|
|
<p className="text-center text-xs text-kodo-content-dim mt-4">
|
||
|
|
Supported formats: WAV, MP3, FLAC, AIFF. Max 100MB.
|
||
|
|
</p>
|
||
|
|
</div>
|
||
|
|
)}
|
||
|
|
|
||
|
|
{isProcessing && (
|
||
|
|
<div className="w-full max-w-md text-center space-y-4">
|
||
|
|
<div className="w-20 h-20 bg-kodo-ink rounded-full border-4 border-kodo-steel border-t-kodo-cyan animate-spin mx-auto" />
|
||
|
|
<h3 className="text-xl font-bold text-white animate-pulse">Processing Audio...</h3>
|
||
|
|
<p className="text-kodo-content-dim text-sm">
|
||
|
|
Separating frequencies and analyzing waveforms.
|
||
|
|
</p>
|
||
|
|
<UploadProgressBar progress={progress} status="processing" />
|
||
|
|
</div>
|
||
|
|
)}
|
||
|
|
|
||
|
|
{result && (
|
||
|
|
<div className="w-full max-w-2xl animate-scaleIn">
|
||
|
|
<div className="flex items-center gap-4 mb-6 p-4 bg-kodo-lime/10 border border-kodo-lime/30 rounded-lg">
|
||
|
|
<CheckCircle className="w-6 h-6 text-kodo-lime" />
|
||
|
|
<div>
|
||
|
|
<h3 className="font-bold text-white">Analysis Complete</h3>
|
||
|
|
<p className="text-xs text-kodo-text-main">{result.fileName}</p>
|
||
|
|
</div>
|
||
|
|
<Button variant="ghost" size="sm" className="ml-auto" onClick={onReset}>
|
||
|
|
Reset
|
||
|
|
</Button>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<h4 className="text-sm font-bold text-kodo-content-dim uppercase mb-4 tracking-wider">
|
||
|
|
Output Files
|
||
|
|
</h4>
|
||
|
|
<div className="grid grid-cols-1 gap-4">
|
||
|
|
{result.outputs.map((file, i) => (
|
||
|
|
<div
|
||
|
|
key={i}
|
||
|
|
className="flex items-center justify-between p-4 bg-kodo-ink rounded border border-kodo-steel hover:border-kodo-steel/50 transition-colors"
|
||
|
|
>
|
||
|
|
<div className="flex items-center gap-4">
|
||
|
|
<Music className="w-5 h-5 text-kodo-steel" />
|
||
|
|
<span className="text-white font-medium">{file}</span>
|
||
|
|
</div>
|
||
|
|
<div className="flex gap-2">
|
||
|
|
<Button variant="ghost" size="icon" aria-label="Play">
|
||
|
|
<Play className="w-4 h-4" />
|
||
|
|
</Button>
|
||
|
|
<Button variant="secondary" size="sm" icon={<Download className="w-4 h-4" />}>
|
||
|
|
Download
|
||
|
|
</Button>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
))}
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
)}
|
||
|
|
</Card>
|
||
|
|
);
|
||
|
|
}
|