Enhance download center with file size preview and dual options

This commit is contained in:
backuppc
2026-01-21 15:11:57 +09:00
parent fc9500f99b
commit b31b3c6d31
2 changed files with 132 additions and 6 deletions

View File

@@ -0,0 +1,119 @@
import React, { useEffect, useState } from 'react';
import { Download, Package, Server, X } from 'lucide-react';
import { formatBytes } from '../utils/formatters';
interface DownloadModalProps {
isOpen: boolean;
onClose: () => void;
}
const DownloadModal: React.FC<DownloadModalProps> = ({ isOpen, onClose }) => {
const [sizes, setSizes] = useState({ full: 0, backend: 0 });
useEffect(() => {
if (isOpen) {
// Fetch sizes
const fetchSize = async (url: string, key: 'full' | 'backend') => {
try {
const res = await fetch(url, { method: 'HEAD' });
const len = res.headers.get('content-length');
if (len) setSizes(prev => ({ ...prev, [key]: parseInt(len, 10) }));
} catch (e) {
console.error("Failed to fetch size", e);
}
};
fetchSize(`${import.meta.env.BASE_URL}webftp.exe`, 'full');
fetchSize(`${import.meta.env.BASE_URL}webftp-backend.exe`, 'backend');
}
}, [isOpen]);
if (!isOpen) return null;
return (
<div className="fixed inset-0 z-50 flex items-center justify-center bg-black/50 backdrop-blur-sm">
<div className="bg-white rounded-lg shadow-xl w-[500px] max-w-full m-4 overflow-hidden animate-in fade-in zoom-in duration-200">
{/* Header */}
<div className="flex items-center justify-between px-4 py-3 border-b border-slate-100 bg-slate-50">
<h3 className="font-bold text-slate-800 flex items-center gap-2">
<Download size={20} className="text-blue-600" />
WebZilla
</h3>
<button onClick={onClose} className="text-slate-400 hover:text-slate-600 transition-colors">
<X size={20} />
</button>
</div>
{/* Content */}
<div className="p-6 space-y-4">
<p className="text-sm text-slate-500 mb-4">
.
</p>
<div className="grid gap-4">
{/* Option 1: Full Version */}
<a
href={`${import.meta.env.BASE_URL}webftp.exe`}
download="webftp.exe"
className="flex items-start gap-4 p-4 rounded-lg border border-slate-200 hover:border-blue-400 hover:bg-blue-50 transition-all group relative"
>
<div className="p-3 bg-blue-100 text-blue-600 rounded-lg group-hover:bg-blue-200 transition-colors">
<Package size={24} />
</div>
<div className="flex-1">
<div className="flex items-center justify-between">
<h4 className="font-bold text-slate-800"> (All-in-One)</h4>
<span className="text-xs font-mono bg-slate-100 px-2 py-0.5 rounded text-slate-500">
{sizes.full > 0 ? formatBytes(sizes.full) : 'Loading...'}
</span>
</div>
<p className="text-xs text-slate-500 mt-1">
, .
<span className="block text-blue-600 mt-1 font-semibold"> .</span>
</p>
</div>
<Download size={16} className="absolute top-4 right-4 text-slate-300 group-hover:text-blue-500" />
</a>
{/* Option 2: Backend Only */}
<a
href={`${import.meta.env.BASE_URL}webftp-backend.exe`}
download="webftp-backend.exe"
className="flex items-start gap-4 p-4 rounded-lg border border-slate-200 hover:border-emerald-400 hover:bg-emerald-50 transition-all group relative"
>
<div className="p-3 bg-emerald-100 text-emerald-600 rounded-lg group-hover:bg-emerald-200 transition-colors">
<Server size={24} />
</div>
<div className="flex-1">
<div className="flex items-center justify-between">
<h4 className="font-bold text-slate-800"> (Backend Only)</h4>
<span className="text-xs font-mono bg-slate-100 px-2 py-0.5 rounded text-slate-500">
{sizes.backend > 0 ? formatBytes(sizes.backend) : 'Loading...'}
</span>
</div>
<p className="text-xs text-slate-500 mt-1">
, .
( )
</p>
</div>
<Download size={16} className="absolute top-4 right-4 text-slate-300 group-hover:text-emerald-500" />
</a>
</div>
</div>
{/* Footer */}
<div className="px-4 py-3 bg-slate-50 border-t border-slate-100 text-right">
<button
onClick={onClose}
className="px-4 py-2 bg-white border border-slate-300 text-slate-700 rounded hover:bg-slate-50 text-sm font-medium shadow-sm"
>
</button>
</div>
</div>
</div>
);
};
export default DownloadModal;