diff --git a/src/lib/CalendarMonth.svelte b/src/lib/CalendarMonth.svelte index 8f6c725..87ff74e 100644 --- a/src/lib/CalendarMonth.svelte +++ b/src/lib/CalendarMonth.svelte @@ -6,10 +6,33 @@ export let holidays = []; export let optimizedDaysOff = []; export let consecutiveDaysOff = []; + export let selectedCountryCode; + + // Function to determine the first day of the week based on locale + function getFirstDayOfWeek(locale) { + // Convert 'us' to proper locale format + const normalizedLocale = locale.toLowerCase() === 'us' ? 'en-US' : `en-${locale.toUpperCase()}`; + + try { + // Try to get firstDay from Intl.Locale weekInfo + // @ts-ignore .weekInfo exists on all browsers except Firefox + const weekFirstDay = new Intl.Locale(normalizedLocale)?.weekInfo?.firstDay; + if (weekFirstDay !== undefined) { + return weekFirstDay; + } + } catch (e) { + // Fallback if weekInfo is not supported + } + + // Fallback: US starts on Sunday (0), most others on Monday (1) + return normalizedLocale === 'en-US' ? 0 : 1; + } // Reactive declarations $: daysInMonth = getDaysInMonth(year, month); - $: firstDay = getFirstDayOfMonth(year, month); + $: locale = selectedCountryCode ? new Intl.Locale(selectedCountryCode).toString() : 'us'; + $: firstDayOfWeek = getFirstDayOfWeek(locale); + $: adjustedFirstDay = (getFirstDayOfMonth(year, month) - firstDayOfWeek + 7) % 7; function getDaysInMonth(year, month) { return new Date(year, month + 1, 0).getDate(); @@ -58,15 +81,45 @@ return date >= start && date <= end; }); } + + // Function to determine if a day is a weekend + function isWeekend(day) { + const dayOfWeek = (adjustedFirstDay + day - 1) % 7; + // Calculate the indices for Saturday and Sunday + const saturdayIndex = (6 - firstDayOfWeek + 7) % 7; + const sundayIndex = (7 - firstDayOfWeek + 7) % 7; + return dayOfWeek === saturdayIndex || dayOfWeek === sundayIndex; + } + + // Function to get the localized day initials based on the first day of the week + function getLocalizedDayInitials(locale) { + const formatter = new Intl.DateTimeFormat(locale, { weekday: 'short' }); + const dayInitials = []; + for (let i = 0; i < 7; i++) { + const date = new Date(Date.UTC(2021, 0, i + 3)); // Start from a known Thursday to ensure full week coverage + const dayName = formatter.format(date); + dayInitials.push(dayName.charAt(0).toUpperCase()); + } + return dayInitials; + } + + // Reactive declaration to get the ordered day initials + $: orderedDayInitials = getLocalizedDayInitials(locale).slice(firstDayOfWeek).concat(getLocalizedDayInitials(locale).slice(0, firstDayOfWeek));
{new Date(year, month).toLocaleString('default', { month: 'long' })}
- {#each Array.from({ length: firstDay }) as _} + + + {#each orderedDayInitials as dayInitial} +
{dayInitial}
+ {/each} + + {#each Array.from({ length: adjustedFirstDay }) as _}
{/each} {#each Array.from({ length: daysInMonth }, (_, i) => i + 1) as day} -
+
{day} {#if getHoliday(day)} @@ -96,6 +149,12 @@ width: 100%; height: auto; } + .day-initial { + text-align: center; + font-weight: bold; + color: #c5c6c7; + font-size: 0.6em; + } .day { aspect-ratio: 1; text-align: center; diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index 503c915..54d2474 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -35,6 +35,12 @@ let showHolidaysList = false; // State to toggle the visibility of the holidays list + $: selectedCountryCode = Object.keys(countriesList).find(code => countriesList[code] === selectedCountry); + + $: if (selectedCountryCode || selectedStateCode || daysOff) { + updateHolidays(); + } + function updateStatesList(countryCode) { const hd = new Holidays(countryCode); statesList = hd.getStates(countryCode) || []; @@ -44,7 +50,6 @@ const stateName = event.target.value; selectedStateCode = Object.keys(statesList).find(code => statesList[code] === stateName); selectedState = stateName; - updateHolidays(); localStorage.setItem('selectedState', selectedState); localStorage.setItem('selectedStateCode', selectedStateCode); } @@ -70,13 +75,12 @@ daysOff = storedDaysOff ? parseInt(storedDaysOff, 10) : defaultDaysOff; selectedState = storedState || ''; selectedStateCode = storedStateCode || ''; - updateHolidays(); }); - const countryCode = Object.keys(countriesList).find(code => countriesList[code] === selectedCountry); - if (countryCode) { - updateStatesList(countryCode); + if (selectedCountryCode) { + updateStatesList(selectedCountryCode); } + window.addEventListener('keydown', handleKeyDown); }); async function fetchCountryCode() { @@ -94,14 +98,11 @@ function handleCountryChange(event) { const fullValue = event.target.value; - const countryCode = Object.keys(countriesList).find(code => countriesList[code] === fullValue); - if (countryCode) { - selectedCountry = fullValue; - daysOff = ptoData[countryCode] || 0; + if (selectedCountryCode) { + daysOff = ptoData[selectedCountryCode] || 0; selectedState = ''; // Reset state selectedStateCode = ''; // Reset state code - updateStatesList(countryCode); // Update states list for the new country - updateHolidays(); + updateStatesList(selectedCountryCode); // Update states list for the new country localStorage.setItem('selectedCountry', selectedCountry); localStorage.setItem('selectedState', selectedState); localStorage.setItem('selectedStateCode', selectedStateCode); @@ -110,15 +111,13 @@ } function updateHolidays() { - const countryCode = Object.keys(countriesList).find(code => countriesList[code] === selectedCountry); - if (countryCode) { - updateStatesList(countryCode); - let allHolidays = getHolidaysForYear(countryCode, year, selectedStateCode); + if (selectedCountryCode) { + updateStatesList(selectedCountryCode); + let allHolidays = getHolidaysForYear(selectedCountryCode, year, selectedStateCode); holidays = allHolidays.map(holiday => ({ ...holiday, hidden: isHolidayHidden(holiday) })); - // Filter out hidden holidays for calculations const visibleHolidays = holidays.filter(h => !h.hidden); optimizedDaysOff = optimizeDaysOff(visibleHolidays, year, daysOff); consecutiveDaysOff = calculateConsecutiveDaysOff(visibleHolidays, optimizedDaysOff, year); @@ -142,7 +141,6 @@ localStorage.setItem('selectedState', selectedState); localStorage.setItem('selectedStateCode', selectedStateCode); localStorage.setItem('daysOff', daysOff); - updateHolidays(); } function handleKeyDown(event) { @@ -665,7 +663,14 @@
{#each months as month}
- +
{/each}