diff --git a/app/components/SidebarTodayEvents.vue b/app/components/SidebarTodayEvents.vue
index 5afdd17..a05d15f 100644
--- a/app/components/SidebarTodayEvents.vue
+++ b/app/components/SidebarTodayEvents.vue
@@ -6,9 +6,7 @@ import { motion, AnimatePresence } from "motion-v"
import type { TEventType } from "~/types/calendar"
const scheduleStore = useScheduleStore()
-const calendarStore = useCalendarStore()
const { selectedSchedule } = storeToRefs(scheduleStore)
-const { allEvents } = storeToRefs(calendarStore)
const { formatTime, formatDate } = useEventFormatting()
const { effectiveTimezone } = useTimezone()
@@ -24,13 +22,33 @@ const formattedDate = computed(() => {
return `${day}, ${date}`
})
-// Filter the already-loaded full-year events to the preview date — no extra network request.
-// 3.3 fix: guard auditorium?.name — auditorium can be null for online lessons.
+// Own query pinned to today's academic year — independent of the calendar's
+// navigation date. TanStack dedupes when the user is in the same academic year
+// (zero extra requests); diverges only when they navigate to a different year.
+const scheduleId = computed(() => selectedSchedule.value?.id)
+const todayRange = getAcademicYearRange(new Date())
+const todayStart = computed(() => {
+ if (!selectedSchedule.value) return undefined
+ return Math.floor(todayRange.start.getTime() / 1000)
+})
+const todayEnd = computed(() => {
+ if (!selectedSchedule.value) return undefined
+ return Math.floor(todayRange.end.getTime() / 1000)
+})
+
+const { data: todayRangeEvents, isLoading } = useScheduleQuery(scheduleId, todayStart, todayEnd)
+
+// Filter the year-range events down to just previewDate — no extra network request.
+// dayKey drives the outer AnimatePresence key so changing date triggers a full
+// wait-mode swap: old list exits, then new list enters (no stacking).
+const dayKey = computed(() =>
+ formatInTimeZone(previewDate.value, effectiveTimezone.value, "yyyy-MM-dd")
+)
const todayEvents = computed(() => {
+ if (!todayRangeEvents.value) return []
const tz = effectiveTimezone.value
- const targetKey = formatInTimeZone(previewDate.value, tz, "yyyy-MM-dd")
- return allEvents.value.filter(
- (e) => formatInTimeZone(new Date(e.startedAt * 1000), tz, "yyyy-MM-dd") === targetKey
+ return todayRangeEvents.value.filter(
+ (e) => formatInTimeZone(new Date(e.startedAt * 1000), tz, "yyyy-MM-dd") === dayKey.value
)
})
@@ -86,39 +104,42 @@ const hasEvents = computed(() => todayEvents.value.length > 0)
-
+
+
+
+
+
-
+
diff --git a/app/components/calendar/month/DayCell.vue b/app/components/calendar/month/DayCell.vue
index 2c2728a..ddf06f5 100644
--- a/app/components/calendar/month/DayCell.vue
+++ b/app/components/calendar/month/DayCell.vue
@@ -43,9 +43,10 @@ const { trackEvent } = useAnalytics()
// SSR serializer puts object keys first; client patchClass appends them after static.
const dayClasses = computed(() =>
cn("flex size-6 items-center justify-center rounded-full text-xs font-medium", {
- "text-muted-foreground/50": !props.cell.currentMonth,
+ "text-muted-foreground/50": !props.cell.currentMonth && !props.isDateToday,
"text-muted-foreground": props.cell.currentMonth && !props.isDateToday,
"bg-primary": props.isDateToday && props.cell.currentMonth,
+ "bg-primary/40": props.isDateToday && !props.cell.currentMonth,
})
)
diff --git a/app/pages/index.vue b/app/pages/index.vue
index 8f028b3..934cb3e 100644
--- a/app/pages/index.vue
+++ b/app/pages/index.vue
@@ -38,18 +38,6 @@ useSeo({
const hasActiveSchedule = computed(() => !!selectedSchedule.value)
const scheduleId = computed(() => selectedSchedule.value?.id)
-const getAcademicYearRange = (date: Date) => {
- // Academic year: Sept 1 → Sept 1. Pad ±7 days so month/week grid cells
- // that overhang the boundary (up to 6 days in either direction) still have
- // events fetched. Without the pad, September cells in August's grid and
- // August cells in September's grid render empty.
- const startYear = date.getMonth() < 8 ? date.getFullYear() - 1 : date.getFullYear()
- return {
- start: new Date(startYear, 8, 1 - 7, 0, 0, 0, 0),
- end: new Date(startYear + 1, 8, 1 + 7, 23, 59, 59, 999),
- }
-}
-
const dateRange = computed(() => getAcademicYearRange(selectedDate.value))
const startTimestamp = computed(() => {
diff --git a/app/utils/academic-year.ts b/app/utils/academic-year.ts
new file mode 100644
index 0000000..0b3bbd4
--- /dev/null
+++ b/app/utils/academic-year.ts
@@ -0,0 +1,13 @@
+/**
+ * Returns the academic year date range covering the given date.
+ * Academic year: Sept 1 → Sept 1. Padded ±7 days so month/week grid cells
+ * that overhang the boundary (up to 6 days in either direction) still have
+ * events fetched.
+ */
+export const getAcademicYearRange = (date: Date) => {
+ const startYear = date.getMonth() < 8 ? date.getFullYear() - 1 : date.getFullYear()
+ return {
+ start: new Date(startYear, 8, 1 - 7, 0, 0, 0, 0),
+ end: new Date(startYear + 1, 8, 1 + 7, 23, 59, 59, 999),
+ }
+}
diff --git a/package.json b/package.json
index 52ee446..5114e2c 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "mindenit-schedule",
- "version": "1.2.1",
+ "version": "1.2.2",
"private": true,
"type": "module",
"scripts": {