Initial commit – TimeMaster Zeiterfassung & HR-Tool
Stand: agent-06 (Audit-Log), agent-05 (Krankmeldung), agent-07 Phase 1 (Personalnummer), Busylight-Pull-Integration, TOTP/2FA, Abwesenheiten, Zeiterfassung, Kiosk-Grundgerüst. Migrations 0001–0023 deployed auf 192.168.1.137 + .164. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,72 @@
|
||||
import type { AbsenceSpan } from '../types/absence'
|
||||
|
||||
export const MONTHS = [
|
||||
'Januar', 'Februar', 'März', 'April', 'Mai', 'Juni',
|
||||
'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember',
|
||||
]
|
||||
|
||||
export const MONTHS_SHORT = [
|
||||
'Jan', 'Feb', 'Mär', 'Apr', 'Mai', 'Jun',
|
||||
'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dez',
|
||||
]
|
||||
|
||||
export const DAY_LABELS = ['Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa', 'So']
|
||||
|
||||
export const STATUS_LABELS: Record<string, string> = {
|
||||
pending: 'Ausstehend',
|
||||
approved: 'Genehmigt',
|
||||
rejected: 'Abgelehnt',
|
||||
cancelled: 'Storniert',
|
||||
}
|
||||
|
||||
export const STATUS_COLORS: Record<string, string> = {
|
||||
pending: 'bg-yellow-100 text-yellow-700',
|
||||
approved: 'bg-green-100 text-green-700',
|
||||
rejected: 'bg-red-100 text-red-700',
|
||||
cancelled: 'bg-gray-100 text-gray-500',
|
||||
}
|
||||
|
||||
export const MANAGER_ROLES = ['COMPANY_ADMIN', 'SUPER_ADMIN', 'HR', 'MANAGER']
|
||||
|
||||
export function isoWeekday(d: Date): number {
|
||||
return (d.getDay() + 6) % 7
|
||||
}
|
||||
|
||||
export function buildCalendarWeeks(year: number, month: number): Date[][] {
|
||||
const first = new Date(year, month, 1)
|
||||
const last = new Date(year, month + 1, 0)
|
||||
const weeks: Date[][] = []
|
||||
let week: Date[] = []
|
||||
|
||||
// Pad from Monday to the first day of the month
|
||||
const startWd = isoWeekday(first)
|
||||
for (let i = 0; i < startWd; i++) {
|
||||
const d = new Date(year, month, 1 - (startWd - i))
|
||||
week.push(d)
|
||||
}
|
||||
|
||||
for (let day = 1; day <= last.getDate(); day++) {
|
||||
week.push(new Date(year, month, day))
|
||||
if (week.length === 7) {
|
||||
weeks.push(week)
|
||||
week = []
|
||||
}
|
||||
}
|
||||
|
||||
// Pad remaining days to complete last week
|
||||
if (week.length > 0) {
|
||||
let next = 1
|
||||
while (week.length < 7) {
|
||||
week.push(new Date(year, month + 1, next++))
|
||||
}
|
||||
weeks.push(week)
|
||||
}
|
||||
|
||||
return weeks
|
||||
}
|
||||
|
||||
export function getWeekSpans(week: Date[], spans: AbsenceSpan[]): AbsenceSpan[] {
|
||||
const weekStart = week[0]
|
||||
const weekEnd = week[week.length - 1]
|
||||
return spans.filter(s => s.start <= weekEnd && s.end >= weekStart)
|
||||
}
|
||||
Reference in New Issue
Block a user