Add missing
This commit is contained in:
101
src/lib/CalendarMonth.svelte
Normal file
101
src/lib/CalendarMonth.svelte
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
<script>
|
||||||
|
import Tooltip from './Tooltip.svelte';
|
||||||
|
|
||||||
|
export let year;
|
||||||
|
export let month;
|
||||||
|
export let holidays = [];
|
||||||
|
export let optimizedDaysOff = [];
|
||||||
|
|
||||||
|
function getDaysInMonth(year, month) {
|
||||||
|
return new Date(year, month + 1, 0).getDate();
|
||||||
|
}
|
||||||
|
|
||||||
|
function getFirstDayOfMonth(year, month) {
|
||||||
|
return new Date(year, month, 1).getDay();
|
||||||
|
}
|
||||||
|
|
||||||
|
let daysInMonth = getDaysInMonth(year, month);
|
||||||
|
let firstDay = getFirstDayOfMonth(year, month);
|
||||||
|
|
||||||
|
function getHoliday(day) {
|
||||||
|
return holidays.find(holiday =>
|
||||||
|
holiday.date.getFullYear() === year &&
|
||||||
|
holiday.date.getMonth() === month &&
|
||||||
|
holiday.date.getDate() === day
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function isOptimizedDayOff(day) {
|
||||||
|
return optimizedDaysOff.some(date =>
|
||||||
|
date.getFullYear() === year &&
|
||||||
|
date.getMonth() === month &&
|
||||||
|
date.getDate() === day
|
||||||
|
);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.calendar {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(7, 1fr);
|
||||||
|
gap: 1px;
|
||||||
|
border: 1px solid #444;
|
||||||
|
padding: 5px;
|
||||||
|
margin: 5px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
.day {
|
||||||
|
aspect-ratio: 1;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 0.7em;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
color: #ddd;
|
||||||
|
background-color: #222;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.day:hover {
|
||||||
|
:global(.tooltip) {
|
||||||
|
opacity: 1;
|
||||||
|
pointer-events: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.weekend {
|
||||||
|
background-color: #333;
|
||||||
|
}
|
||||||
|
.holiday {
|
||||||
|
background-color: #555;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.optimized {
|
||||||
|
background-color: #4caf50;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
.month-name {
|
||||||
|
grid-column: span 7;
|
||||||
|
text-align: center;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 0.8em;
|
||||||
|
margin-bottom: 2px;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div class="calendar">
|
||||||
|
<div class="month-name">{new Date(year, month).toLocaleString('default', { month: 'long' })}</div>
|
||||||
|
{#each Array.from({ length: firstDay }) as _}
|
||||||
|
<div class="day"></div>
|
||||||
|
{/each}
|
||||||
|
{#each Array.from({ length: daysInMonth }, (_, i) => i + 1) as day}
|
||||||
|
<div class="day {(firstDay + day - 1) % 7 === 0 || (firstDay + day - 1) % 7 === 6 ? 'weekend' : ''} {getHoliday(day) ? 'holiday' : ''} {isOptimizedDayOff(day) ? 'optimized' : ''}">
|
||||||
|
{day}
|
||||||
|
{#if getHoliday(day)}
|
||||||
|
<Tooltip text={getHoliday(day).name} />
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
40
src/lib/Tooltip.svelte
Normal file
40
src/lib/Tooltip.svelte
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
<script>
|
||||||
|
export let text = '';
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.tooltip {
|
||||||
|
position: absolute;
|
||||||
|
background-color: #333;
|
||||||
|
color: #fff;
|
||||||
|
padding: 5px;
|
||||||
|
border-radius: 3px;
|
||||||
|
font-size: 0.8em;
|
||||||
|
white-space: nowrap;
|
||||||
|
z-index: 1000;
|
||||||
|
pointer-events: none;
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tooltip::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 100%; /* Position the tail at the bottom of the tooltip */
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
border-width: 5px;
|
||||||
|
border-style: solid;
|
||||||
|
border-color: #333 transparent transparent transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tooltip {
|
||||||
|
bottom: 100%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div class="tooltip">
|
||||||
|
{text}
|
||||||
|
</div>
|
||||||
Reference in New Issue
Block a user