// Reads employee names from first column of xlsx (skips header row 0) export function readEmployeeNames(arrayBuffer) { const wb = XLSX.read(arrayBuffer, { type: 'array' }); const sheet = wb.Sheets[wb.SheetNames[0]]; const rows = XLSX.utils.sheet_to_json(sheet, { header: 1 }); return rows.slice(1) .map(row => String(row[0] ?? '').trim()) .filter(name => name.length > 0); } // Pure helper: returns { names: [...], dates: [...] } columns for a schedule. // Multiple employees per date are joined alphabetically with " & ". export function buildScheduleColumns(assignments, employees) { const nameById = Object.fromEntries(employees.map(e => [e.id, e.name])); const byDate = new Map(); for (const a of assignments) { if (!byDate.has(a.date)) byDate.set(a.date, []); byDate.get(a.date).push(nameById[a.employeeId] ?? ''); } const sortedDates = [...byDate.keys()].sort(); const names = sortedDates.map(d => byDate.get(d).slice().sort((x, y) => x.localeCompare(y, 'de')).join(' & ') ); const dates = sortedDates.map(d => { const [y, m, day] = d.split('-'); return day + '.' + m + '.' + y; }); return { names, dates }; } // Exports schedule as xlsx blob // assignments: [{ date: "2026-04-01", employeeId }] — multiple entries per date allowed // employees: [{ id, name }] export function exportSchedule(assignments, employees) { const { names, dates } = buildScheduleColumns(assignments, employees); const ws = XLSX.utils.aoa_to_sheet([names, dates]); const wb = XLSX.utils.book_new(); XLSX.utils.book_append_sheet(wb, ws, 'Moderationsplan'); const buf = XLSX.write(wb, { type: 'array', bookType: 'xlsx' }); return new Blob([buf], { type: 'application/octet-stream' }); } export function downloadBlob(blob, filename) { const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = filename; a.click(); URL.revokeObjectURL(url); }