Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,9 @@ public String saveReport(
newReport.name(),
newReport.event(),
f,
currentUser.getUsername()
currentUser.getUsername(),
newReport.witness(),
newReport.victim()
);
}
}
Expand All @@ -106,7 +108,9 @@ public String saveReport(
newReport.name(),
newReport.event(),
img,
currentUser.getUsername()
currentUser.getUsername(),
newReport.witness(),
newReport.victim()
);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,24 @@ public EvidenceFileService(EvidenceFileRepository evidenceFileRepository,

public void upload(String caseNumber, String reportName, String reportEvent,
MultipartFile file, String uploadedBy) throws IOException {
upload(caseNumber, reportName, reportEvent, file, uploadedBy, null);
upload(caseNumber, reportName, reportEvent, file, uploadedBy, null, "", "");
}

public void upload(String caseNumber, String reportName, String reportEvent,
MultipartFile file, String uploadedBy,
String witness, String victim) throws IOException {
upload(caseNumber, reportName, reportEvent, file, uploadedBy, null, witness, victim);
}

@Transactional
public void upload(String caseNumber, String reportName, String reportEvent,
MultipartFile file, String uploadedBy, UUID groupId) throws IOException {
upload(caseNumber, reportName, reportEvent, file, uploadedBy, groupId, "", "");
}

@Transactional
public void upload(String caseNumber, String reportName, String reportEvent,
MultipartFile file, String uploadedBy, UUID groupId,
String witness, String victim) throws IOException {
String s3KeyPdf = null;
String s3KeyFile = null;

Expand All @@ -85,7 +97,7 @@ public void upload(String caseNumber, String reportName, String reportEvent,
resolvedGroupId = UUID.randomUUID();
}

byte[] pdfBytes = generatePdf(reportName, reportEvent, file);
byte[] pdfBytes = generatePdf(caseNumber, reportName, reportEvent, witness, victim, file);
s3KeyPdf = "cases/" + caseNumber + "/pdf/" + UUID.randomUUID() + ".pdf";

s3Client.putObject(
Expand Down Expand Up @@ -198,15 +210,19 @@ private void requireCaseAccess(String caseNumber, Account currentUser) {
}
}

private byte[] generatePdf(String reportName, String reportEvent, MultipartFile file) throws Exception {
private byte[] generatePdf(String caseNumber, String reportName, String reportEvent,
String witness, String victim, MultipartFile file) throws Exception {
ByteArrayOutputStream pdfStream = new ByteArrayOutputStream();
Document document = new Document();
PdfWriter.getInstance(document, pdfStream);
document.open();

document.add(new Paragraph("Brottsanmälan"));
document.add(new Paragraph("Namn: " + reportName));
document.add(new Paragraph("Brottstyp: " + reportEvent));
document.add(new Paragraph("K-nummer: " + caseNumber));
document.add(new Paragraph("Ansvarig polis: " + reportName));
document.add(new Paragraph("Brottsplats: " + reportEvent));
document.add(new Paragraph("Vittne: " + (witness != null && !witness.isBlank() ? witness : "-")));
document.add(new Paragraph("Offer: " + (victim != null && !victim.isBlank() ? victim : "-")));
document.add(new Paragraph("Datum: " + LocalDateTime.now()));

if (file != null && !file.isEmpty()) {
Expand Down
84 changes: 62 additions & 22 deletions src/main/resources/templates/registerreport.html
Original file line number Diff line number Diff line change
Expand Up @@ -75,38 +75,78 @@ <h2>Bifoga bevis</h2>
</main>
</div>
<script>
var pendingList = [];

function syncInputs() {
var filesInput = document.getElementById('evidenceFiles');
var imagesInput = document.getElementById('evidenceImages');
var dt;

dt = new DataTransfer();
pendingList.filter(p => p.kind === 'Fil').forEach(p => dt.items.add(p.file));
filesInput.files = dt.files;

dt = new DataTransfer();
pendingList.filter(p => p.kind === 'Bild').forEach(p => dt.items.add(p.file));
imagesInput.files = dt.files;
}

function renderPending() {
var pending = document.getElementById('pendingFiles');
pending.innerHTML = '';
[
{ input: document.getElementById('evidenceFiles'), label: 'Fil' },
{ input: document.getElementById('evidenceImages'), label: 'Bild' }
].forEach(function(entry) {
Array.from(entry.input.files).forEach(function(f) {
var row = document.createElement('div');
row.className = 'evidence-row';
var meta = document.createElement('div');
meta.className = 'file-meta';
var name = document.createElement('span');
name.className = 'file-name';
name.textContent = f.name;
var type = document.createElement('span');
type.className = 'file-type';
type.textContent = entry.label + ' · ' + (f.size / 1024).toFixed(1) + ' KB';
meta.appendChild(name);
meta.appendChild(type);
row.appendChild(meta);
pending.appendChild(row);
pendingList.forEach(function(entry, idx) {
var row = document.createElement('div');
row.className = 'evidence-row';

var meta = document.createElement('div');
meta.className = 'file-meta';
var name = document.createElement('span');
name.className = 'file-name';
name.textContent = entry.file.name;
var type = document.createElement('span');
type.className = 'file-type';
type.textContent = entry.kind + ' · ' + (entry.file.size / 1024).toFixed(1) + ' KB';
meta.appendChild(name);
meta.appendChild(type);

var actions = document.createElement('div');
actions.style.cssText = 'display:flex;gap:6px;align-items:center';
var del = document.createElement('button');
del.type = 'button';
del.className = 'btn btn-danger btn-sm';
del.textContent = 'Ta bort';
del.addEventListener('click', function() {
pendingList.splice(idx, 1);
syncInputs();
renderPending();
});
actions.appendChild(del);

row.appendChild(meta);
row.appendChild(actions);
pending.appendChild(row);
});
}

function addFiles(kind, files) {
Array.from(files).forEach(function(f) {
pendingList.push({ kind: kind, file: f });
});
renderPending();
}

function clearPending() {
document.getElementById('pendingFiles').innerHTML = '';
pendingList = [];
syncInputs();
renderPending();
}

document.getElementById('evidenceFiles').addEventListener('change', renderPending);
document.getElementById('evidenceImages').addEventListener('change', renderPending);
document.getElementById('evidenceFiles').addEventListener('change', function() {
addFiles('Fil', this.files);
});
document.getElementById('evidenceImages').addEventListener('change', function() {
addFiles('Bild', this.files);
});
</script>
</body>
</html>
92 changes: 43 additions & 49 deletions src/main/resources/templates/reports.html
Original file line number Diff line number Diff line change
Expand Up @@ -245,58 +245,52 @@ <h2>Brottsplats</h2>
return list.some(f => f.name === file.name && f.size === file.size);
}

function renderList(label, filesArray, type) {
const section = document.createElement("div");
section.classList.add("evidence-section");

const title = document.createElement("strong");
title.textContent = label;
section.appendChild(title);

const list = document.createElement("ul");

filesArray.forEach((file, index) => {
const li = document.createElement("li");

const text = document.createElement("span");
text.textContent = file.name;

const removeBtn = document.createElement("button");
removeBtn.textContent = "❌";
removeBtn.style.marginLeft = "10px";
removeBtn.type = "button";
removeBtn.setAttribute("aria-label", `Ta bort ${file.name}`);

removeBtn.onclick = () => {
if (type === "file") {
selectedFiles.splice(index, 1);
updateInput(fileInput, selectedFiles);
} else {
selectedImages.splice(index, 1);
updateInput(imageInput, selectedImages);
}
renderAll();
};

li.appendChild(text);
li.appendChild(removeBtn);
list.appendChild(li);
});

section.appendChild(list);
return section;
}

function renderAll() {
evidenceList.innerHTML = "";

if (selectedFiles.length > 0) {
evidenceList.appendChild(renderList("Filer:", selectedFiles, "file"));
}

if (selectedImages.length > 0) {
evidenceList.appendChild(renderList("Bilder:", selectedImages, "image"));
}
[
{ filesArray: selectedFiles, label: "Fil", type: "file" },
{ filesArray: selectedImages, label: "Bild", type: "image" }
].forEach(({ filesArray, label, type }) => {
filesArray.forEach((file, index) => {
const row = document.createElement("div");
row.className = "evidence-row";

const meta = document.createElement("div");
meta.className = "file-meta";

const name = document.createElement("span");
name.className = "file-name";
name.textContent = file.name;

const info = document.createElement("span");
info.className = "file-type";
info.textContent = label + " · " + (file.size / 1024).toFixed(1) + " KB";

meta.appendChild(name);
meta.appendChild(info);
row.appendChild(meta);

const removeBtn = document.createElement("button");
removeBtn.textContent = "Ta bort";
removeBtn.type = "button";
removeBtn.className = "btn btn-danger btn-sm";
removeBtn.setAttribute("aria-label", `Ta bort ${file.name}`);
removeBtn.onclick = () => {
if (type === "file") {
selectedFiles.splice(index, 1);
updateInput(fileInput, selectedFiles);
} else {
selectedImages.splice(index, 1);
updateInput(imageInput, selectedImages);
}
renderAll();
};

row.appendChild(removeBtn);
evidenceList.appendChild(row);
});
});
}

fileInput.addEventListener("change", () => {
Expand Down