194 lines
5.3 KiB
JavaScript
194 lines
5.3 KiB
JavaScript
/**
|
|
* 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>} - 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<Object|null>} - 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<Object|null>} - 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<boolean>} - 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');
|
|
}
|
|
}
|