Initial commit
This commit is contained in:
commit
f1548f10cc
7585 files changed
+1411120
No files matched your search
@@ -0,0 +1,256 @@
|
||||
// Event-Listener für das Laden der Seite
|
||||
window.addEventListener('DOMContentLoaded', () => {
|
||||
const savedYear = localStorage.getItem('selectedYear');
|
||||
const savedMonth = localStorage.getItem('selectedMonth');
|
||||
|
||||
document.getElementById('jahr').value = savedYear || new Date().getFullYear();
|
||||
document.getElementById('monat').value = savedMonth || String(new Date().getMonth() + 1).padStart(2, '0');
|
||||
|
||||
loadData();
|
||||
});
|
||||
|
||||
document.getElementById('jahr').addEventListener('change', loadData);
|
||||
document.getElementById('monat').addEventListener('change', loadData);
|
||||
document.getElementById('eintrag').addEventListener('click', addNewEntry);
|
||||
document.getElementById('export').addEventListener('click', async () => {
|
||||
try {
|
||||
const res = await fetch('/api/ordner-oeffnen');
|
||||
const data = await res.json();
|
||||
console.log(data.message);
|
||||
} catch (err) {
|
||||
console.error('Fehler beim Öffnen des Ordners:', err);
|
||||
alert('Ordner konnte nicht geöffnet werden');
|
||||
}
|
||||
});
|
||||
document.getElementById('path').addEventListener('click', async () => {
|
||||
try {
|
||||
const res = await fetch('/api/pfad-aendern', { method: 'POST' });
|
||||
const data = await res.json();
|
||||
alert(`Pfad geändert: ${data.path || 'Abgebrochen'}`);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
alert('Fehler beim Ändern des Pfades');
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
function zeigeNachricht(text, typ = 'erfolg') {
|
||||
const nachrichtContainer = document.getElementById('nachricht-container');
|
||||
nachrichtContainer.textContent = text;
|
||||
nachrichtContainer.className = `nachricht ${typ}`;
|
||||
nachrichtContainer.style.display = 'block';
|
||||
setTimeout(() => nachrichtContainer.style.display = 'none', 3000);
|
||||
}
|
||||
|
||||
function getMonthName(monthNumber) {
|
||||
const months = ['Januar','Februar','März','April','Mai','Juni','Juli','August','September','Oktober','November','Dezember'];
|
||||
return months[parseInt(monthNumber)-1];
|
||||
}
|
||||
|
||||
async function loadData() {
|
||||
const selectedYear = document.getElementById('jahr').value;
|
||||
const selectedMonth = document.getElementById('monat').value;
|
||||
|
||||
localStorage.setItem('selectedYear', selectedYear);
|
||||
localStorage.setItem('selectedMonth', selectedMonth);
|
||||
|
||||
const tableBody = document.querySelector('#buchhaltung-tabelle tbody');
|
||||
tableBody.innerHTML = '';
|
||||
|
||||
try {
|
||||
const response = await fetch(`/api/daten/${selectedYear}/${selectedMonth}`);
|
||||
let data = [];
|
||||
|
||||
if (response.ok) {
|
||||
data = await response.json();
|
||||
} else {
|
||||
console.warn('Daten nicht gefunden, erzeuge leere Tabelle');
|
||||
}
|
||||
|
||||
if (!data || data.length === 0) {
|
||||
addNewEntry(true);
|
||||
zeigeNachricht(`Für den Monat ${getMonthName(selectedMonth)} gibt es keine Daten!`, 'fehler');
|
||||
} else {
|
||||
data.forEach((row, idx) => {
|
||||
const tr = document.createElement('tr');
|
||||
tr.dataset.rowIndex = idx;
|
||||
|
||||
row.forEach(cell => {
|
||||
const td = document.createElement('td');
|
||||
td.contentEditable = true;
|
||||
td.textContent = cell || '';
|
||||
tr.appendChild(td);
|
||||
});
|
||||
|
||||
const betragZelle = tr.querySelector('td');
|
||||
betragZelle.addEventListener('blur', () => {
|
||||
betragZelle.textContent = formatAsEuro(betragZelle.textContent);
|
||||
});
|
||||
|
||||
tr.appendChild(createButtonCell(tr));
|
||||
tableBody.appendChild(tr);
|
||||
});
|
||||
}
|
||||
|
||||
updateSumme();
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
addNewEntry(true);
|
||||
updateSumme();
|
||||
zeigeNachricht('Keine Verbindung zum Server - arbeite offline.', 'fehler');
|
||||
}
|
||||
}
|
||||
|
||||
function addNewEntry(suppressMessage = false) {
|
||||
const tableBody = document.querySelector('#buchhaltung-tabelle tbody');
|
||||
const tr = document.createElement('tr');
|
||||
const rowIndex = tableBody.children.length;
|
||||
tr.dataset.rowIndex = rowIndex;
|
||||
|
||||
const today = new Date();
|
||||
const formattedDate = `${String(today.getDate()).padStart(2,'0')}.${String(today.getMonth()+1).padStart(2,'0')}.${today.getFullYear()}`;
|
||||
|
||||
const ausgabeTd = createEditableCell();
|
||||
ausgabeTd.addEventListener('blur', () => ausgabeTd.textContent = formatAsEuro(ausgabeTd.textContent));
|
||||
const kategorieTd = createEditableCell();
|
||||
const datumTd = document.createElement('td');
|
||||
datumTd.textContent = formattedDate;
|
||||
datumTd.contentEditable = false;
|
||||
|
||||
tr.appendChild(ausgabeTd);
|
||||
tr.appendChild(kategorieTd);
|
||||
tr.appendChild(datumTd);
|
||||
tr.appendChild(createButtonCell(tr));
|
||||
|
||||
tableBody.appendChild(tr);
|
||||
if (!suppressMessage) zeigeNachricht('Neue Zeile hinzugefügt!', 'erfolg');
|
||||
}
|
||||
|
||||
function createEditableCell() {
|
||||
const td = document.createElement('td');
|
||||
td.contentEditable = true;
|
||||
return td;
|
||||
}
|
||||
|
||||
function createButtonCell(tr) {
|
||||
const td = document.createElement('td');
|
||||
td.style.textAlign = 'center';
|
||||
td.innerHTML = `<button class="speichern-btn">Speichern</button><button class="loeschen-btn">Löschen</button>`;
|
||||
|
||||
td.querySelector('.speichern-btn').addEventListener('click', () => saveRowData(tr));
|
||||
td.querySelector('.loeschen-btn').addEventListener('click', () => handleDeleteButtonClick(tr));
|
||||
|
||||
return td;
|
||||
}
|
||||
|
||||
async function saveRowData(tr) {
|
||||
const rowIndex = parseInt(tr.dataset.rowIndex, 10);
|
||||
const updatedRowData = Array.from(tr.querySelectorAll('td')).slice(0, -1).map(td => td.textContent);
|
||||
|
||||
// Immer aktuelle Dropdown-Werte nehmen
|
||||
const selectedYear = document.getElementById('jahr').value;
|
||||
const selectedMonth = document.getElementById('monat').value;
|
||||
|
||||
// In LocalStorage speichern
|
||||
localStorage.setItem('selectedYear', selectedYear);
|
||||
localStorage.setItem('selectedMonth', selectedMonth);
|
||||
|
||||
try {
|
||||
const response = await fetch('/api/zeile-speichern', {
|
||||
method: 'POST',
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: JSON.stringify({
|
||||
rowIndex,
|
||||
updatedRowData,
|
||||
jahr: selectedYear,
|
||||
monat: selectedMonth
|
||||
})
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const errData = await response.json();
|
||||
throw new Error(errData.error || 'Fehler beim Speichern');
|
||||
}
|
||||
|
||||
zeigeNachricht('Daten gespeichert!', 'erfolg');
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
zeigeNachricht(`Fehler beim Speichern der Zeile: ${err.message}`, 'fehler');
|
||||
}
|
||||
updateSumme();
|
||||
}
|
||||
|
||||
|
||||
function handleDeleteButtonClick(tr) {
|
||||
const popup = document.getElementById('confirm-popup');
|
||||
const yes = document.getElementById('confirm-yes');
|
||||
const no = document.getElementById('confirm-no');
|
||||
if (!popup) return console.error('Popup nicht gefunden!');
|
||||
|
||||
popup.style.display = 'grid';
|
||||
yes.replaceWith(yes.cloneNode(true));
|
||||
no.replaceWith(no.cloneNode(true));
|
||||
|
||||
document.getElementById('confirm-yes').addEventListener('click', () => { deleteRow(tr); popup.style.display='none'; });
|
||||
document.getElementById('confirm-no').addEventListener('click', () => popup.style.display='none');
|
||||
}
|
||||
|
||||
async function deleteRow(tr) {
|
||||
const rowIndex = parseInt(tr.dataset.rowIndex, 10);
|
||||
const selectedYear = document.getElementById('jahr').value;
|
||||
const selectedMonth = document.getElementById('monat').value;
|
||||
|
||||
try {
|
||||
const response = await fetch('/api/zeile-loeschen', {
|
||||
method: 'POST',
|
||||
headers: {'Content-Type':'application/json'},
|
||||
body: JSON.stringify({
|
||||
zeileIndex: rowIndex, // korrekt benennen
|
||||
jahr: localStorage.getItem('selectedYear'),
|
||||
monat: localStorage.getItem('selectedMonth')
|
||||
})
|
||||
});
|
||||
if (!response.ok) throw new Error((await response.json()).error || 'Fehler beim Löschen');
|
||||
tr.remove();
|
||||
updateSumme();
|
||||
zeigeNachricht('Zeile erfolgreich gelöscht!', 'erfolg');
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
zeigeNachricht(`Fehler: ${err.message}`, 'fehler');
|
||||
}
|
||||
}
|
||||
|
||||
function updateSumme() {
|
||||
const rows = document.querySelectorAll('#buchhaltung-tabelle tbody tr');
|
||||
let summe = 0;
|
||||
|
||||
rows.forEach(row => {
|
||||
let val = row.querySelector('td').textContent.trim();
|
||||
|
||||
// Punkte als Tausender-Trennzeichen entfernen
|
||||
val = val.replace(/\./g, '');
|
||||
|
||||
// Komma als Dezimaltrennzeichen in Punkt konvertieren
|
||||
val = val.replace(',', '.');
|
||||
|
||||
const num = parseFloat(val);
|
||||
summe += isNaN(num) ? 0 : num;
|
||||
});
|
||||
|
||||
const summeZelle = document.getElementById('summe-zelle');
|
||||
if (summeZelle) summeZelle.textContent = `Summe: ${new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(summe)}`;
|
||||
}
|
||||
|
||||
document.getElementById('suche').addEventListener('input', function() {
|
||||
const term = this.value.toLowerCase().trim();
|
||||
document.querySelectorAll('#buchhaltung-tabelle tbody tr').forEach(row => {
|
||||
const kategorie = row.querySelectorAll('td')[1]?.textContent.toLowerCase().trim();
|
||||
row.style.display = kategorie?.includes(term) ? '' : 'none';
|
||||
});
|
||||
});
|
||||
|
||||
function formatAsEuro(value) {
|
||||
const parsed = parseFloat(value.replace(/[^\d,.-]/g,'').replace(',','.'));
|
||||
if (isNaN(parsed)) return '';
|
||||
return new Intl.NumberFormat('de-DE',{style:'currency',currency:'EUR',minimumFractionDigits:2,maximumFractionDigits:2}).format(parsed);
|
||||
}
|
||||
Reference in new issue
Block a user