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.
165 lines
5.3 KiB
TypeScript
165 lines
5.3 KiB
TypeScript
import { computed } from 'vue'
|
|
import { injectService, SERVICE_TOKENS } from '@/core/di-container'
|
|
import type { ScheduledEventService, ScheduledEvent, EventCompletion } from '../services/ScheduledEventService'
|
|
import type { AuthService } from '@/modules/base/auth/auth-service'
|
|
import { useToast } from '@/core/composables/useToast'
|
|
|
|
/**
|
|
* Composable for managing scheduled events in the feed
|
|
*/
|
|
export function useScheduledEvents() {
|
|
const scheduledEventService = injectService<ScheduledEventService>(SERVICE_TOKENS.SCHEDULED_EVENT_SERVICE)
|
|
const authService = injectService<AuthService>(SERVICE_TOKENS.AUTH_SERVICE)
|
|
const toast = useToast()
|
|
|
|
// Get current user's pubkey
|
|
const currentUserPubkey = computed(() => authService?.user.value?.pubkey)
|
|
|
|
/**
|
|
* Get all scheduled events
|
|
*/
|
|
const getScheduledEvents = (): ScheduledEvent[] => {
|
|
if (!scheduledEventService) return []
|
|
return scheduledEventService.getScheduledEvents()
|
|
}
|
|
|
|
/**
|
|
* Get events for a specific date (YYYY-MM-DD)
|
|
*/
|
|
const getEventsForDate = (date: string): ScheduledEvent[] => {
|
|
if (!scheduledEventService) return []
|
|
return scheduledEventService.getEventsForDate(date)
|
|
}
|
|
|
|
/**
|
|
* Get events for a specific date (filtered by current user participation)
|
|
* @param date - ISO date string (YYYY-MM-DD). Defaults to today.
|
|
*/
|
|
const getEventsForSpecificDate = (date?: string): ScheduledEvent[] => {
|
|
if (!scheduledEventService) return []
|
|
return scheduledEventService.getEventsForSpecificDate(date, currentUserPubkey.value)
|
|
}
|
|
|
|
/**
|
|
* Get today's scheduled events (filtered by current user participation)
|
|
*/
|
|
const getTodaysEvents = (): ScheduledEvent[] => {
|
|
if (!scheduledEventService) return []
|
|
return scheduledEventService.getTodaysEvents(currentUserPubkey.value)
|
|
}
|
|
|
|
/**
|
|
* Get completion status for an event
|
|
*/
|
|
const getCompletion = (eventAddress: string): EventCompletion | undefined => {
|
|
if (!scheduledEventService) return undefined
|
|
return scheduledEventService.getCompletion(eventAddress)
|
|
}
|
|
|
|
/**
|
|
* Check if an event is completed
|
|
*/
|
|
const isCompleted = (eventAddress: string): boolean => {
|
|
if (!scheduledEventService) return false
|
|
return scheduledEventService.isCompleted(eventAddress)
|
|
}
|
|
|
|
/**
|
|
* Toggle completion status of an event (optionally for a specific occurrence)
|
|
*/
|
|
const toggleComplete = async (event: ScheduledEvent, occurrence?: string, notes: string = ''): Promise<void> => {
|
|
console.log('🔧 useScheduledEvents: toggleComplete called for event:', event.title, 'occurrence:', occurrence)
|
|
|
|
if (!scheduledEventService) {
|
|
console.error('❌ useScheduledEvents: Scheduled event service not available')
|
|
toast.error('Scheduled event service not available')
|
|
return
|
|
}
|
|
|
|
try {
|
|
const eventAddress = `31922:${event.pubkey}:${event.dTag}`
|
|
const currentlyCompleted = scheduledEventService.isCompleted(eventAddress, occurrence)
|
|
console.log('📊 useScheduledEvents: Current completion status:', currentlyCompleted)
|
|
|
|
if (currentlyCompleted) {
|
|
console.log('⬇️ useScheduledEvents: Marking as incomplete...')
|
|
await scheduledEventService.uncompleteEvent(event, occurrence)
|
|
toast.success('Event marked as incomplete')
|
|
} else {
|
|
console.log('⬆️ useScheduledEvents: Marking as complete...')
|
|
await scheduledEventService.completeEvent(event, notes, occurrence)
|
|
toast.success('Event completed!')
|
|
}
|
|
} catch (error) {
|
|
const message = error instanceof Error ? error.message : 'Failed to toggle completion'
|
|
|
|
if (message.includes('authenticated')) {
|
|
toast.error('Please sign in to complete events')
|
|
} else if (message.includes('Not connected')) {
|
|
toast.error('Not connected to relays')
|
|
} else {
|
|
toast.error(message)
|
|
}
|
|
|
|
console.error('❌ useScheduledEvents: Failed to toggle completion:', error)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Complete an event with optional notes
|
|
*/
|
|
const completeEvent = async (event: ScheduledEvent, notes: string = ''): Promise<void> => {
|
|
if (!scheduledEventService) {
|
|
toast.error('Scheduled event service not available')
|
|
return
|
|
}
|
|
|
|
try {
|
|
await scheduledEventService.completeEvent(event, notes)
|
|
toast.success('Event completed!')
|
|
} catch (error) {
|
|
const message = error instanceof Error ? error.message : 'Failed to complete event'
|
|
toast.error(message)
|
|
console.error('Failed to complete event:', error)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get loading state
|
|
*/
|
|
const isLoading = computed(() => {
|
|
return scheduledEventService?.isLoading ?? false
|
|
})
|
|
|
|
/**
|
|
* Get all scheduled events (reactive)
|
|
*/
|
|
const allScheduledEvents = computed(() => {
|
|
return scheduledEventService?.scheduledEvents ?? new Map()
|
|
})
|
|
|
|
/**
|
|
* Get all completions (reactive) - returns array for better reactivity
|
|
*/
|
|
const allCompletions = computed(() => {
|
|
if (!scheduledEventService?.completions) return []
|
|
return Array.from(scheduledEventService.completions.values())
|
|
})
|
|
|
|
return {
|
|
// Methods
|
|
getScheduledEvents,
|
|
getEventsForDate,
|
|
getEventsForSpecificDate,
|
|
getTodaysEvents,
|
|
getCompletion,
|
|
isCompleted,
|
|
toggleComplete,
|
|
completeEvent,
|
|
|
|
// State
|
|
isLoading,
|
|
allScheduledEvents,
|
|
allCompletions
|
|
}
|
|
}
|