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:
@@ -14,7 +14,8 @@ import Badge from '../../components/ui/Badge';
|
||||
import Input from '../../components/ui/Input';
|
||||
import Modal from '../../components/ui/Modal';
|
||||
import FileUpload from '../../components/ui/FileUpload';
|
||||
import { Edit, Trash2, Copy, Eye, EyeOff, ArrowLeft, ArrowRight, Download, ExternalLink, Plus, ChevronDown, ChevronUp, Gauge, CheckCircle, Circle, ClipboardList, MessageSquare, Calculator, Info, X, BellOff, Lock, Shield, FileText } from 'lucide-react';
|
||||
import { Edit, Trash2, Copy, Eye, EyeOff, ArrowLeft, ArrowRight, Download, ExternalLink, Plus, ChevronDown, ChevronUp, Gauge, CheckCircle, Circle, ClipboardList, MessageSquare, Calculator, Info, X, BellOff, Lock, Shield, FileText, Images } from 'lucide-react';
|
||||
import JpgToPdfModal from '../../components/ui/JpgToPdfModal';
|
||||
import { calculateConsumption, calculateCosts, calculateMultiMeterConsumption } from '../../utils/energyCalculations';
|
||||
import CopyButton, { CopyableBlock } from '../../components/ui/CopyButton';
|
||||
import { formatDate } from '../../utils/dateFormat';
|
||||
@@ -3484,6 +3485,7 @@ function ContractDocumentsSection({
|
||||
const [uploadDeliveryDate, setUploadDeliveryDate] = useState<string>(
|
||||
() => new Date().toISOString().split('T')[0],
|
||||
);
|
||||
const [isJpgModalOpen, setIsJpgModalOpen] = useState(false);
|
||||
|
||||
const { data: docsData } = useQuery({
|
||||
queryKey: ['contract-documents', contractId],
|
||||
@@ -3581,15 +3583,31 @@ function ContractDocumentsSection({
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="flex items-center gap-3 flex-wrap">
|
||||
<label className="inline-flex items-center gap-2 px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 cursor-pointer text-sm">
|
||||
<Plus className="w-4 h-4" />
|
||||
Datei wählen (PDF, JPG, PNG)
|
||||
<input type="file" accept=".pdf,.jpg,.jpeg,.png" className="hidden" onChange={handleFileSelect} />
|
||||
</label>
|
||||
<Button variant="ghost" size="sm" onClick={() => setIsJpgModalOpen(true)} title="Mehrere JPGs zu einer PDF kombinieren">
|
||||
<Images className="w-4 h-4 mr-1" /> JPGs → PDF
|
||||
</Button>
|
||||
<Button variant="secondary" size="sm" onClick={() => setShowUpload(false)}>Abbrechen</Button>
|
||||
{uploadMutation.isPending && <span className="text-sm text-gray-500">Hochladen...</span>}
|
||||
</div>
|
||||
<JpgToPdfModal
|
||||
isOpen={isJpgModalOpen}
|
||||
onClose={() => setIsJpgModalOpen(false)}
|
||||
onComplete={(file) => {
|
||||
uploadMutation.mutate({
|
||||
file,
|
||||
documentType: uploadType,
|
||||
notes: uploadNotes || undefined,
|
||||
deliveryDate: isDelivery ? uploadDeliveryDate : undefined,
|
||||
});
|
||||
}}
|
||||
fileNameHint={uploadType}
|
||||
/>
|
||||
{uploadMutation.isError && (
|
||||
<p className="text-xs text-red-600 mt-2">Fehler beim Hochladen</p>
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user