Let uploaded documents open as a preview, download separately

Every uploaded-document link (contract PDFs, ID front/back, Schufa
report — active and archived) previously forced a download on click
via the `download` attribute, with no way to just look at the file
first. New shared buildDocumentChip() renders the filename as a
target="_blank" link (browsers preview PDFs/images natively) plus a
small ⬇ icon next to it for an explicit download, reused across all
three places these chips are rendered.
This commit is contained in:
Giuseppe Lombardo 2026-08-13 12:11:08 +00:00
parent 72008ac59b
commit 92101e3077

View File

@ -2854,6 +2854,33 @@
return `Dokument ${index + 1}.${ext}`;
}
// Klick auf den Namen öffnet eine Vorschau im neuen Tab (Browser können
// PDFs/Bilder nativ anzeigen); der Pfeil daneben lädt bei Bedarf separat
// herunter. Für alle hochgeladenen Dokumente (Verträge, Ausweis, Schufa) einheitlich.
function buildDocumentChip(label, url) {
const chip = el('span', 'invite-status-chip');
chip.style.cssText = 'background:var(--bg); color:var(--text); text-transform:none; display:inline-flex; align-items:center; gap:7px;';
const previewLink = document.createElement('a');
previewLink.href = url;
previewLink.target = '_blank';
previewLink.rel = 'noopener';
previewLink.textContent = label;
previewLink.style.color = 'var(--text)';
chip.appendChild(previewLink);
const ext = url.includes('application/pdf') ? 'pdf' : (/^data:image\/(\w+)/.exec(url)?.[1] || 'jpg');
const downloadLink = document.createElement('a');
downloadLink.href = url;
downloadLink.download = `${label.replace(/[^\w.-]+/g, '_')}.${ext}`;
downloadLink.title = 'Herunterladen';
downloadLink.textContent = '⬇';
downloadLink.style.cssText = 'color:var(--text-muted); text-decoration:none; font-size:12px;';
chip.appendChild(downloadLink);
return chip;
}
function buildProfileCompletenessBadge(user) {
const missing = [];
if (!user.phoneNumber) missing.push('Telefonnummer');
@ -2894,13 +2921,7 @@
['Schufa-Auskunft', user.schufaDocumentUrl],
].forEach(([label, url]) => {
if (!url) return;
const link = document.createElement('a');
link.href = url;
link.download = label + '.' + (url.includes('application/pdf') ? 'pdf' : 'jpg');
link.textContent = label;
link.className = 'invite-status-chip';
link.style.cssText = 'background:var(--bg); color:var(--text); text-transform:none;';
linkWrap.appendChild(link);
linkWrap.appendChild(buildDocumentChip(label, url));
});
if (linkWrap.children.length) wrap.appendChild(linkWrap);
@ -2951,14 +2972,7 @@
docWrap.appendChild(el('span', 'meta-text', 'Noch keine Dateien hochgeladen.'));
} else {
c.contractDocumentUrls.forEach((url, idx) => {
const chip = el('span', 'invite-status-chip');
chip.style.cssText = 'background:var(--bg); color:var(--text); display:inline-flex; align-items:center; gap:6px; text-transform:none;';
const link = document.createElement('a');
link.href = url;
link.download = documentFileName(url, idx);
link.textContent = documentFileName(url, idx);
link.style.color = 'var(--text)';
chip.appendChild(link);
const chip = buildDocumentChip(documentFileName(url, idx), url);
if (isLandlord) {
const removeBtn = document.createElement('button');
removeBtn.type = 'button';
@ -3068,13 +3082,7 @@
const docWrap = el('div');
docWrap.style.cssText = 'display:flex; flex-wrap:wrap; gap:6px;';
c.contractDocumentUrls.forEach((url, idx) => {
const link = document.createElement('a');
link.href = url;
link.download = documentFileName(url, idx);
link.textContent = documentFileName(url, idx);
link.className = 'invite-status-chip';
link.style.cssText = 'background:var(--bg); color:var(--text); text-transform:none;';
docWrap.appendChild(link);
docWrap.appendChild(buildDocumentChip(documentFileName(url, idx), url));
});
row.appendChild(docWrap);
}