veza/apps/web/src/components/studio/ai-tools-view/AIToolsViewWorkspace.tsx
senke 64061aff64 style(studio): elevate AIToolsView to SaaS Premium
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 14:25:23 +01:00

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>
);
}