152 lines
5.1 KiB
TypeScript
152 lines
5.1 KiB
TypeScript
interface AttendanceRecord {
|
|
arrival_time?: string | null
|
|
departure_time?: string | null
|
|
break_start?: string | null
|
|
break_end?: string | null
|
|
leave_type?: string
|
|
leave_hours?: number
|
|
shift_date?: string
|
|
notes?: string
|
|
project_logs?: Array<{
|
|
id?: number
|
|
project_id?: number
|
|
project_name?: string
|
|
started_at?: string
|
|
ended_at?: string | null
|
|
hours?: string | number | null
|
|
minutes?: string | number | null
|
|
}>
|
|
}
|
|
|
|
export const formatDate = (dateStr: string | null | undefined): string => {
|
|
if (!dateStr) return '—'
|
|
const d = new Date(dateStr)
|
|
return d.toLocaleDateString('cs-CZ')
|
|
}
|
|
|
|
export const formatDatetime = (datetime: string | null | undefined): string => {
|
|
if (!datetime) return '—'
|
|
const d = new Date(datetime)
|
|
return `${d.getDate()}.${d.getMonth() + 1}. ${d.toLocaleTimeString('cs-CZ', { hour: '2-digit', minute: '2-digit' })}`
|
|
}
|
|
|
|
export const formatTime = (datetime: string | null | undefined): string => {
|
|
if (!datetime) return '—'
|
|
return new Date(datetime).toLocaleTimeString('cs-CZ', { hour: '2-digit', minute: '2-digit' })
|
|
}
|
|
|
|
export const calculateWorkMinutes = (record: AttendanceRecord): number => {
|
|
if (!record.arrival_time || !record.departure_time) return 0
|
|
const arrival = new Date(record.arrival_time).getTime()
|
|
const departure = new Date(record.departure_time).getTime()
|
|
let minutes = (departure - arrival) / 60000
|
|
|
|
if (record.break_start && record.break_end) {
|
|
const breakStart = new Date(record.break_start).getTime()
|
|
const breakEnd = new Date(record.break_end).getTime()
|
|
minutes -= (breakEnd - breakStart) / 60000
|
|
}
|
|
|
|
return Math.max(0, Math.floor(minutes))
|
|
}
|
|
|
|
export const formatMinutes = (minutes: number, withUnit = false): string => {
|
|
const h = Math.floor(minutes / 60)
|
|
const m = minutes % 60
|
|
return `${h}:${String(m).padStart(2, '0')}${withUnit ? ' h' : ''}`
|
|
}
|
|
|
|
export const getLeaveTypeName = (type: string): string => {
|
|
const types: Record<string, string> = {
|
|
work: 'Práce',
|
|
vacation: 'Dovolená',
|
|
sick: 'Nemoc',
|
|
holiday: 'Svátek',
|
|
unpaid: 'Neplacené volno',
|
|
}
|
|
return types[type] || 'Práce'
|
|
}
|
|
|
|
export const getLeaveTypeBadgeClass = (type: string): string => {
|
|
const classes: Record<string, string> = {
|
|
vacation: 'badge-vacation',
|
|
sick: 'badge-sick',
|
|
holiday: 'badge-holiday',
|
|
unpaid: 'badge-unpaid',
|
|
}
|
|
return classes[type] || ''
|
|
}
|
|
|
|
export const getDatePart = (datetime: string | null | undefined): string => {
|
|
if (!datetime) return ''
|
|
if (datetime.includes('T')) {
|
|
return datetime.split('T')[0]
|
|
}
|
|
return datetime.split(' ')[0]
|
|
}
|
|
|
|
export const getTimePart = (datetime: string | null | undefined): string => {
|
|
if (!datetime) return ''
|
|
const d = new Date(datetime)
|
|
return `${String(d.getHours()).padStart(2, '0')}:${String(d.getMinutes()).padStart(2, '0')}`
|
|
}
|
|
|
|
export const calcProjectMinutesTotal = (logs: Array<{ project_id?: number; hours?: string | number; minutes?: string | number }>): number => {
|
|
return logs.filter(l => l.project_id).reduce((sum, l) => {
|
|
return sum + (parseInt(String(l.hours)) || 0) * 60 + (parseInt(String(l.minutes)) || 0)
|
|
}, 0)
|
|
}
|
|
|
|
interface ShiftForm {
|
|
arrival_time?: string
|
|
departure_time?: string
|
|
arrival_date?: string
|
|
departure_date?: string
|
|
break_start_time?: string
|
|
break_end_time?: string
|
|
break_start_date?: string
|
|
break_end_date?: string
|
|
}
|
|
|
|
export const calcFormWorkMinutes = (form: ShiftForm): number => {
|
|
if (!form.arrival_time || !form.departure_time) return 0
|
|
const arrivalStr = `${form.arrival_date}T${form.arrival_time}`
|
|
const departureStr = `${form.departure_date}T${form.departure_time}`
|
|
let mins = (new Date(departureStr).getTime() - new Date(arrivalStr).getTime()) / 60000
|
|
if (form.break_start_time && form.break_end_time) {
|
|
const bsStr = `${form.break_start_date}T${form.break_start_time}`
|
|
const beStr = `${form.break_end_date}T${form.break_end_time}`
|
|
mins -= (new Date(beStr).getTime() - new Date(bsStr).getTime()) / 60000
|
|
}
|
|
return Math.max(0, Math.floor(mins))
|
|
}
|
|
|
|
export const formatTimeOrDatetimePrint = (datetime: string | null | undefined, shiftDate: string): string => {
|
|
if (!datetime) return '—'
|
|
const timeDate = new Date(datetime).toISOString().split('T')[0]
|
|
if (timeDate !== shiftDate) {
|
|
const d = new Date(datetime)
|
|
return `${d.getDate()}.${d.getMonth() + 1}. ${d.toLocaleTimeString('cs-CZ', { hour: '2-digit', minute: '2-digit' })}`
|
|
}
|
|
return new Date(datetime).toLocaleTimeString('cs-CZ', { hour: '2-digit', minute: '2-digit' })
|
|
}
|
|
|
|
export const calculateWorkMinutesPrint = (record: AttendanceRecord): number => {
|
|
const leaveType = record.leave_type || 'work'
|
|
if (leaveType !== 'work') {
|
|
return (Number(record.leave_hours) || 8) * 60
|
|
}
|
|
if (!record.arrival_time || !record.departure_time) return 0
|
|
const arrival = new Date(record.arrival_time).getTime()
|
|
const departure = new Date(record.departure_time).getTime()
|
|
let minutes = (departure - arrival) / 60000
|
|
|
|
if (record.break_start && record.break_end) {
|
|
const breakStart = new Date(record.break_start).getTime()
|
|
const breakEnd = new Date(record.break_end).getTime()
|
|
minutes -= (breakEnd - breakStart) / 60000
|
|
}
|
|
|
|
return Math.max(0, Math.floor(minutes))
|
|
}
|