Benutzerverwaltung mit Rollen/Rechten und Urlaubsplanung

Führt Login mit vier Rollen (Admin, Teamleiter, Mitarbeiter, Beobachter) ein,
über die Teammitglieder eigenen Urlaub inkl. Pflicht-Vertreter eintragen
können. Die Auslastungsberechnung berücksichtigt Urlaub jetzt als reduzierte
Kapazität. Neue Konten vergeben ihr Passwort selbst beim ersten Login.
Migrationsskript für bestehende Mitarbeiter aus der Vorversion inklusive.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-10 22:57:25 +02:00
parent 60a0928d2f
commit 06ea149d41
20 changed files with 1139 additions and 91 deletions
+37 -2
View File
@@ -1,18 +1,53 @@
let authToken = localStorage.getItem('authToken') || null;
export function setAuthToken(token) {
authToken = token;
if (token) localStorage.setItem('authToken', token);
else localStorage.removeItem('authToken');
}
async function request(method, url, body) {
const headers = {};
if (body) headers['Content-Type'] = 'application/json';
if (authToken) headers['Authorization'] = `Bearer ${authToken}`;
const res = await fetch(url, {
method,
headers: body ? { 'Content-Type': 'application/json' } : undefined,
headers,
body: body ? JSON.stringify(body) : undefined,
});
if (!res.ok) {
const text = await res.text().catch(() => '');
throw new Error(`${method} ${url} fehlgeschlagen: ${res.status} ${text}`);
let error;
try {
error = JSON.parse(text).error;
} catch {
error = text;
}
throw new Error(error || `${method} ${url} fehlgeschlagen: ${res.status}`);
}
const text = await res.text();
return text ? JSON.parse(text) : null;
}
export const api = {
// auth
login: (email, password) => request('POST', '/api/auth/login', { email, password }),
logout: () => request('POST', '/api/auth/logout'),
me: () => request('GET', '/api/auth/me'),
// vacations
getVacations: () => request('GET', '/api/vacations'),
createVacation: (data) => request('POST', '/api/vacations', data),
updateVacation: (id, data) => request('PUT', `/api/vacations/${id}`, data),
deleteVacation: (id) => request('DELETE', `/api/vacations/${id}`),
// users
getUsers: () => request('GET', '/api/users'),
createUser: (data) => request('POST', '/api/users', data),
updateUser: (id, data) => request('PUT', `/api/users/${id}`, data),
deleteUser: (id) => request('DELETE', `/api/users/${id}`),
// employees
getEmployees: () => request('GET', '/api/employees'),
createEmployee: (data) => request('POST', '/api/employees', data),