feat: multiple holiday calendars per vacay plan

- Add vacay_holiday_calendars table (region, label, color, sort_order)
- Lazy migration of existing holidays_region to first calendar row
- Extract applyHolidayCalendars() helper; replace inline holiday logic
- GET /vacay/plan now includes holiday_calendars array
- Add POST/PUT/DELETE /vacay/plan/holiday-calendars/:id endpoints
- Client VacayPlan/VacayEntry/HolidayInfo types updated
- loadHolidays() loops over all calendars; per-calendar color on HolidayInfo
- VacayMonthCard uses holiday.color instead of hardcoded red
- VacaySettings replaced single country picker with calendar list UI
- VacayPage legend renders one item per calendar
- i18n: addCalendar, calendarLabel, calendarColor, noCalendars (en + de)
- Fix pre-existing TS errors: VacayPlan/VacayEntry missing fields,
  SettingToggleProps icon/onChange types, packing.suggestions.items array type

Closes #36
This commit is contained in:
Stephen Wheet
2026-03-28 22:16:12 +00:00
parent 1f9ae8e4b5
commit 3c4f5f7193
10 changed files with 421 additions and 122 deletions

View File

@@ -281,10 +281,23 @@ export interface WebSocketEvent {
}
// Vacay types
export interface VacayHolidayCalendar {
id: number
plan_id: number
region: string
label: string | null
color: string
sort_order: number
}
export interface VacayPlan {
id: number
holidays_enabled: boolean
holidays_region: string | null
holiday_calendars: VacayHolidayCalendar[]
block_weekends: boolean
carry_over_enabled: boolean
company_holidays_enabled: boolean
name?: string
year?: number
owner_id?: number
@@ -301,6 +314,9 @@ export interface VacayUser {
export interface VacayEntry {
date: string
user_id: number
plan_id?: number
person_color?: string
person_name?: string
}
export interface VacayStat {
@@ -312,6 +328,8 @@ export interface VacayStat {
export interface HolidayInfo {
name: string
localName: string
color: string
label: string | null
}
export interface HolidaysMap {