173 lines
3.4 KiB
Vue
173 lines
3.4 KiB
Vue
<script setup>
|
|
const props = defineProps({
|
|
day: Object,
|
|
})
|
|
|
|
const emit = defineEmits(['event-click'])
|
|
|
|
const handleEventClick = (eventId) => {
|
|
emit('event-click', { id: eventId, instanceId: eventId, occurrenceIndex: 0 })
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<div
|
|
class="cell"
|
|
:class="[
|
|
props.day.monthClass,
|
|
{
|
|
today: props.day.isToday,
|
|
weekend: props.day.isWeekend,
|
|
firstday: props.day.isFirstDay,
|
|
selected: props.day.isSelected,
|
|
holiday: props.day.isHoliday,
|
|
},
|
|
]"
|
|
:data-date="props.day.date"
|
|
>
|
|
<h1>{{ props.day.displayText }}</h1>
|
|
<span v-if="props.day.lunarPhase" class="lunar-phase">{{ props.day.lunarPhase }}</span>
|
|
|
|
<!-- Holiday indicator -->
|
|
<div v-if="props.day.holiday" class="holiday-info">
|
|
<span class="holiday-name" :title="props.day.holiday.name">
|
|
{{ props.day.holiday.name }}
|
|
</span>
|
|
</div>
|
|
|
|
<!-- Simple event display for now -->
|
|
<div v-if="props.day.events && props.day.events.length > 0" class="day-events">
|
|
<div
|
|
v-for="event in props.day.events.slice(0, 3)"
|
|
:key="event.id"
|
|
class="event-dot"
|
|
:class="`event-color-${event.colorId}`"
|
|
:title="event.title"
|
|
@click.stop="handleEventClick(event.id)"
|
|
></div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<style scoped>
|
|
.cell {
|
|
position: relative;
|
|
border-right: 1px solid var(--border-color);
|
|
border-bottom: 1px solid var(--border-color);
|
|
user-select: none;
|
|
touch-action: none;
|
|
display: flex;
|
|
flex-direction: row;
|
|
align-items: flex-start;
|
|
justify-content: flex-start;
|
|
padding: 0.25em;
|
|
overflow: hidden;
|
|
width: 100%;
|
|
height: var(--cell-h);
|
|
font-weight: 700;
|
|
transition: background-color 0.15s ease;
|
|
}
|
|
|
|
.cell h1 {
|
|
margin: 0;
|
|
padding: 0;
|
|
min-width: 1.5em;
|
|
font-size: 1em;
|
|
font-weight: 700;
|
|
color: var(--ink);
|
|
transition: background-color 0.15s ease;
|
|
}
|
|
|
|
.cell.today h1 {
|
|
border-radius: 2em;
|
|
background: var(--today);
|
|
border: 0.2em solid var(--today);
|
|
margin: -0.2em;
|
|
color: white;
|
|
font-weight: bold;
|
|
}
|
|
|
|
.cell:hover h1 {
|
|
text-shadow: 0 0 0.2em var(--shadow);
|
|
}
|
|
|
|
.cell.weekend h1 {
|
|
color: var(--weekend);
|
|
}
|
|
.cell.firstday h1 {
|
|
color: var(--firstday);
|
|
text-shadow: 0 0 0.1em var(--strong);
|
|
}
|
|
.cell.selected {
|
|
filter: hue-rotate(180deg);
|
|
}
|
|
.cell.selected h1 {
|
|
color: var(--strong);
|
|
}
|
|
|
|
.lunar-phase {
|
|
position: absolute;
|
|
top: 0.1em;
|
|
right: 0.1em;
|
|
font-size: 0.8em;
|
|
opacity: 0.7;
|
|
}
|
|
|
|
.cell.holiday {
|
|
background-color: var(--holiday-bg, rgba(255, 215, 0, 0.1));
|
|
border-color: var(--holiday-border, rgba(255, 215, 0, 0.3));
|
|
}
|
|
|
|
.cell.holiday h1 {
|
|
color: var(--holiday-text, #8b4513);
|
|
font-weight: bold;
|
|
}
|
|
|
|
.holiday-info {
|
|
position: absolute;
|
|
bottom: 0.1em;
|
|
left: 0.1em;
|
|
right: 0.1em;
|
|
font-size: 0.7em;
|
|
line-height: 1;
|
|
max-height: 2.4em;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.holiday-name {
|
|
display: block;
|
|
background: var(--holiday-label-bg, rgba(255, 215, 0, 0.8));
|
|
color: var(--holiday-label-text, #5d4037);
|
|
padding: 0.1em 0.2em;
|
|
border-radius: 0.2em;
|
|
font-weight: 600;
|
|
font-size: 0.85em;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
overflow: hidden;
|
|
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
|
|
}
|
|
|
|
.day-events {
|
|
position: absolute;
|
|
top: 1.5em;
|
|
right: 0.1em;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 0.1em;
|
|
}
|
|
|
|
.event-dot {
|
|
width: 0.6em;
|
|
height: 0.6em;
|
|
border-radius: 50%;
|
|
cursor: pointer;
|
|
opacity: 0.8;
|
|
transition: opacity 0.2s ease;
|
|
}
|
|
|
|
.event-dot:hover {
|
|
opacity: 1;
|
|
}
|
|
</style>
|