From 0e423180363a07d0ea2555bec7592a0dbec4a2b6 Mon Sep 17 00:00:00 2001 From: padreug Date: Thu, 23 Oct 2025 15:05:58 +0200 Subject: [PATCH] Adds date navigation to scheduled events Implements date navigation for scheduled events, allowing users to view events for different days. This change replaces the static "Today's Events" section with a dynamic date selector. It introduces buttons for navigating to the previous and next days, as well as a "Today" button to return to the current date. A date display shows the selected date, and a message indicates when there are no scheduled events for a given day. --- .../nostr-feed/components/NostrFeed.vue | 123 ++++++++++++++++-- .../composables/useScheduledEvents.ts | 10 ++ .../services/ScheduledEventService.ts | 27 ++-- 3 files changed, 137 insertions(+), 23 deletions(-) diff --git a/src/modules/nostr-feed/components/NostrFeed.vue b/src/modules/nostr-feed/components/NostrFeed.vue index 7f22c2b..0c2ae18 100644 --- a/src/modules/nostr-feed/components/NostrFeed.vue +++ b/src/modules/nostr-feed/components/NostrFeed.vue @@ -9,7 +9,7 @@ import { DialogHeader, DialogTitle, } from '@/components/ui/dialog' -import { Megaphone, RefreshCw, AlertCircle } from 'lucide-vue-next' +import { Megaphone, RefreshCw, AlertCircle, ChevronLeft, ChevronRight } from 'lucide-vue-next' import { useFeed } from '../composables/useFeed' import { useProfiles } from '../composables/useProfiles' import { useReactions } from '../composables/useReactions' @@ -99,10 +99,66 @@ const { getDisplayName, fetchProfiles } = useProfiles() const { getEventReactions, subscribeToReactions, toggleLike } = useReactions() // Use scheduled events service -const { getTodaysEvents, getCompletion, toggleComplete, allCompletions } = useScheduledEvents() +const { getEventsForSpecificDate, getCompletion, toggleComplete, allCompletions } = useScheduledEvents() -// Get today's scheduled events (reactive) -const todaysScheduledEvents = computed(() => getTodaysEvents()) +// Selected date for viewing events (defaults to today) +const selectedDate = ref(new Date().toISOString().split('T')[0]) + +// Get scheduled events for the selected date (reactive) +const scheduledEventsForDate = computed(() => getEventsForSpecificDate(selectedDate.value)) + +// Navigate to previous day +function goToPreviousDay() { + const date = new Date(selectedDate.value) + date.setDate(date.getDate() - 1) + selectedDate.value = date.toISOString().split('T')[0] +} + +// Navigate to next day +function goToNextDay() { + const date = new Date(selectedDate.value) + date.setDate(date.getDate() + 1) + selectedDate.value = date.toISOString().split('T')[0] +} + +// Go back to today +function goToToday() { + selectedDate.value = new Date().toISOString().split('T')[0] +} + +// Check if selected date is today +const isToday = computed(() => { + const today = new Date().toISOString().split('T')[0] + return selectedDate.value === today +}) + +// Format date for display +const dateDisplayText = computed(() => { + const today = new Date().toISOString().split('T')[0] + const yesterday = new Date() + yesterday.setDate(yesterday.getDate() - 1) + const yesterdayStr = yesterday.toISOString().split('T')[0] + const tomorrow = new Date() + tomorrow.setDate(tomorrow.getDate() + 1) + const tomorrowStr = tomorrow.toISOString().split('T')[0] + + if (selectedDate.value === today) { + return "Today's Events" + } else if (selectedDate.value === yesterdayStr) { + return "Yesterday's Events" + } else if (selectedDate.value === tomorrowStr) { + return "Tomorrow's Events" + } else { + // Format as "Events for Mon, Jan 15" + const date = new Date(selectedDate.value + 'T00:00:00') + const formatted = date.toLocaleDateString('en-US', { + weekday: 'short', + month: 'short', + day: 'numeric' + }) + return `Events for ${formatted}` + } +}) // Watch for new posts and fetch their profiles and reactions watch(notes, async (newNotes) => { @@ -119,12 +175,12 @@ watch(notes, async (newNotes) => { }, { immediate: true }) // Watch for scheduled events and fetch profiles for event authors and completers -watch(todaysScheduledEvents, async (events) => { +watch(scheduledEventsForDate, async (events) => { if (events.length > 0) { const pubkeys = new Set() // Add event authors - events.forEach(event => { + events.forEach((event: ScheduledEvent) => { pubkeys.add(event.pubkey) // Add completer pubkey if event is completed @@ -421,14 +477,50 @@ function cancelDelete() {
- -
-

- 📅 Today's Events -

-
+ +
+
+ + + + +
+

+ 📅 {{ dateDisplayText }} +

+ +
+ + + +
+ + +
+
+ No events scheduled for this day +
-

+

💬 Posts

{ + if (!scheduledEventService) return [] + return scheduledEventService.getEventsForSpecificDate(date, currentUserPubkey.value) + } + /** * Get today's scheduled events (filtered by current user participation) */ @@ -141,6 +150,7 @@ export function useScheduledEvents() { // Methods getScheduledEvents, getEventsForDate, + getEventsForSpecificDate, getTodaysEvents, getCompletion, isCompleted, diff --git a/src/modules/nostr-feed/services/ScheduledEventService.ts b/src/modules/nostr-feed/services/ScheduledEventService.ts index 09faee6..21af01f 100644 --- a/src/modules/nostr-feed/services/ScheduledEventService.ts +++ b/src/modules/nostr-feed/services/ScheduledEventService.ts @@ -251,22 +251,24 @@ export class ScheduledEventService extends BaseService { } /** - * Get events for today, optionally filtered by user participation + * Get events for a specific date, optionally filtered by user participation + * @param date - ISO date string (YYYY-MM-DD). Defaults to today. + * @param userPubkey - Optional user pubkey to filter by participation */ - getTodaysEvents(userPubkey?: string): ScheduledEvent[] { - const today = new Date().toISOString().split('T')[0] + getEventsForSpecificDate(date?: string, userPubkey?: string): ScheduledEvent[] { + const targetDate = date || new Date().toISOString().split('T')[0] - // Get one-time events for today (exclude recurring events to avoid duplicates) - const oneTimeEvents = this.getEventsForDate(today).filter(event => !event.recurrence) + // Get one-time events for the date (exclude recurring events to avoid duplicates) + const oneTimeEvents = this.getEventsForDate(targetDate).filter(event => !event.recurrence) - // Get all events and check for recurring events that occur today + // Get all events and check for recurring events that occur on this date const allEvents = this.getScheduledEvents() - const recurringEventsToday = allEvents.filter(event => - event.recurrence && this.doesRecurringEventOccurOnDate(event, today) + const recurringEventsOnDate = allEvents.filter(event => + event.recurrence && this.doesRecurringEventOccurOnDate(event, targetDate) ) // Combine one-time and recurring events - let events = [...oneTimeEvents, ...recurringEventsToday] + let events = [...oneTimeEvents, ...recurringEventsOnDate] // Filter events based on participation (if user pubkey provided) if (userPubkey) { @@ -288,6 +290,13 @@ export class ScheduledEventService extends BaseService { return events } + /** + * Get events for today, optionally filtered by user participation + */ + getTodaysEvents(userPubkey?: string): ScheduledEvent[] { + return this.getEventsForSpecificDate(undefined, userPubkey) + } + /** * Get completion status for an event (optionally for a specific occurrence) */