- Restructured docker-compose for Nginx Proxy Manager (no custom nginx) - Added domain wordly.art configuration - Added Prometheus + Grafana monitoring stack with pre-configured dashboards - Added PostgreSQL backup script to NAS (daily/weekly/monthly rotation) - Added alert rules for backend, system, and Docker metrics - Updated deployment guide for NPM + IONOS DNS homelab setup - Added marketing plan document - PDF translator and watermark support - Enhanced middleware, routes, and translator modules Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
54 lines
1.5 KiB
TypeScript
54 lines
1.5 KiB
TypeScript
'use client';
|
|
|
|
import { FileSpreadsheet, FileText, Presentation, X } from 'lucide-react';
|
|
import { Button } from '@/components/ui/button';
|
|
|
|
const FILE_ICONS: Record<string, React.ElementType> = {
|
|
xlsx: FileSpreadsheet,
|
|
docx: FileText,
|
|
pptx: Presentation,
|
|
};
|
|
|
|
interface FilePreviewProps {
|
|
file: File;
|
|
onRemove: () => void;
|
|
}
|
|
|
|
function formatFileSize(bytes: number): string {
|
|
if (bytes < 1024) return `${bytes} B`;
|
|
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
|
|
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
}
|
|
|
|
export function FilePreview({ file, onRemove }: FilePreviewProps) {
|
|
const ext = file.name.split('.').pop()?.toLowerCase() || '';
|
|
const FileIcon = FILE_ICONS[ext] || FileText;
|
|
|
|
return (
|
|
<div className="flex items-center gap-3">
|
|
<div className="flex size-10 items-center justify-center rounded-lg bg-secondary">
|
|
<FileIcon className="size-5 text-foreground" />
|
|
</div>
|
|
<div className="flex flex-col min-w-0 flex-1">
|
|
<span className="text-sm font-medium text-foreground truncate">
|
|
{file.name}
|
|
</span>
|
|
<span className="text-xs text-muted-foreground">
|
|
{formatFileSize(file.size)} · .{ext}
|
|
</span>
|
|
</div>
|
|
<Button
|
|
variant="ghost"
|
|
size="icon-sm"
|
|
className="ms-2 text-muted-foreground hover:text-foreground shrink-0"
|
|
onClick={(e) => {
|
|
e.stopPropagation();
|
|
onRemove();
|
|
}}
|
|
>
|
|
<X className="size-4" />
|
|
</Button>
|
|
</div>
|
|
);
|
|
}
|