/** * API Client for backend communication */ import { formatDateISO } from '../utils/dateUtils.js'; import { showNotification } from '../ui/notifications.js'; /** * Fetch entries from the backend * @param {string|null} fromDate - Start date (YYYY-MM-DD) * @param {string|null} toDate - End date (YYYY-MM-DD) * @returns {Promise} - Array of entries */ export async function fetchEntries(fromDate = null, toDate = null) { try { let url = '/api/entries'; const params = new URLSearchParams(); if (fromDate) params.append('from', fromDate); if (toDate) params.append('to', toDate); if (params.toString()) { url += '?' + params.toString(); } const response = await fetch(url); if (!response.ok) { throw new Error('Failed to fetch entries'); } const entries = await response.json(); return entries; } catch (error) { console.error('Error fetching entries:', error); showNotification('Fehler beim Laden der Einträge', 'error'); return []; } } /** * Create a new entry * @param {string} date - Date in DD.MM.YYYY format * @param {string} startTime - Start time HH:MM * @param {string} endTime - End time HH:MM * @param {number|null} pauseMinutes - Pause in minutes * @param {string} location - Location (office/home) * @returns {Promise} - Created entry or null */ export async function createEntry(date, startTime, endTime, pauseMinutes, location) { try { const body = { date: formatDateISO(date), startTime, endTime, location: location || 'office' }; // Only include pauseMinutes if explicitly provided (not empty) if (pauseMinutes !== null && pauseMinutes !== undefined && pauseMinutes !== '') { body.pauseMinutes = parseInt(pauseMinutes); } const response = await fetch('/api/entries', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body) }); if (!response.ok) { const error = await response.json(); throw new Error(error.error || 'Failed to create entry'); } const entry = await response.json(); return entry; } catch (error) { console.error('Error creating entry:', error); showNotification(error.message || 'Fehler beim Erstellen des Eintrags', 'error'); return null; } } /** * Update an existing entry * @param {number} id - Entry ID * @param {string} date - Date in DD.MM.YYYY format * @param {string} startTime - Start time HH:MM * @param {string} endTime - End time HH:MM * @param {number|null} pauseMinutes - Pause in minutes * @param {string} location - Location (office/home) * @returns {Promise} - Updated entry or null */ export async function updateEntry(id, date, startTime, endTime, pauseMinutes, location) { try { const body = { date: formatDateISO(date), startTime, endTime, location: location || 'office' }; // Only include pauseMinutes if explicitly provided (not empty) if (pauseMinutes !== null && pauseMinutes !== undefined && pauseMinutes !== '') { body.pauseMinutes = parseInt(pauseMinutes); } const response = await fetch(`/api/entries/${id}`, { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body) }); if (!response.ok) { const error = await response.json(); throw new Error(error.error || 'Failed to update entry'); } const entry = await response.json(); return entry; } catch (error) { console.error('Error updating entry:', error); showNotification(error.message || 'Fehler beim Aktualisieren des Eintrags', 'error'); return null; } } /** * Delete an entry * @param {number} id - Entry ID * @returns {Promise} - True if successful */ export async function deleteEntry(id) { try { const response = await fetch(`/api/entries/${id}`, { method: 'DELETE' }); if (!response.ok) { throw new Error('Failed to delete entry'); } return true; } catch (error) { console.error('Error deleting entry:', error); showNotification('Fehler beim Löschen des Eintrags', 'error'); return false; } } /** * Export entries as CSV * @param {string|null} fromDate - Start date (YYYY-MM-DD) * @param {string|null} toDate - End date (YYYY-MM-DD) */ export async function exportEntries(fromDate = null, toDate = null) { try { let url = '/api/export'; const params = new URLSearchParams(); if (fromDate) params.append('from', fromDate); if (toDate) params.append('to', toDate); if (params.toString()) { url += '?' + params.toString(); } const response = await fetch(url); if (!response.ok) { throw new Error('Failed to export entries'); } const blob = await response.blob(); const downloadUrl = window.URL.createObjectURL(blob); const a = document.createElement('a'); a.href = downloadUrl; a.download = 'zeiterfassung.csv'; document.body.appendChild(a); a.click(); document.body.removeChild(a); window.URL.revokeObjectURL(downloadUrl); showNotification('Export erfolgreich', 'success'); } catch (error) { console.error('Error exporting entries:', error); showNotification('Fehler beim Exportieren', 'error'); } }