import { useState } from 'react'; import { useTranslation } from 'react-i18next'; import { Helmet } from 'react-helmet-async'; import { Layers } from 'lucide-react'; import FileUploader from '@/components/shared/FileUploader'; import ProgressBar from '@/components/shared/ProgressBar'; import DownloadButton from '@/components/shared/DownloadButton'; import AdSlot from '@/components/layout/AdSlot'; import { useTaskPolling } from '@/hooks/useTaskPolling'; import { uploadFile, type TaskResponse } from '@/services/api'; import { generateToolSchema } from '@/utils/seo'; export default function MergePdf() { const { t } = useTranslation(); const [phase, setPhase] = useState<'upload' | 'processing' | 'done'>('upload'); const [files, setFiles] = useState([]); const [uploadProgress, setUploadProgress] = useState(0); const [isUploading, setIsUploading] = useState(false); const [taskId, setTaskId] = useState(null); const [error, setError] = useState(null); const { status, result, error: taskError } = useTaskPolling({ taskId, onComplete: () => setPhase('done'), onError: () => setPhase('done'), }); const handleFilesSelect = (newFiles: FileList | File[]) => { const fileArray = Array.from(newFiles).filter( (f) => f.type === 'application/pdf' ); if (fileArray.length === 0) { setError(t('tools.mergePdf.invalidFiles')); return; } setFiles((prev) => [...prev, ...fileArray]); setError(null); }; const removeFile = (index: number) => { setFiles((prev) => prev.filter((_, i) => i !== index)); }; const handleUpload = async () => { if (files.length < 2) { setError(t('tools.mergePdf.minFiles')); return; } setIsUploading(true); setError(null); try { const formData = new FormData(); files.forEach((f) => formData.append('files', f)); const response = await fetch('/api/pdf-tools/merge', { method: 'POST', body: formData, }); const data = await response.json(); if (!response.ok) { throw new Error(data.error || 'Upload failed.'); } setTaskId(data.task_id); setPhase('processing'); } catch (err) { setError(err instanceof Error ? err.message : 'Upload failed.'); } finally { setIsUploading(false); } }; const handleReset = () => { setFiles([]); setPhase('upload'); setTaskId(null); setError(null); setUploadProgress(0); }; const schema = generateToolSchema({ name: t('tools.mergePdf.title'), description: t('tools.mergePdf.description'), url: `${window.location.origin}/tools/merge-pdf`, }); return ( <> {t('tools.mergePdf.title')} — {t('common.appName')}

{t('tools.mergePdf.title')}

{t('tools.mergePdf.description')}

{phase === 'upload' && (
{/* Drop zone for adding files */}
document.getElementById('merge-file-input')?.click()} onDragOver={(e) => e.preventDefault()} onDrop={(e) => { e.preventDefault(); if (e.dataTransfer.files) handleFilesSelect(e.dataTransfer.files); }} > { if (e.target.files) handleFilesSelect(e.target.files); e.target.value = ''; }} />

{t('common.dragDrop')}

PDF (.pdf)

{t('common.maxSize', { size: 20 })}

{/* File list */} {files.length > 0 && (
{files.map((f, idx) => (
{idx + 1}. {f.name}
))}

{files.length} {t('tools.mergePdf.filesSelected')}

)} {error && (

{error}

)} {files.length >= 2 && ( )}
)} {phase === 'processing' && !result && ( )} {phase === 'done' && result && result.status === 'completed' && ( )} {phase === 'done' && taskError && (

{taskError}

)}
); }