veza/apps/web/src/components/views/StudioView.tsx
senke 7c69474cf9 aesthetic-improvements: align spacing to 8px grid (Action 11.2.1.3)
- Created automated script (scripts/align-8px-grid.py) to align all spacing to 8px grid
- Replaced non-8px-aligned spacing: gap-3/p-3/m-3 (12px) → gap-4/p-4/m-4 (16px), gap-5/p-5/m-5 (20px) → gap-6/p-6/m-6 (24px), gap-10/p-10/m-10 (40px) → gap-12/p-12/m-12 (48px), gap-20/p-20/m-20 (80px) → gap-24/p-24/m-24 (96px)
- Preserved: 4px values (gap-1, p-1, m-1) as they may be intentional fine-tuning, responsive breakpoints (sm:, md:, lg:), test files, documentation
- Modified files across all components to ensure consistent 8px grid alignment
- Action 11.2.1.3: Align all elements to 8px grid - COMPLETE
2026-01-16 11:50:46 +01:00

169 lines
5.5 KiB
TypeScript

import React, { useState } from 'react';
import { Button } from '../ui/button';
import {
Wand2,
Mic2,
Layers,
Cloud,
Folder,
Settings,
Network,
} from 'lucide-react';
import { useToast } from '../../context/ToastContext';
import { CloudFileBrowser } from '../studio/CloudFileBrowser';
import { AIToolsView } from '../studio/AIToolsView';
import { ConnectivityView } from '../studio/ConnectivityView';
import { CloudSettingsView } from '../studio/CloudSettingsView';
import { ProjectsManager } from '../studio/ProjectsManager';
interface StudioViewProps {
section?: 'cloud' | 'projects';
}
export const StudioView: React.FC<StudioViewProps> = ({
section: initialSection = 'cloud',
}) => {
const { addToast } = useToast();
const [section, setSection] = useState<'cloud' | 'projects'>(initialSection);
const [activeTab, setActiveTab] = useState<
'files' | 'tools' | 'connect' | 'settings'
>('files');
// --- RENDER PROJECTS ---
if (section === 'projects') {
return (
<>
<div className="flex justify-end mb-4">
<Button
variant="ghost"
onClick={() => setSection('cloud')}
icon={<Cloud className="w-4 h-4" />}
>
Switch to Cloud Studio
</Button>
</div>
<ProjectsManager />
</>
);
}
// --- RENDER CLOUD STUDIO ---
return (
<div className="flex flex-col h-[calc(100vh-140px)] animate-fadeIn">
{/* Header */}
<div className="flex justify-between items-center mb-6 shrink-0">
<div>
<h2 className="text-3xl font-display font-bold text-white mb-2">
CLOUD STUDIO
</h2>
<p className="text-kodo-content-dim font-mono text-sm">
Manage assets, process audio, and sync devices.
</p>
</div>
<div className="flex gap-2">
<Button
variant="ghost"
onClick={() => setSection('projects')}
icon={<Layers className="w-4 h-4" />}
>
Switch to Projects
</Button>
<div className="px-4 py-2 bg-kodo-ink border border-kodo-steel rounded-lg flex items-center gap-4">
<Cloud className="w-4 h-4 text-kodo-steel" />
<div className="w-32 h-2 bg-kodo-steel rounded-full overflow-hidden">
<div className="w-[65%] h-full bg-kodo-cyan"></div>
</div>
<span className="text-xs font-mono text-kodo-content-dim">
65GB / 100GB
</span>
</div>
</div>
</div>
<div className="flex flex-1 gap-6 overflow-hidden">
{/* Sidebar Navigation */}
<div className="w-64 flex flex-col gap-2 shrink-0">
<NavButton
active={activeTab === 'files'}
onClick={() => setActiveTab('files')}
icon={<Folder className="w-4 h-4" />}
label="File Browser"
/>
<NavButton
active={activeTab === 'tools'}
onClick={() => setActiveTab('tools')}
icon={<Wand2 className="w-4 h-4" />}
label="AI Tools"
/>
<NavButton
active={activeTab === 'connect'}
onClick={() => setActiveTab('connect')}
icon={<Network className="w-4 h-4" />}
label="Connectivity"
/>
<NavButton
active={activeTab === 'settings'}
onClick={() => setActiveTab('settings')}
icon={<Settings className="w-4 h-4" />}
label="Storage Settings"
/>
<div className="mt-auto p-4 bg-kodo-ink rounded-xl border border-kodo-steel">
<h4 className="text-xs font-bold text-kodo-content-dim uppercase mb-2">
Quick Actions
</h4>
<div className="space-y-2">
<Button
variant="secondary"
size="sm"
className="w-full text-xs justify-start"
icon={<Mic2 className="w-3 h-3" />}
onClick={() => {
setActiveTab('tools');
addToast('Vocal Remover Selected');
}}
>
Remove Vocals
</Button>
<Button
variant="secondary"
size="sm"
className="w-full text-xs justify-start"
icon={<Layers className="w-3 h-3" />}
onClick={() => {
setActiveTab('tools');
addToast('Stem Splitter Selected');
}}
>
Split Stems
</Button>
</div>
</div>
</div>
{/* Main Content Area */}
<div className="flex-1 bg-kodo-graphite/30 border border-kodo-steel/30 rounded-xl p-6 overflow-hidden">
{activeTab === 'files' && <CloudFileBrowser />}
{activeTab === 'tools' && <AIToolsView />}
{activeTab === 'connect' && <ConnectivityView />}
{activeTab === 'settings' && <CloudSettingsView />}
</div>
</div>
</div>
);
};
const NavButton: React.FC<{
active: boolean;
onClick: () => void;
icon: React.ReactNode;
label: string;
}> = ({ active, onClick, icon, label }) => (
<button
onClick={onClick}
className={`w-full flex items-center gap-4 px-4 py-4 rounded-lg text-sm font-medium transition-all ${active ? 'bg-kodo-cyan/10 text-kodo-cyan border border-kodo-cyan/30' : 'text-kodo-content-dim hover:text-white hover:bg-white/5 border border-transparent'}`}
>
{icon}
{label}
</button>
);