JPGs → PDF: neuer Button überall bei PDF-Upload
- Neue Komponente JpgToPdfModal (jsPDF clientseitig, kein Backend-Roundtrip). - Bilder hinzufügen per Klick, Drag&Drop oder Strg+V (Clipboard). - Reihenfolge per Drag&Drop sortierbar; pro Bild 90°/180°-Drehung + horizontal/vertikal-Spiegelung. - Jedes Bild = eine A4-Seite, Orientation automatisch nach Bild, JPEG-Qualität 100%. - FileUpload-Komponente zeigt den Sekundär-Button automatisch, sobald accept PDF einschließt (Datenschutz, Vollmacht, Bankkarten, Ausweise, Gewerbeanmeldung, Handelsregister, Kündigungsschreiben/-bestätigung + jeweilige Optionen). - Direktinputs ebenfalls erweitert: Vertragsdokumente (ContractDetail), Vollmacht-Tab (CustomerDetail), Rechnungen (InvoicesSection). - PdfTemplates bewusst ausgenommen – braucht AcroForm-Felder.
This commit is contained in:
@@ -1,7 +1,8 @@
|
||||
import { useState, useRef } from 'react';
|
||||
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
||||
import { formatDate } from '../../utils/dateFormat';
|
||||
import { Plus, Edit, Trash2, ChevronDown, ChevronUp, FileText, Download, AlertTriangle, Check, Eye } from 'lucide-react';
|
||||
import { Plus, Edit, Trash2, ChevronDown, ChevronUp, FileText, Download, AlertTriangle, Check, Eye, Images } from 'lucide-react';
|
||||
import JpgToPdfModal from '../ui/JpgToPdfModal';
|
||||
import Modal from '../ui/Modal';
|
||||
import Button from '../ui/Button';
|
||||
import Input from '../ui/Input';
|
||||
@@ -218,6 +219,7 @@ function InvoiceModal({
|
||||
});
|
||||
const [selectedFile, setSelectedFile] = useState<File | null>(null);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
const [isJpgModalOpen, setIsJpgModalOpen] = useState(false);
|
||||
|
||||
const addInvoiceFn = async (data: { invoiceDate: string; invoiceType: string; notes?: string }) => {
|
||||
if (ecdId) {
|
||||
@@ -386,15 +388,31 @@ function InvoiceModal({
|
||||
onChange={handleFileSelect}
|
||||
className="hidden"
|
||||
/>
|
||||
<Button
|
||||
type="button"
|
||||
variant="secondary"
|
||||
onClick={() => fileInputRef.current?.click()}
|
||||
>
|
||||
{invoice?.documentPath || selectedFile ? 'Ersetzen' : 'PDF hochladen'}
|
||||
</Button>
|
||||
<div className="flex gap-2 flex-wrap">
|
||||
<Button
|
||||
type="button"
|
||||
variant="secondary"
|
||||
onClick={() => fileInputRef.current?.click()}
|
||||
>
|
||||
{invoice?.documentPath || selectedFile ? 'Ersetzen' : 'PDF hochladen'}
|
||||
</Button>
|
||||
<Button
|
||||
type="button"
|
||||
variant="ghost"
|
||||
onClick={() => setIsJpgModalOpen(true)}
|
||||
title="Mehrere JPGs zu einer PDF kombinieren"
|
||||
>
|
||||
<Images className="w-4 h-4 mr-1" /> JPGs → PDF
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<JpgToPdfModal
|
||||
isOpen={isJpgModalOpen}
|
||||
onClose={() => setIsJpgModalOpen(false)}
|
||||
onComplete={(file) => setSelectedFile(file)}
|
||||
fileNameHint="rechnung"
|
||||
/>
|
||||
|
||||
{formData.invoiceType === 'NOT_AVAILABLE' && (
|
||||
<div className="p-3 bg-yellow-50 border border-yellow-200 rounded-lg text-yellow-800 text-sm">
|
||||
|
||||
Reference in New Issue
Block a user