89 lines
3.3 KiB
TypeScript
89 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-muted-foreground 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-card rounded-full border-4 border-border border-t-primary animate-spin mx-auto" />
|
|
<h3 className="text-xl font-bold text-foreground animate-pulse">Processing Audio...</h3>
|
|
<p className="text-muted-foreground 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-success/10 border border-success/30 rounded-xl">
|
|
<CheckCircle className="w-6 h-6 text-success" />
|
|
<div>
|
|
<h3 className="font-bold text-foreground">Analysis Complete</h3>
|
|
<p className="text-xs text-foreground">{result.fileName}</p>
|
|
</div>
|
|
<Button variant="ghost" size="sm" className="ml-auto" onClick={onReset}>
|
|
Reset
|
|
</Button>
|
|
</div>
|
|
|
|
<h4 className="text-sm font-bold text-muted-foreground 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-card rounded-xl border border-border hover:border-border transition-colors duration-[var(--duration-normal)]"
|
|
>
|
|
<div className="flex items-center gap-4">
|
|
<Music className="w-5 h-5 text-muted-foreground" />
|
|
<span className="text-foreground 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>
|
|
);
|
|
}
|