mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-06-19 13:21:46 +00:00
fix(vacay): allow vacation on public holidays and add today marker
Removes the client-side guard that blocked toggling vacation entries on public holiday dates, so users who work on holidays can still book leave. Also adds a filled blue circle on today's date in the Vacay calendar for quick orientation. Closes #651
This commit is contained in:
@@ -151,7 +151,7 @@ describe('VacayCalendar', () => {
|
|||||||
expect(toggleEntry).toHaveBeenCalledWith('2025-01-01', 42)
|
expect(toggleEntry).toHaveBeenCalledWith('2025-01-01', 42)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('FE-COMP-VACAYCALENDAR-007: cell click blocked by public holiday', async () => {
|
it('FE-COMP-VACAYCALENDAR-007: cell click on public holiday toggles vacation entry', async () => {
|
||||||
const user = userEvent.setup()
|
const user = userEvent.setup()
|
||||||
const toggleEntry = vi.fn().mockResolvedValue(undefined)
|
const toggleEntry = vi.fn().mockResolvedValue(undefined)
|
||||||
|
|
||||||
@@ -168,10 +168,10 @@ describe('VacayCalendar', () => {
|
|||||||
|
|
||||||
render(<VacayCalendar />)
|
render(<VacayCalendar />)
|
||||||
|
|
||||||
// Month 0, button emits '2025-01-01' which is a holiday
|
// Month 0, button emits '2025-01-01' which is a holiday — should still toggle vacation
|
||||||
await user.click(screen.getByText('click-0'))
|
await user.click(screen.getByText('click-0'))
|
||||||
|
|
||||||
expect(toggleEntry).not.toHaveBeenCalled()
|
expect(toggleEntry).toHaveBeenCalledWith('2025-01-01', undefined)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('FE-COMP-VACAYCALENDAR-008: cell click in company mode calls toggleCompanyHoliday', async () => {
|
it('FE-COMP-VACAYCALENDAR-008: cell click in company mode calls toggleCompanyHoliday', async () => {
|
||||||
|
|||||||
@@ -60,11 +60,10 @@ export default function VacayCalendar() {
|
|||||||
await toggleCompanyHoliday(dateStr)
|
await toggleCompanyHoliday(dateStr)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (holidays[dateStr]) return
|
|
||||||
if (blockWeekends && isWeekend(dateStr, weekendDays)) return
|
if (blockWeekends && isWeekend(dateStr, weekendDays)) return
|
||||||
if (companyHolidaysEnabled && companyHolidaySet.has(dateStr)) return
|
if (companyHolidaysEnabled && companyHolidaySet.has(dateStr)) return
|
||||||
await toggleEntry(dateStr, selectedUserId || undefined)
|
await toggleEntry(dateStr, selectedUserId || undefined)
|
||||||
}, [companyMode, toggleEntry, toggleCompanyHoliday, holidays, companyHolidaySet, blockWeekends, companyHolidaysEnabled, selectedUserId])
|
}, [companyMode, toggleEntry, toggleCompanyHoliday, companyHolidaySet, blockWeekends, companyHolidaysEnabled, selectedUserId])
|
||||||
|
|
||||||
const selectedUser = users.find(u => u.id === selectedUserId)
|
const selectedUser = users.find(u => u.id === selectedUserId)
|
||||||
|
|
||||||
|
|||||||
@@ -54,6 +54,11 @@ export default function VacayMonthCard({
|
|||||||
|
|
||||||
const pad = (n) => String(n).padStart(2, '0')
|
const pad = (n) => String(n).padStart(2, '0')
|
||||||
|
|
||||||
|
const todayStr = useMemo(() => {
|
||||||
|
const d = new Date()
|
||||||
|
return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`
|
||||||
|
}, [])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="rounded-xl border overflow-hidden" style={{ background: 'var(--bg-card)', borderColor: 'var(--border-primary)' }}>
|
<div className="rounded-xl border overflow-hidden" style={{ background: 'var(--bg-card)', borderColor: 'var(--border-primary)' }}>
|
||||||
<div className="px-3 py-2 border-b" style={{ borderColor: 'var(--border-secondary)' }}>
|
<div className="px-3 py-2 border-b" style={{ borderColor: 'var(--border-secondary)' }}>
|
||||||
@@ -85,7 +90,8 @@ export default function VacayMonthCard({
|
|||||||
const holiday = holidays[dateStr]
|
const holiday = holidays[dateStr]
|
||||||
const isCompany = companyHolidaysEnabled && companyHolidaySet.has(dateStr)
|
const isCompany = companyHolidaysEnabled && companyHolidaySet.has(dateStr)
|
||||||
const dayEntries = entryMap[dateStr] || []
|
const dayEntries = entryMap[dateStr] || []
|
||||||
const isBlocked = !!holiday || (weekend && blockWeekends) || (isCompany && !companyMode)
|
const isBlocked = (weekend && blockWeekends) || (isCompany && !companyMode)
|
||||||
|
const isToday = dateStr === todayStr
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
@@ -135,9 +141,24 @@ export default function VacayMonthCard({
|
|||||||
<span className="absolute top-[3px] right-[3px] w-[5px] h-[5px] rounded-full z-[2]" style={{ background: '#3b82f6' }} />
|
<span className="absolute top-[3px] right-[3px] w-[5px] h-[5px] rounded-full z-[2]" style={{ background: '#3b82f6' }} />
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<span className="relative z-[1] text-[11px] font-medium" style={{
|
<span className="relative z-[1] text-[11px]" style={{
|
||||||
color: holiday ? holiday.color : weekend ? 'var(--text-faint)' : 'var(--text-primary)',
|
|
||||||
fontWeight: dayEntries.length > 0 ? 700 : 500,
|
fontWeight: dayEntries.length > 0 ? 700 : 500,
|
||||||
|
color: isToday
|
||||||
|
? '#fff'
|
||||||
|
: dayEntries.length > 0
|
||||||
|
? 'var(--text-primary)'
|
||||||
|
: holiday ? holiday.color
|
||||||
|
: weekend ? 'var(--text-faint)'
|
||||||
|
: 'var(--text-primary)',
|
||||||
|
...(isToday ? {
|
||||||
|
display: 'inline-flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
width: 18,
|
||||||
|
height: 18,
|
||||||
|
borderRadius: '50%',
|
||||||
|
background: '#3b82f6',
|
||||||
|
} : {}),
|
||||||
}}>
|
}}>
|
||||||
{day}
|
{day}
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
Reference in New Issue
Block a user