MCPcopy Create free account
hub / github.com/NanmiCoder/MediaCrawler / FileCard

Function FileCard

webui/src/components/data/FileCard.tsx:46–132  ·  view source on GitHub ↗
({ file }: FileCardProps)

Source from the content-addressed store, hash-verified

44}
45
46export function FileCard({ file }: FileCardProps) {
47 const { t } = useTranslation('data')
48 const [previewOpen, setPreviewOpen] = useState(false)
49
50 const Icon = fileIcons[file.type] || FileText
51 const styles = fileStyles[file.type] || {
52 icon: 'text-cyber-text-muted',
53 border: 'hover:border-cyber-neon-cyan/50',
54 badge: 'border-cyber-border-DEFAULT bg-cyber-bg-tertiary text-cyber-text-secondary'
55 }
56
57 // 检查是否支持预览
58 const isPreviewable = ['json', 'csv', 'xlsx', 'xls'].includes(file.type.toLowerCase())
59
60 const handleDownload = () => {
61 const url = dataApi.getDownloadUrl(file.path)
62 window.open(url, '_blank')
63 }
64
65 return (
66 <>
67 <Card className={`relative overflow-hidden card-scan group transition-all ${styles.border} hover:shadow-[0_0_15px_rgb(var(--cyber-neon-cyan)/0.15)]`}>
68 {/* Scan effect overlay */}
69 <div className="absolute inset-0 bg-gradient-to-r from-transparent via-cyber-neon-cyan/5 to-transparent -translate-x-full group-hover:translate-x-full transition-transform duration-700 pointer-events-none" />
70
71 <CardContent className="p-4 relative">
72 <div className="flex items-start gap-3">
73 <div className={`p-2 rounded bg-cyber-bg-panel border border-cyber-border-DEFAULT ${styles.icon}`}>
74 <Icon className="w-6 h-6" />
75 </div>
76 <div className="flex-1 min-w-0">
77 <h3 className="font-mono font-medium text-sm text-cyber-text-primary truncate" title={file.name}>
78 {file.name}
79 </h3>
80 <p className="text-xs text-cyber-text-muted mt-1 font-mono">
81 {formatFileSize(file.size)}
82 {file.record_count !== null && (
83 <span className="text-cyber-neon-green"> | {t('file.entries', { count: file.record_count })}</span>
84 )}
85 </p>
86 <p className="text-xs text-cyber-text-muted mt-1 font-mono">
87 {formatDateTime(file.modified_at)}
88 </p>
89 </div>
90 </div>
91
92 <div className="flex items-center justify-between mt-3 pt-3 border-t border-cyber-border-subtle">
93 <Badge variant="outline" className={`text-[10px] font-mono ${styles.badge}`}>
94 .{file.type.toUpperCase()}
95 </Badge>
96 <div className="flex gap-1 opacity-0 group-hover:opacity-100 transition-opacity">
97 {isPreviewable && (
98 <Button
99 variant="ghost"
100 size="sm"
101 className="h-7 px-2 font-mono text-cyber-neon-cyan hover:text-cyber-neon-cyan hover:bg-cyber-neon-cyan/10"
102 onClick={() => setPreviewOpen(true)}
103 >

Callers

nothing calls this directly

Calls 2

formatFileSizeFunction · 0.90
formatDateTimeFunction · 0.90

Tested by

no test coverage detected