Implements a feature to mark scheduled events as complete, replacing the checkbox with a button for improved UX. This commit enhances the Scheduled Events functionality by allowing users to mark events as complete. It also includes: - Replaces the checkbox with a "Mark Complete" button for better usability. - Adds logging for debugging purposes during event completion toggling. - Routes completion events (kind 31925) to the ScheduledEventService. - Optimistically updates the local state after publishing completion events.
149 lines
4.3 KiB
TypeScript
149 lines
4.3 KiB
TypeScript
import { computed } from 'vue'
|
|
import { injectService, SERVICE_TOKENS } from '@/core/di-container'
|
|
import type { ScheduledEventService, ScheduledEvent, EventCompletion } from '../services/ScheduledEventService'
|
|
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 toast = useToast()
|
|
|
|
/**
|
|
* 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 today's scheduled events
|
|
*/
|
|
const getTodaysEvents = (): ScheduledEvent[] => {
|
|
if (!scheduledEventService) return []
|
|
return scheduledEventService.getTodaysEvents()
|
|
}
|
|
|
|
/**
|
|
* 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
|
|
*/
|
|
const toggleComplete = async (event: ScheduledEvent, notes: string = ''): Promise<void> => {
|
|
console.log('🔧 useScheduledEvents: toggleComplete called for event:', event.title)
|
|
|
|
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)
|
|
console.log('📊 useScheduledEvents: Current completion status:', currentlyCompleted)
|
|
|
|
if (currentlyCompleted) {
|
|
console.log('⬇️ useScheduledEvents: Marking as incomplete...')
|
|
await scheduledEventService.uncompleteEvent(event)
|
|
toast.success('Event marked as incomplete')
|
|
} else {
|
|
console.log('⬆️ useScheduledEvents: Marking as complete...')
|
|
await scheduledEventService.completeEvent(event, notes)
|
|
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)
|
|
*/
|
|
const allCompletions = computed(() => {
|
|
return scheduledEventService?.completions ?? new Map()
|
|
})
|
|
|
|
return {
|
|
// Methods
|
|
getScheduledEvents,
|
|
getEventsForDate,
|
|
getTodaysEvents,
|
|
getCompletion,
|
|
isCompleted,
|
|
toggleComplete,
|
|
completeEvent,
|
|
|
|
// State
|
|
isLoading,
|
|
allScheduledEvents,
|
|
allCompletions
|
|
}
|
|
}
|