Add entry image backgrounds and indicators to calendar !
This commit is contained in:
@@ -1,7 +1,15 @@
|
||||
<script lang="ts">
|
||||
interface Entry {
|
||||
date: string;
|
||||
id: string;
|
||||
image?: string;
|
||||
content: string;
|
||||
}
|
||||
|
||||
let {
|
||||
year = $bindable('2026'),
|
||||
month = $bindable('0')
|
||||
month = $bindable('0'),
|
||||
entries
|
||||
} = $props()
|
||||
|
||||
var headers = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"];
|
||||
@@ -10,6 +18,16 @@
|
||||
let currentYear = $state(parseInt(year));
|
||||
let currentMonth = $state(parseInt(month));
|
||||
|
||||
// Helper function to find entry for a specific day
|
||||
function getEntryForDay(year: number, month: number, date: number): Entry | undefined {
|
||||
if (!entries) return undefined;
|
||||
const dateStr = new Date(year, month, date).toISOString().split('T')[0];
|
||||
return entries.find(entry => {
|
||||
const entryDate = entry.date.split('T')[0];
|
||||
return entryDate === dateStr;
|
||||
});
|
||||
}
|
||||
|
||||
// Get current week when in week view
|
||||
function getCurrentWeek() {
|
||||
const today = new Date();
|
||||
@@ -23,13 +41,15 @@
|
||||
for (let i = 0; i < 7; i++) {
|
||||
const day = new Date(monday);
|
||||
day.setDate(monday.getDate() + i);
|
||||
const entry = getEntryForDay(day.getFullYear(), day.getMonth(), day.getDate());
|
||||
week.push({
|
||||
date: day.getDate(),
|
||||
month: day.getMonth(),
|
||||
year: day.getFullYear(),
|
||||
dayName: headers[i],
|
||||
isCurrentMonth: day.getMonth() === today.getMonth(),
|
||||
isToday: day.toDateString() === today.toDateString()
|
||||
isToday: day.toDateString() === today.toDateString(),
|
||||
entry
|
||||
});
|
||||
}
|
||||
return week;
|
||||
@@ -51,13 +71,18 @@
|
||||
const prevMonthLastDay = new Date(year, month, 0).getDate();
|
||||
for (let i = startDay - 1; i >= 0; i--) {
|
||||
const dayIndex = days.length % 7;
|
||||
const dayDate = prevMonthLastDay - i;
|
||||
const dayMonth = month - 1;
|
||||
const dayYear = month === 0 ? year - 1 : year;
|
||||
const entry = getEntryForDay(dayYear, dayMonth, dayDate);
|
||||
days.push({
|
||||
date: prevMonthLastDay - i,
|
||||
month: month - 1,
|
||||
year: month === 0 ? year - 1 : year,
|
||||
date: dayDate,
|
||||
month: dayMonth,
|
||||
year: dayYear,
|
||||
dayName: headers[dayIndex],
|
||||
isCurrentMonth: false,
|
||||
isToday: false
|
||||
isToday: false,
|
||||
entry
|
||||
});
|
||||
}
|
||||
|
||||
@@ -68,13 +93,15 @@
|
||||
today.getMonth() === month &&
|
||||
today.getFullYear() === year;
|
||||
const dayIndex = days.length % 7;
|
||||
const entry = getEntryForDay(year, month, i);
|
||||
days.push({
|
||||
date: i,
|
||||
month: month,
|
||||
year: year,
|
||||
dayName: headers[dayIndex],
|
||||
isCurrentMonth: true,
|
||||
isToday
|
||||
isToday,
|
||||
entry
|
||||
});
|
||||
}
|
||||
|
||||
@@ -82,13 +109,17 @@
|
||||
const remaining = 42 - days.length; // 6 rows * 7 days
|
||||
for (let i = 1; i <= remaining; i++) {
|
||||
const dayIndex = days.length % 7;
|
||||
const dayMonth = month + 1;
|
||||
const dayYear = month === 11 ? year + 1 : year;
|
||||
const entry = getEntryForDay(dayYear, dayMonth, i);
|
||||
days.push({
|
||||
date: i,
|
||||
month: month + 1,
|
||||
year: month === 11 ? year + 1 : year,
|
||||
month: dayMonth,
|
||||
year: dayYear,
|
||||
dayName: headers[dayIndex],
|
||||
isCurrentMonth: false,
|
||||
isToday: false
|
||||
isToday: false,
|
||||
entry
|
||||
});
|
||||
}
|
||||
|
||||
@@ -155,12 +186,24 @@
|
||||
|
||||
<div class="calendar">
|
||||
{#each days as day, index}
|
||||
<div class="day" class:other-month={!day.isCurrentMonth} class:today={day.isToday}>
|
||||
<div
|
||||
class="day"
|
||||
class:other-month={!day.isCurrentMonth}
|
||||
class:today={day.isToday}
|
||||
class:has-image={day.entry?.image}
|
||||
style={day.entry?.image ? `background-image: url(${day.entry.image}); background-size: cover; background-position: center;` : ''}
|
||||
>
|
||||
{#if day.entry?.image}
|
||||
<div class="image-overlay"></div>
|
||||
{/if}
|
||||
<div class="day-header">
|
||||
{#if index < 7}
|
||||
<span class="day-name">{day.dayName}</span>
|
||||
{/if}
|
||||
<span class="date">{day.date}</span>
|
||||
{#if day.entry}
|
||||
<span class="entry-indicator"></span>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
{/each}
|
||||
@@ -187,7 +230,7 @@
|
||||
height: 36px;
|
||||
border: 1px solid rgba(166, 168, 179, 0.2);
|
||||
background: transparent;
|
||||
color: #e9a1a7;
|
||||
color: #009FB7;
|
||||
font-size: 24px;
|
||||
cursor: pointer;
|
||||
border-radius: 4px;
|
||||
@@ -199,7 +242,7 @@
|
||||
|
||||
.expand-btn:hover {
|
||||
background: rgba(233, 161, 167, 0.1);
|
||||
border-color: #e9a1a7;
|
||||
border-color: #009FB7;
|
||||
}
|
||||
|
||||
.nav-btn {
|
||||
@@ -207,7 +250,7 @@
|
||||
height: 32px;
|
||||
border: 1px solid rgba(166, 168, 179, 0.2);
|
||||
background: transparent;
|
||||
color: #e9a1a7;
|
||||
color: #009FB7;
|
||||
font-size: 20px;
|
||||
cursor: pointer;
|
||||
border-radius: 4px;
|
||||
@@ -219,13 +262,13 @@
|
||||
|
||||
.nav-btn:hover {
|
||||
background: rgba(233, 161, 167, 0.1);
|
||||
border-color: #e9a1a7;
|
||||
border-color: #009FB7;
|
||||
}
|
||||
|
||||
.month-year {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: #e9a1a7;
|
||||
color: #009FB7;
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
}
|
||||
@@ -248,17 +291,33 @@
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.day.has-image {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.image-overlay {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: rgba(0, 0, 0, 0.3);
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.day-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 8px;
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.day-name {
|
||||
font-size: 12px;
|
||||
text-transform: uppercase;
|
||||
color: #e9a1a7;
|
||||
color: #009FB7;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
@@ -268,6 +327,21 @@
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
|
||||
.entry-indicator {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 50%;
|
||||
background-color: #4a9eff;
|
||||
display: inline-block;
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
.day.has-image .day-name,
|
||||
.day.has-image .date {
|
||||
color: white;
|
||||
text-shadow: 0 1px 3px rgba(0, 0, 0, 0.8);
|
||||
}
|
||||
|
||||
.day.other-month {
|
||||
opacity: 0.3;
|
||||
}
|
||||
@@ -277,7 +351,7 @@
|
||||
}
|
||||
|
||||
.day.today .date {
|
||||
color: #e9a1a7;
|
||||
color: #009FB7;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
<Calendar />
|
||||
<Calendar entries={data.all} />
|
||||
|
||||
<div class="flex flex-col md:flex-row space-y-4 w-full mt-6">
|
||||
|
||||
|
||||
Reference in New Issue
Block a user