2026-01-07 09:31:02 +00:00
|
|
|
import React from 'react';
|
|
|
|
|
import { Card } from '../ui/card';
|
|
|
|
|
import { Button } from '../ui/button';
|
|
|
|
|
import { Badge } from '../ui/badge';
|
|
|
|
|
import { FileNode } from '../../types';
|
2026-01-13 18:47:57 +00:00
|
|
|
import {
|
|
|
|
|
ArrowLeft,
|
|
|
|
|
Download,
|
|
|
|
|
Share2,
|
|
|
|
|
Trash2,
|
|
|
|
|
Edit3,
|
|
|
|
|
Music,
|
|
|
|
|
FileText,
|
|
|
|
|
Play,
|
|
|
|
|
Activity,
|
|
|
|
|
Layers,
|
|
|
|
|
HardDrive,
|
|
|
|
|
Info,
|
2026-01-07 09:31:02 +00:00
|
|
|
} from 'lucide-react';
|
|
|
|
|
import { useToast } from '../../context/ToastContext';
|
|
|
|
|
|
|
|
|
|
// Extended Mock Data for Demo
|
|
|
|
|
const MOCK_ACTIVITY = [
|
2026-01-13 18:47:57 +00:00
|
|
|
{
|
|
|
|
|
id: 'a1',
|
|
|
|
|
user: 'Cyber_Producer',
|
|
|
|
|
action: 'uploaded',
|
|
|
|
|
timestamp: '2 days ago',
|
|
|
|
|
},
|
|
|
|
|
{ id: 'a2', user: 'Sarah Connor', action: 'viewed', timestamp: '1 day ago' },
|
|
|
|
|
{ id: 'a3', user: 'System', action: 'processed', timestamp: '2 days ago' },
|
2026-01-07 09:31:02 +00:00
|
|
|
];
|
|
|
|
|
|
|
|
|
|
const MOCK_VERSIONS = [
|
2026-01-13 18:47:57 +00:00
|
|
|
{
|
|
|
|
|
id: 'v1',
|
|
|
|
|
version: 'v1.0',
|
|
|
|
|
uploadedBy: 'Cyber_Producer',
|
|
|
|
|
timestamp: '2 days ago',
|
|
|
|
|
size: '24.5 MB',
|
|
|
|
|
url: '#',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
id: 'v2',
|
|
|
|
|
version: 'v1.1',
|
|
|
|
|
uploadedBy: 'Cyber_Producer',
|
|
|
|
|
timestamp: '5 hours ago',
|
|
|
|
|
size: '24.6 MB',
|
|
|
|
|
url: '#',
|
|
|
|
|
current: true,
|
|
|
|
|
},
|
2026-01-07 09:31:02 +00:00
|
|
|
];
|
|
|
|
|
|
|
|
|
|
interface FileDetailsViewProps {
|
|
|
|
|
fileId: string;
|
|
|
|
|
onBack: () => void;
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-13 18:47:57 +00:00
|
|
|
export const FileDetailsView: React.FC<FileDetailsViewProps> = ({
|
|
|
|
|
fileId,
|
|
|
|
|
onBack,
|
|
|
|
|
}) => {
|
2026-01-07 09:31:02 +00:00
|
|
|
const { addToast } = useToast();
|
|
|
|
|
|
|
|
|
|
// Mock fetching logic based on ID
|
|
|
|
|
const file: FileNode = {
|
2026-01-13 18:47:57 +00:00
|
|
|
id: fileId,
|
|
|
|
|
name: 'Neon_Nights_Final_Master.wav',
|
|
|
|
|
type: 'audio',
|
|
|
|
|
size: '48.2 MB',
|
|
|
|
|
modified: '2 hours ago',
|
|
|
|
|
status: 'ready',
|
|
|
|
|
metadata: {
|
|
|
|
|
bpm: 128,
|
|
|
|
|
key: 'F# Minor',
|
|
|
|
|
genre: 'Synthwave',
|
|
|
|
|
duration: '3:45',
|
|
|
|
|
},
|
2026-01-07 09:31:02 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const isAudio = file.type === 'audio';
|
|
|
|
|
const isImage = file.type === 'image';
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<div className="animate-fadeIn space-y-6 pb-20">
|
2026-01-13 18:47:57 +00:00
|
|
|
{/* Header */}
|
|
|
|
|
<div className="flex items-center justify-between">
|
|
|
|
|
<div className="flex items-center gap-4">
|
|
|
|
|
<Button
|
|
|
|
|
variant="ghost"
|
|
|
|
|
size="icon"
|
|
|
|
|
onClick={onBack}
|
|
|
|
|
aria-label="Retour"
|
|
|
|
|
>
|
|
|
|
|
<ArrowLeft className="w-5 h-5" />
|
|
|
|
|
</Button>
|
|
|
|
|
<div>
|
|
|
|
|
<h2 className="text-2xl font-bold text-white flex items-center gap-3">
|
|
|
|
|
{file.name}
|
|
|
|
|
<Badge label={file.type} variant="terminal" />
|
|
|
|
|
</h2>
|
|
|
|
|
<p className="text-gray-400 text-sm font-mono flex items-center gap-4 mt-1">
|
|
|
|
|
<span>{file.size}</span>
|
|
|
|
|
<span>•</span>
|
|
|
|
|
<span>Modified {file.modified}</span>
|
|
|
|
|
</p>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div className="flex gap-2">
|
|
|
|
|
<Button
|
|
|
|
|
variant="ghost"
|
|
|
|
|
icon={<Share2 className="w-4 h-4" />}
|
|
|
|
|
onClick={() => addToast('Link copied')}
|
|
|
|
|
>
|
|
|
|
|
Share
|
|
|
|
|
</Button>
|
|
|
|
|
<Button
|
|
|
|
|
variant="primary"
|
|
|
|
|
icon={<Download className="w-4 h-4" />}
|
|
|
|
|
onClick={() => addToast('Downloading...')}
|
|
|
|
|
>
|
|
|
|
|
Download
|
|
|
|
|
</Button>
|
|
|
|
|
<Button
|
|
|
|
|
variant="ghost"
|
|
|
|
|
className="text-kodo-red hover:bg-kodo-red/10"
|
|
|
|
|
icon={<Trash2 className="w-4 h-4" />}
|
|
|
|
|
>
|
|
|
|
|
Delete
|
|
|
|
|
</Button>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div className="grid grid-cols-1 lg:grid-cols-3 gap-8">
|
|
|
|
|
{/* Left: Preview Area */}
|
|
|
|
|
<div className="lg:col-span-2 space-y-6">
|
|
|
|
|
<Card
|
|
|
|
|
variant="default"
|
|
|
|
|
className="min-h-[400px] flex items-center justify-center bg-black relative overflow-hidden group"
|
|
|
|
|
>
|
|
|
|
|
{isAudio && (
|
|
|
|
|
<div className="text-center w-full max-w-md">
|
|
|
|
|
<div className="w-32 h-32 bg-gradient-to-br from-kodo-cyan to-blue-600 rounded-full mx-auto mb-8 flex items-center justify-center shadow-[0_0_50px_rgba(102,252,241,0.3)] animate-pulse">
|
|
|
|
|
<Music className="w-12 h-12 text-black" />
|
2026-01-07 09:31:02 +00:00
|
|
|
</div>
|
2026-01-13 18:47:57 +00:00
|
|
|
<div className="h-16 flex items-center justify-center gap-1 mb-8">
|
|
|
|
|
{Array.from({ length: 40 }).map((_, i) => (
|
|
|
|
|
<div
|
|
|
|
|
key={i}
|
|
|
|
|
className="w-1.5 bg-kodo-cyan rounded-full"
|
|
|
|
|
style={{ height: `${Math.random() * 100}%` }}
|
|
|
|
|
></div>
|
|
|
|
|
))}
|
|
|
|
|
</div>
|
|
|
|
|
<Button
|
|
|
|
|
variant="primary"
|
|
|
|
|
size="lg"
|
|
|
|
|
className="rounded-full px-8"
|
|
|
|
|
icon={<Play className="w-5 h-5 fill-current" />}
|
|
|
|
|
>
|
|
|
|
|
PLAY PREVIEW
|
|
|
|
|
</Button>
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
{isImage && (
|
|
|
|
|
<img
|
|
|
|
|
src="https://picsum.photos/id/200/800/600"
|
|
|
|
|
className="w-full h-full object-contain"
|
|
|
|
|
/>
|
|
|
|
|
)}
|
|
|
|
|
{!isAudio && !isImage && (
|
|
|
|
|
<div className="text-center text-gray-500">
|
|
|
|
|
<FileText className="w-24 h-24 mx-auto mb-4 opacity-50" />
|
|
|
|
|
<p>No preview available for this file type.</p>
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
</Card>
|
|
|
|
|
|
|
|
|
|
{/* Metadata Grid */}
|
|
|
|
|
<Card variant="default">
|
|
|
|
|
<div className="flex justify-between items-center mb-6">
|
|
|
|
|
<h3 className="font-bold text-white flex items-center gap-2">
|
|
|
|
|
<Info className="w-4 h-4 text-kodo-cyan" /> Metadata
|
|
|
|
|
</h3>
|
|
|
|
|
<Button
|
|
|
|
|
variant="ghost"
|
|
|
|
|
size="sm"
|
|
|
|
|
icon={<Edit3 className="w-3 h-3" />}
|
|
|
|
|
>
|
|
|
|
|
Edit
|
|
|
|
|
</Button>
|
2026-01-07 09:31:02 +00:00
|
|
|
</div>
|
2026-01-13 18:47:57 +00:00
|
|
|
<div className="grid grid-cols-2 md:grid-cols-4 gap-4">
|
|
|
|
|
{Object.entries(file.metadata || {}).map(([key, val]) => (
|
|
|
|
|
<div
|
|
|
|
|
key={key}
|
|
|
|
|
className="bg-kodo-ink p-3 rounded border border-kodo-steel/50"
|
|
|
|
|
>
|
|
|
|
|
<div className="text-xs text-gray-500 uppercase font-bold mb-1">
|
|
|
|
|
{key}
|
|
|
|
|
</div>
|
|
|
|
|
<div className="text-white font-medium">{String(val)}</div>
|
|
|
|
|
</div>
|
|
|
|
|
))}
|
2026-01-07 09:31:02 +00:00
|
|
|
</div>
|
2026-01-13 18:47:57 +00:00
|
|
|
</Card>
|
2026-01-07 09:31:02 +00:00
|
|
|
</div>
|
|
|
|
|
|
2026-01-13 18:47:57 +00:00
|
|
|
{/* Right: Sidebar */}
|
|
|
|
|
<div className="space-y-6">
|
|
|
|
|
{/* Activity Feed */}
|
|
|
|
|
<Card variant="gaming">
|
|
|
|
|
<h3 className="font-bold text-white mb-4 flex items-center gap-2 text-sm uppercase tracking-wider">
|
|
|
|
|
<Activity className="w-4 h-4 text-kodo-gold" /> Activity Log
|
|
|
|
|
</h3>
|
|
|
|
|
<div className="space-y-4 relative">
|
|
|
|
|
<div className="absolute left-3 top-2 bottom-2 w-px bg-kodo-steel"></div>
|
|
|
|
|
{MOCK_ACTIVITY.map((act) => (
|
|
|
|
|
<div key={act.id} className="flex gap-3 relative">
|
|
|
|
|
<div className="w-6 h-6 rounded-full bg-kodo-graphite border border-kodo-steel flex items-center justify-center shrink-0 z-10">
|
|
|
|
|
<div className="w-2 h-2 rounded-full bg-kodo-gold"></div>
|
|
|
|
|
</div>
|
|
|
|
|
<div>
|
|
|
|
|
<p className="text-sm text-gray-300">
|
|
|
|
|
<span className="font-bold text-white">{act.user}</span>{' '}
|
|
|
|
|
{act.action} this file.
|
|
|
|
|
</p>
|
|
|
|
|
<p className="text-xs text-gray-500">{act.timestamp}</p>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
))}
|
2026-01-07 09:31:02 +00:00
|
|
|
</div>
|
2026-01-13 18:47:57 +00:00
|
|
|
</Card>
|
2026-01-07 09:31:02 +00:00
|
|
|
|
2026-01-13 18:47:57 +00:00
|
|
|
{/* Versions */}
|
|
|
|
|
<Card variant="default">
|
|
|
|
|
<h3 className="font-bold text-white mb-4 flex items-center gap-2 text-sm uppercase tracking-wider">
|
|
|
|
|
<Layers className="w-4 h-4 text-kodo-magenta" /> Version History
|
|
|
|
|
</h3>
|
|
|
|
|
<div className="space-y-2">
|
|
|
|
|
{MOCK_VERSIONS.map((ver) => (
|
|
|
|
|
<div
|
|
|
|
|
key={ver.id}
|
|
|
|
|
className={`flex items-center justify-between p-3 rounded border ${ver.current ? 'bg-kodo-magenta/10 border-kodo-magenta/30' : 'bg-kodo-ink border-kodo-steel hover:bg-white/5'}`}
|
|
|
|
|
>
|
|
|
|
|
<div>
|
|
|
|
|
<div className="flex items-center gap-2">
|
|
|
|
|
<span className="font-bold text-white text-sm">
|
|
|
|
|
{ver.version}
|
|
|
|
|
</span>
|
|
|
|
|
{ver.current && (
|
|
|
|
|
<span className="text-[10px] bg-kodo-magenta text-white px-1.5 rounded">
|
|
|
|
|
LATEST
|
|
|
|
|
</span>
|
|
|
|
|
)}
|
2026-01-07 09:31:02 +00:00
|
|
|
</div>
|
2026-01-13 18:47:57 +00:00
|
|
|
<div className="text-xs text-gray-500">
|
|
|
|
|
{ver.timestamp} • {ver.uploadedBy}
|
2026-01-07 09:31:02 +00:00
|
|
|
</div>
|
2026-01-13 18:47:57 +00:00
|
|
|
</div>
|
|
|
|
|
<Button
|
|
|
|
|
variant="ghost"
|
|
|
|
|
size="icon"
|
|
|
|
|
className="h-8 w-8"
|
|
|
|
|
aria-label="Télécharger"
|
|
|
|
|
>
|
|
|
|
|
<Download className="w-3 h-3" />
|
|
|
|
|
</Button>
|
2026-01-07 09:31:02 +00:00
|
|
|
</div>
|
2026-01-13 18:47:57 +00:00
|
|
|
))}
|
|
|
|
|
</div>
|
|
|
|
|
</Card>
|
|
|
|
|
|
|
|
|
|
{/* Storage Info */}
|
|
|
|
|
<div className="bg-kodo-ink p-4 rounded-xl border border-kodo-steel flex items-center gap-4">
|
|
|
|
|
<div className="w-10 h-10 bg-kodo-slate rounded-lg flex items-center justify-center text-gray-400">
|
|
|
|
|
<HardDrive className="w-5 h-5" />
|
|
|
|
|
</div>
|
|
|
|
|
<div>
|
|
|
|
|
<div className="text-xs text-gray-500 uppercase">
|
|
|
|
|
Storage Location
|
|
|
|
|
</div>
|
|
|
|
|
<div className="text-sm font-bold text-white">
|
|
|
|
|
s3://veza-cloud/projects/alpha
|
|
|
|
|
</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
|
|
|
</div>
|
2026-01-13 18:47:57 +00:00
|
|
|
</div>
|
2026-01-07 09:31:02 +00:00
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
};
|