diff --git a/public/index.html b/public/index.html
index 8a6369e..f47ca3f 100644
--- a/public/index.html
+++ b/public/index.html
@@ -509,6 +509,29 @@
class="w-full px-4 py-2 border border-gray-600 bg-gray-700 text-gray-100 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent">
+
+
+
+
+
+ Datenbank Verwaltung
+
+
+
+
+
+
+
+
+ Export erstellt eine JSON-Datei mit allen Einträgen und Einstellungen. Import überschreibt alle vorhandenen Daten.
+
+
diff --git a/public/js/main.js b/public/js/main.js
index 5915f55..503c892 100644
--- a/public/js/main.js
+++ b/public/js/main.js
@@ -3215,6 +3215,115 @@ async function handleExportPDF() {
}
}
+/**
+ * Export entire database
+ */
+async function exportDatabase() {
+ try {
+ // Fetch all data
+ const entries = await fetchEntries();
+ const settings = {
+ employeeName: await getSetting('employeeName') || '',
+ employeeId: await getSetting('employeeId') || '',
+ bundesland: await getSetting('bundesland') || 'NW',
+ vacationDaysPerYear: await getSetting('vacationDaysPerYear') || 30
+ };
+
+ // Create export object
+ const exportData = {
+ version: '1.0',
+ exportDate: new Date().toISOString(),
+ entries: entries,
+ settings: settings
+ };
+
+ // Convert to JSON
+ const jsonString = JSON.stringify(exportData, null, 2);
+ const blob = new Blob([jsonString], { type: 'application/json' });
+
+ // Create download link
+ const url = URL.createObjectURL(blob);
+ const a = document.createElement('a');
+ a.href = url;
+ a.download = `zeiterfassung_backup_${new Date().toISOString().split('T')[0]}.json`;
+ document.body.appendChild(a);
+ a.click();
+ document.body.removeChild(a);
+ URL.revokeObjectURL(url);
+
+ showNotification(`Datenbank exportiert: ${entries.length} Einträge`, 'success');
+ } catch (error) {
+ console.error('Error exporting database:', error);
+ showNotification('Fehler beim Exportieren der Datenbank', 'error');
+ }
+}
+
+/**
+ * Import entire database
+ */
+async function importDatabase(file) {
+ try {
+ const text = await file.text();
+ const importData = JSON.parse(text);
+
+ // Validate data structure
+ if (!importData.entries || !Array.isArray(importData.entries)) {
+ throw new Error('Ungültiges Datenbankformat');
+ }
+
+ // Confirm before overwriting
+ const confirmed = confirm(
+ `Möchten Sie die Datenbank wirklich importieren?\n\n` +
+ `Dies wird alle ${importData.entries.length} Einträge importieren und vorhandene Daten überschreiben.\n\n` +
+ `Export-Datum: ${new Date(importData.exportDate).toLocaleString('de-DE')}`
+ );
+
+ if (!confirmed) {
+ return;
+ }
+
+ // Delete all existing entries
+ const existingEntries = await fetchEntries();
+ for (const entry of existingEntries) {
+ await fetch(`/api/entries/${entry.id}`, { method: 'DELETE' });
+ }
+
+ // Import entries
+ let imported = 0;
+ for (const entry of importData.entries) {
+ try {
+ // Remove ID to create new entries
+ const { id, ...entryData } = entry;
+ await fetch('/api/entries', {
+ method: 'POST',
+ headers: { 'Content-Type': 'application/json' },
+ body: JSON.stringify(entryData)
+ });
+ imported++;
+ } catch (err) {
+ console.error('Error importing entry:', err);
+ }
+ }
+
+ // Import settings
+ if (importData.settings) {
+ await setSetting('employeeName', importData.settings.employeeName || '');
+ await setSetting('employeeId', importData.settings.employeeId || '');
+ await setSetting('bundesland', importData.settings.bundesland || 'NW');
+ await setSetting('vacationDaysPerYear', importData.settings.vacationDaysPerYear || 30);
+ await loadSettings(); // Reload settings to UI
+ }
+
+ // Reload view
+ await reloadView();
+
+ showNotification(`Datenbank importiert: ${imported} Einträge`, 'success');
+ } catch (error) {
+ console.error('Error importing database:', error);
+ showNotification('Fehler beim Importieren der Datenbank: ' + error.message, 'error');
+ }
+}
+
/**
* Show a temporary notification
*/
@@ -3535,6 +3644,19 @@ function initializeEventListeners() {
showNotification('Personalnummer gespeichert', 'success');
});
+ // Database export/import
+ document.getElementById('btnExportDB').addEventListener('click', exportDatabase);
+ document.getElementById('btnImportDB').addEventListener('click', () => {
+ document.getElementById('importDBFile').click();
+ });
+ document.getElementById('importDBFile').addEventListener('change', (e) => {
+ const file = e.target.files[0];
+ if (file) {
+ importDatabase(file);
+ e.target.value = ''; // Reset file input
+ }
+ });
+
// Close modal when clicking outside
document.getElementById('entryModal').addEventListener('click', (e) => {
if (e.target.id === 'entryModal') {