187 lines
9.4 KiB
TypeScript
187 lines
9.4 KiB
TypeScript
|
|
|
||
|
|
import React from 'react';
|
||
|
|
import { Card } from '../ui/card';
|
||
|
|
import { Button } from '../ui/button';
|
||
|
|
import { Badge } from '../ui/badge';
|
||
|
|
import { FileNode } from '../../types';
|
||
|
|
import {
|
||
|
|
ArrowLeft, Download, Share2, Trash2, Edit3,
|
||
|
|
Music, FileText, Play, Activity,
|
||
|
|
Layers, HardDrive, Info
|
||
|
|
} from 'lucide-react';
|
||
|
|
import { useToast } from '../../context/ToastContext';
|
||
|
|
|
||
|
|
// Extended Mock Data for Demo
|
||
|
|
const MOCK_ACTIVITY = [
|
||
|
|
{ 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' },
|
||
|
|
];
|
||
|
|
|
||
|
|
const MOCK_VERSIONS = [
|
||
|
|
{ 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 },
|
||
|
|
];
|
||
|
|
|
||
|
|
interface FileDetailsViewProps {
|
||
|
|
fileId: string;
|
||
|
|
onBack: () => void;
|
||
|
|
}
|
||
|
|
|
||
|
|
export const FileDetailsView: React.FC<FileDetailsViewProps> = ({ fileId, onBack }) => {
|
||
|
|
const { addToast } = useToast();
|
||
|
|
|
||
|
|
// Mock fetching logic based on ID
|
||
|
|
const file: FileNode = {
|
||
|
|
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'
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
const isAudio = file.type === 'audio';
|
||
|
|
const isImage = file.type === 'image';
|
||
|
|
|
||
|
|
return (
|
||
|
|
<div className="animate-fadeIn space-y-6 pb-20">
|
||
|
|
{/* 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" />
|
||
|
|
</div>
|
||
|
|
<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>
|
||
|
|
</div>
|
||
|
|
<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>
|
||
|
|
))}
|
||
|
|
</div>
|
||
|
|
</Card>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
{/* 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>
|
||
|
|
))}
|
||
|
|
</div>
|
||
|
|
</Card>
|
||
|
|
|
||
|
|
{/* 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>}
|
||
|
|
</div>
|
||
|
|
<div className="text-xs text-gray-500">{ver.timestamp} • {ver.uploadedBy}</div>
|
||
|
|
</div>
|
||
|
|
<Button variant="ghost" size="icon" className="h-8 w-8" aria-label="Télécharger"><Download className="w-3 h-3" /></Button>
|
||
|
|
</div>
|
||
|
|
))}
|
||
|
|
</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>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
);
|
||
|
|
};
|