245 lines
5.9 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>Contacts Import / Export</title>
<script src="/backend/xlsx/xlsx.full.min.js"></script>
<script src="/backend/handsontable/handsontable/dist/handsontable.full.min.js"></script>
<link rel="stylesheet" href="/backend/handsontable/handsontable/dist/handsontable.full.min.css">
<style>
/* ===== BASE THEME (Workbench / HMI) ===== */
:root{
--bg:#0b1020;
--card:rgba(255,255,255,0.08);
--border:rgba(255,255,255,0.14);
--text:rgba(255,255,255,0.92);
--muted:rgba(255,255,255,0.6);
--accent:#4f7cff;
--shadow:0 16px 60px rgba(0,0,0,.4);
--radius:20px;
}
*{box-sizing:border-box}
html,body{height:100%}
body{
margin:0;
padding:16px;
font-family:-apple-system,system-ui,Segoe UI,Roboto;
background:
radial-gradient(900px 600px at 20% 10%, rgba(79,124,255,.35), transparent 60%),
var(--bg);
color:var(--text);
}
/* ===== LAYOUT ===== */
.app{
max-width:1400px;
margin:0 auto;
height:100%;
display:grid;
grid-template-rows:auto 1fr;
gap:16px;
}
.panel{
background:linear-gradient(180deg,var(--card),rgba(255,255,255,.04));
border:1px solid var(--border);
border-radius:var(--radius);
box-shadow:var(--shadow);
overflow:hidden;
}
.header{
padding:14px 18px;
display:flex;
align-items:center;
justify-content:space-between;
border-bottom:1px solid var(--border);
}
.header h1{
margin:0;
font-size:18px;
}
/* ===== CONTENT ===== */
.content{
padding:16px;
display:flex;
flex-direction:column;
gap:14px;
height:100%;
}
/* ===== ACTION BAR ===== */
.actions{
display:flex;
gap:12px;
align-items:center;
}
input[type="file"]{
color:var(--muted);
}
/* ===== BUTTONS ===== */
button{
padding:10px 18px;
border-radius:14px;
border:0;
background:var(--accent);
color:#fff;
font-size:14px;
cursor:pointer;
}
button.secondary{
background:rgba(255,255,255,.12);
}
button:hover{
filter:brightness(1.1);
}
/* ===== HANDSONTABLE ===== */
#import-table{
flex:1;
overflow:hidden;
border-radius:14px;
border:1px solid var(--border);
}
.handsontable{
background:transparent;
}
.ht_master .wtHolder{
background:transparent;
}
</style>
</head>
<body>
<main class="app">
<!-- HEADER -->
<section class="panel">
<div class="header">
<h1>Contacts Excel Import / Export</h1>
<div class="actions">
<button id="export-button" class="secondary">Excel Export</button>
<button id="send-button">Daten senden</button>
</div>
</div>
</section>
<!-- CONTENT -->
<section class="panel content">
<div class="actions">
<input type="file" id="file-input" accept=".xlsx">
</div>
<div id="import-table"></div>
</section>
</main>
<script>
document.addEventListener("DOMContentLoaded", function () {
let importedData = [];
let hot;
const url = sessionStorage.getItem("url");
const stationNumber = sessionStorage.getItem("stationNumber");
function exportExcel() {
fetch(url + '/backend/api/getContact', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ station: stationNumber })
})
.then(response => response.json())
.then(data => {
if (!data || data.length === 0) {
alert("Keine Daten zum Exportieren.");
return;
}
const headers = Object.keys(data[0]);
const rows = data.map(obj => headers.map(h => obj[h]));
const worksheet = XLSX.utils.aoa_to_sheet([headers, ...rows]);
const workbook = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(workbook, worksheet, "Contacts");
XLSX.writeFile(workbook, "ContactsExport.xlsx");
})
.catch(err => alert("Fehler beim Exportieren: " + err.message));
}
function importExcelData() {
const fileInput = document.getElementById("file-input");
if (!fileInput.files.length) return;
const reader = new FileReader();
reader.onload = function (event) {
const workbook = XLSX.read(event.target.result, { type: "binary" });
const sheet = workbook.Sheets[workbook.SheetNames[0]];
const jsonData = XLSX.utils.sheet_to_json(sheet, { header: 1 });
if (jsonData.length < 2) return;
const headers = jsonData[0];
importedData = jsonData.slice(1)
.filter(row =>
Array.isArray(row) &&
row.some(cell => cell !== null && cell !== undefined && String(cell).trim() !== "")
);
if (hot) {
hot.loadData(importedData);
hot.updateSettings({ colHeaders: headers });
} else {
hot = new Handsontable(document.getElementById("import-table"), {
data: importedData,
colHeaders: headers,
rowHeaders: true,
width: '100%',
height: '100%',
licenseKey: 'non-commercial-and-evaluation'
});
}
};
reader.readAsBinaryString(fileInput.files[0]);
}
function sendExcelData() {
const jsonData = importedData.map(row => {
const obj = {};
hot.getColHeader().forEach((h, i) => obj[h] = row[i] || "");
return obj;
});
fetch(url + '/backend/api/updateContacts', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ station: stationNumber, data: jsonData })
})
.then(r => {
if (!r.ok) throw new Error(r.status);
return r.json();
})
.then(() => alert("Daten erfolgreich gesendet!"))
.catch(err => alert("Fehler beim Senden: " + err.message));
}
document.getElementById("export-button").addEventListener("click", exportExcel);
document.getElementById("file-input").addEventListener("change", importExcelData);
document.getElementById("send-button").addEventListener("click", sendExcelData);
});
</script>
</body>
</html>