web-app/src/modules/nostr-feed/composables/useScheduledEvents.ts
padreug 5d6f702859 Enables marking scheduled events as complete
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.
2025-10-30 16:19:11 +01:00

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
}
}