2026-01-07 09:31:02 +00:00
|
|
|
import React, { useState } from 'react';
|
|
|
|
|
import { Card } from '../ui/card';
|
|
|
|
|
import { Button } from '../ui/button';
|
|
|
|
|
import { SearchInput } from '../ui/input';
|
|
|
|
|
import { FileNode } from '../../types';
|
2026-01-13 18:47:57 +00:00
|
|
|
import {
|
|
|
|
|
LayoutGrid,
|
|
|
|
|
List,
|
|
|
|
|
Filter,
|
|
|
|
|
MoreVertical,
|
|
|
|
|
Download,
|
|
|
|
|
Trash2,
|
|
|
|
|
Move,
|
|
|
|
|
Folder,
|
|
|
|
|
Music,
|
|
|
|
|
Image as ImageIcon,
|
|
|
|
|
File,
|
|
|
|
|
CheckSquare,
|
|
|
|
|
Square,
|
|
|
|
|
Wand2,
|
|
|
|
|
Stamp,
|
|
|
|
|
Eye,
|
|
|
|
|
ChevronRight,
|
2026-01-07 09:31:02 +00:00
|
|
|
} from 'lucide-react';
|
|
|
|
|
import { useToast } from '../../context/ToastContext';
|
|
|
|
|
import { AutoMetadataDetectionModal } from '../library/AutoMetadataDetectionModal';
|
|
|
|
|
import { WatermarkSettingsModal } from '../library/WatermarkSettingsModal';
|
|
|
|
|
import { FileDetailsView } from './FileDetailsView';
|
|
|
|
|
|
|
|
|
|
// Mock Files
|
|
|
|
|
const MOCK_FILES: FileNode[] = [
|
2026-01-13 18:47:57 +00:00
|
|
|
{
|
|
|
|
|
id: '1',
|
|
|
|
|
name: 'Vocals_Main.wav',
|
|
|
|
|
type: 'audio',
|
|
|
|
|
size: '24 MB',
|
|
|
|
|
modified: '2h ago',
|
|
|
|
|
status: 'ready',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
id: '2',
|
|
|
|
|
name: 'Project_Alpha_v3',
|
|
|
|
|
type: 'folder',
|
|
|
|
|
size: '-',
|
|
|
|
|
modified: '1d ago',
|
|
|
|
|
status: 'ready',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
id: '3',
|
|
|
|
|
name: 'Bass_Drop_F#m.wav',
|
|
|
|
|
type: 'audio',
|
|
|
|
|
size: '12 MB',
|
|
|
|
|
modified: '3d ago',
|
|
|
|
|
status: 'processing',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
id: '4',
|
|
|
|
|
name: 'Album_Cover_Art.png',
|
|
|
|
|
type: 'image',
|
|
|
|
|
size: '4 MB',
|
|
|
|
|
modified: '1w ago',
|
|
|
|
|
status: 'ready',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
id: '5',
|
|
|
|
|
name: 'Reference_Track_01.mp3',
|
|
|
|
|
type: 'audio',
|
|
|
|
|
size: '8 MB',
|
|
|
|
|
modified: '2w ago',
|
|
|
|
|
status: 'ready',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
id: '6',
|
|
|
|
|
name: 'Legal_Contracts.pdf',
|
|
|
|
|
type: 'document',
|
|
|
|
|
size: '2 MB',
|
|
|
|
|
modified: '3w ago',
|
|
|
|
|
status: 'archived',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
id: '7',
|
|
|
|
|
name: 'Drums_Stem_02.wav',
|
|
|
|
|
type: 'audio',
|
|
|
|
|
size: '45 MB',
|
|
|
|
|
modified: '1h ago',
|
|
|
|
|
status: 'ready',
|
|
|
|
|
},
|
2026-01-07 09:31:02 +00:00
|
|
|
];
|
|
|
|
|
|
|
|
|
|
export const FileManagerView: React.FC = () => {
|
|
|
|
|
const { addToast } = useToast();
|
|
|
|
|
const [viewMode, setViewMode] = useState<'list' | 'grid'>('list');
|
|
|
|
|
const [searchQuery, setSearchQuery] = useState('');
|
|
|
|
|
const [selectedFiles, setSelectedFiles] = useState<string[]>([]);
|
|
|
|
|
const [currentFolder, setCurrentFolder] = useState('Root');
|
2026-01-13 18:47:57 +00:00
|
|
|
|
2026-01-07 09:31:02 +00:00
|
|
|
// Navigation State
|
|
|
|
|
const [selectedFileId, setSelectedFileId] = useState<string | null>(null);
|
|
|
|
|
|
|
|
|
|
// Modals
|
|
|
|
|
const [showMetadataModal, setShowMetadataModal] = useState(false);
|
|
|
|
|
const [showWatermarkModal, setShowWatermarkModal] = useState(false);
|
|
|
|
|
|
|
|
|
|
// --- Handlers ---
|
|
|
|
|
|
|
|
|
|
const handleFileClick = (file: FileNode) => {
|
2026-01-13 18:47:57 +00:00
|
|
|
if (file.type === 'folder') {
|
|
|
|
|
setCurrentFolder(file.name);
|
|
|
|
|
addToast(`Navigated to ${file.name}`, 'info');
|
|
|
|
|
} else {
|
|
|
|
|
setSelectedFileId(file.id);
|
|
|
|
|
}
|
2026-01-07 09:31:02 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const toggleSelection = (id: string) => {
|
2026-01-13 18:47:57 +00:00
|
|
|
setSelectedFiles((prev) =>
|
|
|
|
|
prev.includes(id) ? prev.filter((fid) => fid !== id) : [...prev, id],
|
|
|
|
|
);
|
2026-01-07 09:31:02 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const selectAll = () => {
|
2026-01-13 18:47:57 +00:00
|
|
|
if (selectedFiles.length === MOCK_FILES.length) setSelectedFiles([]);
|
|
|
|
|
else setSelectedFiles(MOCK_FILES.map((f) => f.id));
|
2026-01-07 09:31:02 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const handleBulkAction = (action: string) => {
|
2026-01-13 18:47:57 +00:00
|
|
|
addToast(`${action} ${selectedFiles.length} files`, 'success');
|
|
|
|
|
setSelectedFiles([]);
|
2026-01-07 09:31:02 +00:00
|
|
|
};
|
|
|
|
|
|
2026-01-13 18:47:57 +00:00
|
|
|
const filteredFiles = MOCK_FILES.filter((f) =>
|
|
|
|
|
f.name.toLowerCase().includes(searchQuery.toLowerCase()),
|
|
|
|
|
);
|
2026-01-07 09:31:02 +00:00
|
|
|
|
|
|
|
|
// --- Render Detail View if selected ---
|
|
|
|
|
if (selectedFileId) {
|
2026-01-13 18:47:57 +00:00
|
|
|
return (
|
|
|
|
|
<FileDetailsView
|
|
|
|
|
fileId={selectedFileId}
|
|
|
|
|
onBack={() => setSelectedFileId(null)}
|
|
|
|
|
/>
|
|
|
|
|
);
|
2026-01-07 09:31:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// --- Main Render ---
|
|
|
|
|
return (
|
aesthetic-improvements: apply design direction to pages batch 3 (Action 11.5.1.5)
- Pages: Updated remaining spacing issues (p-6 → p-8, space-y-6 → space-y-8, gap-6 → gap-8)
- DashboardPage, DeveloperPage, GearPage, DesignSystemDemoPage, MarketplaceHome
- Views: Updated spacing (space-y-6 → space-y-8, gap-6 → gap-8, p-6 → p-8)
- FileManagerView, NotificationsView, SocialView, FileDetailsView, UploadView, MarketplaceView, GearView, LiveView, ProfileView
- Action 11.5.1.5: Apply direction to all pages - Batch 3 complete (5 pages + 9 views = 14 files)
2026-01-16 11:00:50 +00:00
|
|
|
<div className="space-y-8 animate-fadeIn pb-20">
|
2026-01-13 18:47:57 +00:00
|
|
|
{/* Header & Controls */}
|
|
|
|
|
<div className="flex flex-col md:flex-row justify-between items-start md:items-center gap-4">
|
|
|
|
|
<div>
|
2026-01-15 22:54:05 +00:00
|
|
|
<h2 className="text-2xl font-display font-bold text-white mb-1">
|
2026-01-13 18:47:57 +00:00
|
|
|
FILE MANAGER
|
|
|
|
|
</h2>
|
2026-01-16 00:49:52 +00:00
|
|
|
<div className="flex items-center gap-2 text-sm text-kodo-content-dim">
|
2026-01-13 18:47:57 +00:00
|
|
|
<span
|
|
|
|
|
className="hover:text-white cursor-pointer"
|
|
|
|
|
onClick={() => setCurrentFolder('Root')}
|
|
|
|
|
>
|
|
|
|
|
Root
|
|
|
|
|
</span>
|
|
|
|
|
{currentFolder !== 'Root' && (
|
|
|
|
|
<>
|
|
|
|
|
<ChevronRight className="w-4 h-4" />
|
|
|
|
|
<span className="text-white font-bold">{currentFolder}</span>
|
|
|
|
|
</>
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
2026-01-07 09:31:02 +00:00
|
|
|
</div>
|
|
|
|
|
|
2026-01-13 18:47:57 +00:00
|
|
|
<div className="flex gap-2 w-full md:w-auto">
|
|
|
|
|
<Button
|
|
|
|
|
variant="ghost"
|
|
|
|
|
onClick={() => setShowMetadataModal(true)}
|
|
|
|
|
title="AI Auto-Tag"
|
|
|
|
|
aria-label="AI Auto-Tag"
|
|
|
|
|
>
|
|
|
|
|
<Wand2 className="w-4 h-4" />
|
|
|
|
|
</Button>
|
|
|
|
|
<Button
|
|
|
|
|
variant="ghost"
|
|
|
|
|
onClick={() => setShowWatermarkModal(true)}
|
|
|
|
|
title="Watermark Settings"
|
|
|
|
|
aria-label="Paramètres de filigrane"
|
|
|
|
|
>
|
|
|
|
|
<Stamp className="w-4 h-4" />
|
|
|
|
|
</Button>
|
|
|
|
|
<div className="bg-kodo-ink p-1 rounded-lg border border-kodo-steel flex">
|
|
|
|
|
<button
|
|
|
|
|
onClick={() => setViewMode('list')}
|
2026-01-16 00:49:52 +00:00
|
|
|
className={`p-2 rounded ${viewMode === 'list' ? 'bg-kodo-slate text-white' : 'text-kodo-content-dim hover:text-white'}`}
|
2026-01-13 18:47:57 +00:00
|
|
|
aria-label="Vue liste"
|
|
|
|
|
aria-pressed={viewMode === 'list'}
|
|
|
|
|
>
|
|
|
|
|
<List className="w-4 h-4" />
|
|
|
|
|
</button>
|
|
|
|
|
<button
|
|
|
|
|
onClick={() => setViewMode('grid')}
|
2026-01-16 00:49:52 +00:00
|
|
|
className={`p-2 rounded ${viewMode === 'grid' ? 'bg-kodo-slate text-white' : 'text-kodo-content-dim hover:text-white'}`}
|
2026-01-13 18:47:57 +00:00
|
|
|
aria-label="Vue grille"
|
|
|
|
|
aria-pressed={viewMode === 'grid'}
|
|
|
|
|
>
|
|
|
|
|
<LayoutGrid className="w-4 h-4" />
|
|
|
|
|
</button>
|
|
|
|
|
</div>
|
2026-01-07 09:31:02 +00:00
|
|
|
</div>
|
2026-01-13 18:47:57 +00:00
|
|
|
</div>
|
2026-01-07 09:31:02 +00:00
|
|
|
|
2026-01-13 18:47:57 +00:00
|
|
|
{/* Search & Filter Bar */}
|
|
|
|
|
<div className="bg-kodo-ink/50 p-4 rounded-xl border border-kodo-steel/50 flex flex-col md:flex-row gap-4 items-center justify-between">
|
|
|
|
|
<div className="w-full md:w-96">
|
|
|
|
|
<SearchInput
|
|
|
|
|
placeholder="Search files..."
|
|
|
|
|
value={searchQuery}
|
|
|
|
|
onChange={(e) => setSearchQuery(e.target.value)}
|
|
|
|
|
/>
|
2026-01-07 09:31:02 +00:00
|
|
|
</div>
|
|
|
|
|
|
2026-01-13 18:47:57 +00:00
|
|
|
{selectedFiles.length > 0 ? (
|
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 10:50:46 +00:00
|
|
|
<div className="flex items-center gap-4 bg-kodo-steel/10 px-4 py-2 rounded-lg border border-kodo-steel/30 animate-fadeIn w-full md:w-auto">
|
aesthetic-improvements: reduce decorative cyan backgrounds (80/20 rule)
- KodoEmptyState: decorative background blur and border (bg-kodo-cyan/20 → bg-kodo-steel/20, border-kodo-cyan/30 → border-kodo-steel/30, icon text-kodo-cyan → text-kodo-steel)
- PWAInstallBanner: decorative icon background and blur effect (2 instances)
- Page headers: SettingsPage, GearPage, DeveloperPage, SocialPage icon backgrounds (4 instances) - decorative header icons
- DashboardPage: activity item icon gradient background (decorative)
- FileManagerView: selection banner background (decorative)
- Total: ~8 files, ~9 instances replaced
- Preserved: Active/selected states (StudioView active tab, AccountSettings selected theme, SessionManagement current session), primary actions, informational alerts
- Action 11.3.1.3 in progress (first batch: decorative backgrounds)
2026-01-16 10:03:48 +00:00
|
|
|
<span className="text-sm font-bold text-kodo-steel">
|
2026-01-13 18:47:57 +00:00
|
|
|
{selectedFiles.length} Selected
|
|
|
|
|
</span>
|
|
|
|
|
<div className="h-4 w-px bg-kodo-cyan/30 mx-2"></div>
|
|
|
|
|
<button
|
|
|
|
|
onClick={() => handleBulkAction('Downloaded')}
|
2026-01-16 00:49:52 +00:00
|
|
|
className="text-kodo-text-main hover:text-white"
|
2026-01-13 18:47:57 +00:00
|
|
|
title="Download"
|
|
|
|
|
>
|
|
|
|
|
<Download className="w-4 h-4" />
|
|
|
|
|
</button>
|
|
|
|
|
<button
|
|
|
|
|
onClick={() => handleBulkAction('Moved')}
|
2026-01-16 00:49:52 +00:00
|
|
|
className="text-kodo-text-main hover:text-white"
|
2026-01-13 18:47:57 +00:00
|
|
|
title="Move"
|
|
|
|
|
>
|
|
|
|
|
<Move className="w-4 h-4" />
|
|
|
|
|
</button>
|
|
|
|
|
<button
|
|
|
|
|
onClick={() => handleBulkAction('Deleted')}
|
2026-01-16 00:49:52 +00:00
|
|
|
className="text-kodo-red hover:text-kodo-red/80"
|
2026-01-13 18:47:57 +00:00
|
|
|
title="Delete"
|
|
|
|
|
>
|
|
|
|
|
<Trash2 className="w-4 h-4" />
|
|
|
|
|
</button>
|
|
|
|
|
</div>
|
|
|
|
|
) : (
|
|
|
|
|
<div className="flex gap-2">
|
|
|
|
|
<Button
|
|
|
|
|
variant="ghost"
|
|
|
|
|
size="sm"
|
|
|
|
|
icon={<Filter className="w-3 h-3" />}
|
|
|
|
|
>
|
|
|
|
|
Type
|
|
|
|
|
</Button>
|
|
|
|
|
<Button
|
|
|
|
|
variant="ghost"
|
|
|
|
|
size="sm"
|
|
|
|
|
icon={<Filter className="w-3 h-3" />}
|
|
|
|
|
>
|
|
|
|
|
Date
|
|
|
|
|
</Button>
|
|
|
|
|
</div>
|
2026-01-07 09:31:02 +00:00
|
|
|
)}
|
2026-01-13 18:47:57 +00:00
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{/* Content Area */}
|
|
|
|
|
<div className="min-h-[500px]">
|
|
|
|
|
{viewMode === 'list' ? (
|
|
|
|
|
<Card variant="default" className="p-0 overflow-hidden">
|
|
|
|
|
<div className="overflow-x-auto">
|
|
|
|
|
<table className="w-full text-left border-collapse">
|
|
|
|
|
<thead>
|
2026-01-16 00:49:52 +00:00
|
|
|
<tr className="border-b border-kodo-steel bg-kodo-ink/50 text-xs font-mono text-kodo-content-dim uppercase tracking-wider">
|
2026-01-13 18:47:57 +00:00
|
|
|
<th className="p-4 w-10">
|
|
|
|
|
<div
|
|
|
|
|
onClick={selectAll}
|
|
|
|
|
className="cursor-pointer hover:text-white"
|
|
|
|
|
>
|
|
|
|
|
{selectedFiles.length === MOCK_FILES.length ? (
|
aesthetic-improvements: reduce decorative cyan in player, library, and views (80/20 rule, batch 12)
- Player: VisualizerSettingsModal decorative icon (1 instance)
- Library: QueueView decorative artist text, AutoMetadataDetectionModal decorative icon and loading spinner border and fileName text and detected key text, SaveQueueAsPlaylistModal decorative icon, EditPlaylistModal decorative icon, PlaylistsView loading spinner, CreatePlaylistModal decorative icon (7 instances)
- Views: StudioView decorative icon, FileDetailsView decorative icon, GearView decorative icons and order number text, ProfileView loading spinner and social icons, AnalyticsView loading spinner and decorative chart legend dot and chart bars and device icon and revenue text, DiscoverView loading spinner and decorative icon and weekly mix text, FileManagerView decorative music icons (14 instances)
- Total: ~22 files, ~22 instances replaced
- Preserved: Active/selected states (LyricsPanel autoScroll active state, VisualizerSettingsModal selected mode, PlayerControls shuffle/repeatMode/showVisualizer active states, MiniPlayer isQueueOpen active state, AddToPlaylistModal selected playlist, PlaylistDetailView dragged item, StudioView active tab, SearchBar focused state, CheckoutView checkbox accents - focus/interaction, SearchPageView radio button accent - focus/interaction, FileManagerView selected files checkmarks - active states, ProfileView social links - functional links, LiveView links - functional links), primary actions, design system variants
- Action 11.3.1.3 in progress (twelfth batch: player, library, and views components)
2026-01-16 10:30:07 +00:00
|
|
|
<CheckSquare className="w-4 h-4 text-kodo-steel" />
|
2026-01-13 18:47:57 +00:00
|
|
|
) : (
|
|
|
|
|
<Square className="w-4 h-4" />
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
</th>
|
|
|
|
|
<th className="p-4">Name</th>
|
|
|
|
|
<th className="p-4">Type</th>
|
|
|
|
|
<th className="p-4">Size</th>
|
|
|
|
|
<th className="p-4">Modified</th>
|
|
|
|
|
<th className="p-4">Status</th>
|
|
|
|
|
<th className="p-4 text-right">Actions</th>
|
|
|
|
|
</tr>
|
|
|
|
|
</thead>
|
|
|
|
|
<tbody className="divide-y divide-kodo-steel/30">
|
|
|
|
|
{filteredFiles.map((file) => (
|
|
|
|
|
<tr
|
|
|
|
|
key={file.id}
|
|
|
|
|
className={`group hover:bg-white/5 transition-colors ${selectedFiles.includes(file.id) ? 'bg-kodo-cyan/5' : ''}`}
|
|
|
|
|
>
|
|
|
|
|
<td className="p-4">
|
|
|
|
|
<div
|
|
|
|
|
onClick={() => toggleSelection(file.id)}
|
2026-01-16 00:49:52 +00:00
|
|
|
className="cursor-pointer text-kodo-content-dim hover:text-white"
|
2026-01-13 18:47:57 +00:00
|
|
|
>
|
|
|
|
|
{selectedFiles.includes(file.id) ? (
|
aesthetic-improvements: reduce decorative cyan in player, library, and views (80/20 rule, batch 12)
- Player: VisualizerSettingsModal decorative icon (1 instance)
- Library: QueueView decorative artist text, AutoMetadataDetectionModal decorative icon and loading spinner border and fileName text and detected key text, SaveQueueAsPlaylistModal decorative icon, EditPlaylistModal decorative icon, PlaylistsView loading spinner, CreatePlaylistModal decorative icon (7 instances)
- Views: StudioView decorative icon, FileDetailsView decorative icon, GearView decorative icons and order number text, ProfileView loading spinner and social icons, AnalyticsView loading spinner and decorative chart legend dot and chart bars and device icon and revenue text, DiscoverView loading spinner and decorative icon and weekly mix text, FileManagerView decorative music icons (14 instances)
- Total: ~22 files, ~22 instances replaced
- Preserved: Active/selected states (LyricsPanel autoScroll active state, VisualizerSettingsModal selected mode, PlayerControls shuffle/repeatMode/showVisualizer active states, MiniPlayer isQueueOpen active state, AddToPlaylistModal selected playlist, PlaylistDetailView dragged item, StudioView active tab, SearchBar focused state, CheckoutView checkbox accents - focus/interaction, SearchPageView radio button accent - focus/interaction, FileManagerView selected files checkmarks - active states, ProfileView social links - functional links, LiveView links - functional links), primary actions, design system variants
- Action 11.3.1.3 in progress (twelfth batch: player, library, and views components)
2026-01-16 10:30:07 +00:00
|
|
|
<CheckSquare className="w-4 h-4 text-kodo-steel" />
|
2026-01-13 18:47:57 +00:00
|
|
|
) : (
|
|
|
|
|
<Square className="w-4 h-4" />
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
</td>
|
|
|
|
|
<td className="p-4">
|
|
|
|
|
<div
|
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 10:50:46 +00:00
|
|
|
className="flex items-center gap-4 cursor-pointer"
|
2026-01-13 18:47:57 +00:00
|
|
|
onClick={() => handleFileClick(file)}
|
|
|
|
|
>
|
|
|
|
|
{file.type === 'folder' && (
|
|
|
|
|
<Folder className="w-5 h-5 text-kodo-gold" />
|
|
|
|
|
)}
|
|
|
|
|
{file.type === 'audio' && (
|
aesthetic-improvements: reduce decorative cyan in player, library, and views (80/20 rule, batch 12)
- Player: VisualizerSettingsModal decorative icon (1 instance)
- Library: QueueView decorative artist text, AutoMetadataDetectionModal decorative icon and loading spinner border and fileName text and detected key text, SaveQueueAsPlaylistModal decorative icon, EditPlaylistModal decorative icon, PlaylistsView loading spinner, CreatePlaylistModal decorative icon (7 instances)
- Views: StudioView decorative icon, FileDetailsView decorative icon, GearView decorative icons and order number text, ProfileView loading spinner and social icons, AnalyticsView loading spinner and decorative chart legend dot and chart bars and device icon and revenue text, DiscoverView loading spinner and decorative icon and weekly mix text, FileManagerView decorative music icons (14 instances)
- Total: ~22 files, ~22 instances replaced
- Preserved: Active/selected states (LyricsPanel autoScroll active state, VisualizerSettingsModal selected mode, PlayerControls shuffle/repeatMode/showVisualizer active states, MiniPlayer isQueueOpen active state, AddToPlaylistModal selected playlist, PlaylistDetailView dragged item, StudioView active tab, SearchBar focused state, CheckoutView checkbox accents - focus/interaction, SearchPageView radio button accent - focus/interaction, FileManagerView selected files checkmarks - active states, ProfileView social links - functional links, LiveView links - functional links), primary actions, design system variants
- Action 11.3.1.3 in progress (twelfth batch: player, library, and views components)
2026-01-16 10:30:07 +00:00
|
|
|
<Music className="w-5 h-5 text-kodo-steel" />
|
2026-01-13 18:47:57 +00:00
|
|
|
)}
|
|
|
|
|
{file.type === 'image' && (
|
|
|
|
|
<ImageIcon className="w-5 h-5 text-kodo-magenta" />
|
|
|
|
|
)}
|
|
|
|
|
{['document', 'archive', 'project'].includes(
|
|
|
|
|
file.type,
|
2026-01-16 00:49:52 +00:00
|
|
|
) && <File className="w-5 h-5 text-kodo-content-dim" />}
|
|
|
|
|
<span className="font-medium text-kodo-text-main group-hover:text-white transition-colors">
|
2026-01-13 18:47:57 +00:00
|
|
|
{file.name}
|
|
|
|
|
</span>
|
|
|
|
|
</div>
|
|
|
|
|
</td>
|
|
|
|
|
<td className="p-4">
|
2026-01-16 00:49:52 +00:00
|
|
|
<span className="px-2 py-1 bg-kodo-ink rounded text-[10px] uppercase font-bold text-kodo-content-dim">
|
2026-01-13 18:47:57 +00:00
|
|
|
{file.type}
|
|
|
|
|
</span>
|
|
|
|
|
</td>
|
2026-01-16 00:49:52 +00:00
|
|
|
<td className="p-4 text-sm text-kodo-content-dim font-mono">
|
2026-01-13 18:47:57 +00:00
|
|
|
{file.size}
|
|
|
|
|
</td>
|
2026-01-16 00:49:52 +00:00
|
|
|
<td className="p-4 text-sm text-kodo-content-dim">
|
2026-01-13 18:47:57 +00:00
|
|
|
{file.modified}
|
|
|
|
|
</td>
|
|
|
|
|
<td className="p-4">
|
|
|
|
|
<span
|
2026-01-16 00:49:52 +00:00
|
|
|
className={`flex items-center gap-1.5 text-xs font-bold capitalize ${file.status === 'ready' ? 'text-kodo-lime' : file.status === 'processing' ? 'text-kodo-gold' : 'text-kodo-content-dim'}`}
|
2026-01-13 18:47:57 +00:00
|
|
|
>
|
|
|
|
|
<div
|
2026-01-16 00:49:52 +00:00
|
|
|
className={`w-1.5 h-1.5 rounded-full ${file.status === 'ready' ? 'bg-kodo-lime' : file.status === 'processing' ? 'bg-kodo-gold animate-pulse' : 'bg-kodo-steel'}`}
|
2026-01-13 18:47:57 +00:00
|
|
|
></div>
|
|
|
|
|
{file.status}
|
|
|
|
|
</span>
|
|
|
|
|
</td>
|
|
|
|
|
<td className="p-4 text-right">
|
|
|
|
|
<div className="flex justify-end gap-2 opacity-0 group-hover:opacity-100 transition-opacity">
|
consistency: replace custom buttons with Button component (partial)
- Replaced custom button implementations with Button component in 14 files
- Files updated: LiveStreamDetailView, DashboardPage, CommentItem, PostCard, SocialPage, SocialView, AdminUsersView, UserTableRow, ProjectsManager, CloudFileBrowser, FileManagerView, CreatorModal, ImageCropper, BulkUploadModal
- ~31 buttons replaced across high-priority files
- Used appropriate Button variants: ghost, outline, default, secondary, link
- Preserved visual appearance with className overrides where needed
- Action 9.2.1.2 in progress (partial completion)
2026-01-16 01:06:14 +00:00
|
|
|
<Button
|
|
|
|
|
variant="ghost"
|
|
|
|
|
size="icon"
|
|
|
|
|
className="p-1.5"
|
|
|
|
|
onClick={() => handleFileClick(file)}
|
|
|
|
|
>
|
|
|
|
|
<Eye className="w-4 h-4" />
|
|
|
|
|
</Button>
|
|
|
|
|
<Button variant="ghost" size="icon" className="p-1.5">
|
2026-01-13 18:47:57 +00:00
|
|
|
<MoreVertical className="w-4 h-4" />
|
consistency: replace custom buttons with Button component (partial)
- Replaced custom button implementations with Button component in 14 files
- Files updated: LiveStreamDetailView, DashboardPage, CommentItem, PostCard, SocialPage, SocialView, AdminUsersView, UserTableRow, ProjectsManager, CloudFileBrowser, FileManagerView, CreatorModal, ImageCropper, BulkUploadModal
- ~31 buttons replaced across high-priority files
- Used appropriate Button variants: ghost, outline, default, secondary, link
- Preserved visual appearance with className overrides where needed
- Action 9.2.1.2 in progress (partial completion)
2026-01-16 01:06:14 +00:00
|
|
|
</Button>
|
2026-01-13 18:47:57 +00:00
|
|
|
</div>
|
|
|
|
|
</td>
|
|
|
|
|
</tr>
|
|
|
|
|
))}
|
|
|
|
|
</tbody>
|
|
|
|
|
</table>
|
|
|
|
|
</div>
|
|
|
|
|
</Card>
|
|
|
|
|
) : (
|
|
|
|
|
<div className="grid grid-cols-2 md:grid-cols-4 lg:grid-cols-5 gap-4">
|
|
|
|
|
{filteredFiles.map((file) => (
|
|
|
|
|
<Card
|
|
|
|
|
key={file.id}
|
|
|
|
|
variant="default"
|
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 10:50:46 +00:00
|
|
|
className={`p-4 flex flex-col items-center text-center gap-4 cursor-pointer hover:border-kodo-steel/50 transition-all group relative ${selectedFiles.includes(file.id) ? 'border-kodo-cyan bg-kodo-cyan/5' : ''}`}
|
2026-01-13 18:47:57 +00:00
|
|
|
onClick={() => handleFileClick(file)}
|
|
|
|
|
>
|
|
|
|
|
<div
|
|
|
|
|
className="absolute top-2 right-2 opacity-0 group-hover:opacity-100 transition-opacity"
|
|
|
|
|
onClick={(e) => {
|
|
|
|
|
e.stopPropagation();
|
|
|
|
|
toggleSelection(file.id);
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
{selectedFiles.includes(file.id) ? (
|
|
|
|
|
<CheckSquare className="w-4 h-4 text-kodo-cyan" />
|
|
|
|
|
) : (
|
2026-01-16 00:49:52 +00:00
|
|
|
<Square className="w-4 h-4 text-kodo-content-dim hover:text-white" />
|
2026-01-13 18:47:57 +00:00
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
|
2026-01-16 11:02:55 +00:00
|
|
|
<div className="w-16 h-16 rounded-2xl bg-kodo-ink flex items-center justify-center shadow-lg transition-colors duration-200">
|
2026-01-13 18:47:57 +00:00
|
|
|
{file.type === 'folder' && (
|
|
|
|
|
<Folder className="w-8 h-8 text-kodo-gold" />
|
|
|
|
|
)}
|
|
|
|
|
{file.type === 'audio' && (
|
aesthetic-improvements: reduce decorative cyan in player, library, and views (80/20 rule, batch 12)
- Player: VisualizerSettingsModal decorative icon (1 instance)
- Library: QueueView decorative artist text, AutoMetadataDetectionModal decorative icon and loading spinner border and fileName text and detected key text, SaveQueueAsPlaylistModal decorative icon, EditPlaylistModal decorative icon, PlaylistsView loading spinner, CreatePlaylistModal decorative icon (7 instances)
- Views: StudioView decorative icon, FileDetailsView decorative icon, GearView decorative icons and order number text, ProfileView loading spinner and social icons, AnalyticsView loading spinner and decorative chart legend dot and chart bars and device icon and revenue text, DiscoverView loading spinner and decorative icon and weekly mix text, FileManagerView decorative music icons (14 instances)
- Total: ~22 files, ~22 instances replaced
- Preserved: Active/selected states (LyricsPanel autoScroll active state, VisualizerSettingsModal selected mode, PlayerControls shuffle/repeatMode/showVisualizer active states, MiniPlayer isQueueOpen active state, AddToPlaylistModal selected playlist, PlaylistDetailView dragged item, StudioView active tab, SearchBar focused state, CheckoutView checkbox accents - focus/interaction, SearchPageView radio button accent - focus/interaction, FileManagerView selected files checkmarks - active states, ProfileView social links - functional links, LiveView links - functional links), primary actions, design system variants
- Action 11.3.1.3 in progress (twelfth batch: player, library, and views components)
2026-01-16 10:30:07 +00:00
|
|
|
<Music className="w-8 h-8 text-kodo-steel" />
|
2026-01-13 18:47:57 +00:00
|
|
|
)}
|
|
|
|
|
{file.type === 'image' && (
|
|
|
|
|
<ImageIcon className="w-8 h-8 text-kodo-magenta" />
|
|
|
|
|
)}
|
|
|
|
|
{['document', 'archive', 'project'].includes(file.type) && (
|
2026-01-16 00:49:52 +00:00
|
|
|
<File className="w-8 h-8 text-kodo-content-dim" />
|
2026-01-13 18:47:57 +00:00
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
<div className="w-full">
|
|
|
|
|
<h4 className="font-bold text-white text-sm truncate w-full">
|
|
|
|
|
{file.name}
|
|
|
|
|
</h4>
|
2026-01-16 00:49:52 +00:00
|
|
|
<p className="text-xs text-kodo-content-dim mt-1">{file.size}</p>
|
2026-01-13 18:47:57 +00:00
|
|
|
</div>
|
|
|
|
|
</Card>
|
|
|
|
|
))}
|
|
|
|
|
</div>
|
2026-01-07 09:31:02 +00:00
|
|
|
)}
|
2026-01-13 18:47:57 +00:00
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{/* Modals */}
|
|
|
|
|
{showMetadataModal && (
|
|
|
|
|
<AutoMetadataDetectionModal
|
|
|
|
|
fileName={
|
|
|
|
|
selectedFileId
|
|
|
|
|
? MOCK_FILES.find((f) => f.id === selectedFileId)?.name ||
|
|
|
|
|
'Selected File'
|
|
|
|
|
: 'Scan Library'
|
|
|
|
|
}
|
|
|
|
|
onClose={() => setShowMetadataModal(false)}
|
|
|
|
|
onApply={(data) => {
|
|
|
|
|
addToast(`Applied: ${data.genre} - ${data.bpm}BPM`, 'success');
|
|
|
|
|
setShowMetadataModal(false);
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
)}
|
|
|
|
|
{showWatermarkModal && (
|
|
|
|
|
<WatermarkSettingsModal
|
|
|
|
|
onClose={() => setShowWatermarkModal(false)}
|
|
|
|
|
onSave={() => addToast('Watermark settings updated', 'success')}
|
|
|
|
|
/>
|
|
|
|
|
)}
|
2026-01-07 09:31:02 +00:00
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
};
|