- Fixed processors.py to use correct pypdf API - Fixed app.js escaping issues - PDF generation now working with real Laufzettel files 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
172 lines
7.3 KiB
JavaScript
172 lines
7.3 KiB
JavaScript
// Tab Navigation
|
|
document.querySelectorAll(".tab").forEach(tab => {
|
|
tab.addEventListener("click", () => {
|
|
document.querySelectorAll(".tab").forEach(t => t.classList.remove("active"));
|
|
document.querySelectorAll(".tab-content").forEach(c => c.classList.remove("active"));
|
|
tab.classList.add("active");
|
|
document.getElementById(tab.dataset.tab).classList.add("active");
|
|
if (tab.dataset.tab === "admin") loadTemplates();
|
|
});
|
|
});
|
|
|
|
function setupUploadZone(zoneId, inputId, infoId, btnId) {
|
|
const zone = document.getElementById(zoneId);
|
|
const input = document.getElementById(inputId);
|
|
const info = document.getElementById(infoId);
|
|
const btn = document.getElementById(btnId);
|
|
if (!zone || !input) return;
|
|
|
|
zone.addEventListener("click", () => input.click());
|
|
zone.addEventListener("dragover", (e) => { e.preventDefault(); zone.classList.add("dragover"); });
|
|
zone.addEventListener("dragleave", () => zone.classList.remove("dragover"));
|
|
zone.addEventListener("drop", (e) => {
|
|
e.preventDefault();
|
|
zone.classList.remove("dragover");
|
|
if (e.dataTransfer.files.length) {
|
|
input.files = e.dataTransfer.files;
|
|
updateFileInfo(input, info, btn);
|
|
}
|
|
});
|
|
input.addEventListener("change", () => updateFileInfo(input, info, btn));
|
|
}
|
|
|
|
function updateFileInfo(input, info, btn) {
|
|
if (input.files.length && info && btn) {
|
|
const file = input.files[0];
|
|
info.innerHTML = "<strong>OK " + file.name + "</strong> (" + (file.size/1024).toFixed(1) + " KB)";
|
|
info.classList.add("visible");
|
|
btn.disabled = false;
|
|
}
|
|
}
|
|
|
|
function showStatus(id, type, message) {
|
|
const status = document.getElementById(id);
|
|
if (status) {
|
|
status.className = "status visible " + type;
|
|
status.textContent = message;
|
|
}
|
|
}
|
|
|
|
const API_BASE = "/schadenprotokoll/api";
|
|
|
|
setupUploadZone("laufzettel-zone", "laufzettel-input", "laufzettel-info", "generate-btn");
|
|
setupUploadZone("pdf-zone", "pdf-input", "pdf-info", "analyze-btn");
|
|
setupUploadZone("vorbericht-zone", "vorbericht-input", "vorbericht-info", "vorbericht-btn");
|
|
|
|
document.getElementById("generate-btn").addEventListener("click", async () => {
|
|
showStatus("generate-status", "loading", "Verarbeite Laufzettel...");
|
|
const file = document.getElementById("laufzettel-input").files[0];
|
|
const formData = new FormData();
|
|
formData.append("file", file);
|
|
|
|
try {
|
|
const response = await fetch(API_BASE + "/generate", { method: "POST", body: formData });
|
|
if (!response.ok) throw new Error((await response.json()).error);
|
|
const blob = await response.blob();
|
|
const a = document.createElement("a");
|
|
a.href = URL.createObjectURL(blob);
|
|
a.download = "Schadenprotokoll_vorbefuellt.pdf";
|
|
document.body.appendChild(a);
|
|
a.click();
|
|
document.body.removeChild(a);
|
|
showStatus("generate-status", "success", "PDF erfolgreich generiert!");
|
|
} catch (err) {
|
|
showStatus("generate-status", "error", "Fehler: " + err.message);
|
|
}
|
|
});
|
|
|
|
document.getElementById("analyze-btn").addEventListener("click", async () => {
|
|
showStatus("analyze-status", "loading", "Analysiere PDF...");
|
|
const file = document.getElementById("pdf-input").files[0];
|
|
const formData = new FormData();
|
|
formData.append("file", file);
|
|
|
|
try {
|
|
const response = await fetch(API_BASE + "/analyze", { method: "POST", body: formData });
|
|
if (!response.ok) throw new Error((await response.json()).error);
|
|
const result = await response.json();
|
|
displayAnalysisResult(result.data);
|
|
showStatus("analyze-status", "success", "Analyse abgeschlossen");
|
|
} catch (err) {
|
|
showStatus("analyze-status", "error", "Fehler: " + err.message);
|
|
}
|
|
});
|
|
|
|
function displayAnalysisResult(data) {
|
|
const container = document.getElementById("analyze-data");
|
|
let html = "";
|
|
for (const [key, value] of Object.entries(data.textfields || {})) {
|
|
if (value) html += "<div class='dropdown-item'><strong>" + key + ":</strong> " + value + "</div>";
|
|
}
|
|
for (const [key, val] of Object.entries(data.dropdowns || {})) {
|
|
if (val.selected) html += "<div class='dropdown-item'><strong>" + key + ":</strong> " + val.selected + "</div>";
|
|
}
|
|
container.innerHTML = html || "<p>Keine Felder gefunden.</p>";
|
|
document.getElementById("analyze-result").classList.add("visible");
|
|
}
|
|
|
|
document.getElementById("vorbericht-btn").addEventListener("click", async () => {
|
|
showStatus("vorbericht-status", "loading", "Erstelle Vorbericht...");
|
|
const file = document.getElementById("vorbericht-input").files[0];
|
|
const formData = new FormData();
|
|
formData.append("file", file);
|
|
|
|
try {
|
|
const response = await fetch(API_BASE + "/vorbericht", { method: "POST", body: formData });
|
|
if (!response.ok) throw new Error((await response.json()).error);
|
|
const blob = await response.blob();
|
|
const a = document.createElement("a");
|
|
a.href = URL.createObjectURL(blob);
|
|
a.download = "Vorbericht.docx";
|
|
document.body.appendChild(a);
|
|
a.click();
|
|
document.body.removeChild(a);
|
|
showStatus("vorbericht-status", "success", "Vorbericht erstellt!");
|
|
} catch (err) {
|
|
showStatus("vorbericht-status", "error", "Fehler: " + err.message);
|
|
}
|
|
});
|
|
|
|
function setupTemplateUpload(zoneId, inputId, templateType) {
|
|
const zone = document.getElementById(zoneId);
|
|
const input = document.getElementById(inputId);
|
|
if (!zone || !input) return;
|
|
zone.addEventListener("click", () => input.click());
|
|
zone.addEventListener("dragover", (e) => { e.preventDefault(); zone.classList.add("dragover"); });
|
|
zone.addEventListener("dragleave", () => zone.classList.remove("dragover"));
|
|
zone.addEventListener("drop", (e) => {
|
|
e.preventDefault();
|
|
zone.classList.remove("dragover");
|
|
if (e.dataTransfer.files.length) uploadTemplate(e.dataTransfer.files[0], templateType);
|
|
});
|
|
input.addEventListener("change", () => { if (input.files.length) uploadTemplate(input.files[0], templateType); });
|
|
}
|
|
|
|
async function loadTemplates() {
|
|
const container = document.getElementById("templates-container");
|
|
if (!container) return;
|
|
try {
|
|
const response = await fetch(API_BASE + "/templates");
|
|
const data = await response.json();
|
|
container.innerHTML = data.templates.map(t =>
|
|
"<div class='template-item'><span>" + t.name + "</span><span>" + (t.size/1024).toFixed(0) + " KB</span></div>"
|
|
).join("");
|
|
} catch (err) { container.innerHTML = "Fehler"; }
|
|
}
|
|
|
|
async function uploadTemplate(file, type) {
|
|
showStatus("admin-status", "loading", "Lade hoch...");
|
|
const formData = new FormData();
|
|
formData.append("file", file);
|
|
formData.append("type", type);
|
|
try {
|
|
const response = await fetch(API_BASE + "/templates/upload", { method: "POST", body: formData });
|
|
if (!response.ok) throw new Error((await response.json()).error);
|
|
showStatus("admin-status", "success", "Hochgeladen!");
|
|
loadTemplates();
|
|
} catch (err) { showStatus("admin-status", "error", "Fehler: " + err.message); }
|
|
}
|
|
|
|
setupTemplateUpload("pdf-template-zone", "pdf-template-input", "pdf");
|
|
setupTemplateUpload("docx-template-zone", "docx-template-input", "docx");
|