import { computed, ref } from 'vue'; import { defineStore } from 'pinia'; import { useAuthStore } from '@/features/auth/stores/authStore.js'; import { useWorkspaceStore } from '@/features/workspaces/stores/workspaceStore.js'; import { useClient } from '@/plugins/api.js'; export const useCalendarIntegrationsStore = defineStore('calendar-integrations', () => { const authStore = useAuthStore(); const workspaceStore = useWorkspaceStore(); const client = useClient(); const sources = ref([]); const events = ref([]); const catalogEntries = ref([]); const hiddenSourceIds = ref(new Set()); const isLoadingSources = ref(false); const isLoadingEvents = ref(false); const isLoadingCatalog = ref(false); const isCreatingSource = ref(false); const error = ref(null); const visibleSourceIds = computed(() => new Set(sources.value .filter(source => source.isEnabled && !hiddenSourceIds.value.has(source.id)) .map(source => source.id)) ); const visibleEvents = computed(() => events.value.filter(event => visibleSourceIds.value.has(event.calendarSourceId)) ); function sourceById(sourceId) { return sources.value.find(source => source.id === sourceId) ?? null; } async function fetchSources(workspaceId = workspaceStore.activeWorkspaceId) { if (!authStore.isAuthenticated) { sources.value = []; error.value = null; return; } isLoadingSources.value = true; error.value = null; try { const response = await client.get('/api/calendar-integrations/sources', { params: { workspaceId: workspaceId ?? undefined, }, }); sources.value = response.data ?? []; } catch (fetchError) { console.error('Failed to fetch calendar sources:', fetchError); sources.value = []; error.value = 'Failed to load calendar sources.'; } finally { isLoadingSources.value = false; } } async function fetchEvents({ workspaceId = workspaceStore.activeWorkspaceId, startDate, endDate } = {}) { if (!authStore.isAuthenticated) { events.value = []; error.value = null; return; } isLoadingEvents.value = true; try { const response = await client.get('/api/calendar-integrations/events', { params: { workspaceId: workspaceId ?? undefined, startDate, endDate, }, }); events.value = response.data ?? []; } catch (fetchError) { console.error('Failed to fetch calendar events:', fetchError); events.value = []; error.value = 'Failed to load calendar events.'; } finally { isLoadingEvents.value = false; } } async function searchCatalog(filters = {}) { if (!authStore.isAuthenticated) { catalogEntries.value = []; return; } isLoadingCatalog.value = true; try { const response = await client.get('/api/calendar-integrations/catalog', { params: filters, }); catalogEntries.value = response.data ?? []; } catch (fetchError) { console.error('Failed to search calendar catalog:', fetchError); catalogEntries.value = []; error.value = 'Failed to load calendar catalog.'; } finally { isLoadingCatalog.value = false; } } async function createSource(payload) { isCreatingSource.value = true; error.value = null; try { const response = await client.post('/api/calendar-integrations/sources', payload); if (response.data) { sources.value = [...sources.value, response.data] .sort((left, right) => left.displayTitle.localeCompare(right.displayTitle)); } return response.data; } catch (createError) { console.error('Failed to create calendar source:', createError); error.value = 'Failed to add calendar source.'; throw createError; } finally { isCreatingSource.value = false; } } async function updateSource(sourceId, payload) { if (!sourceId) { return null; } error.value = null; try { const response = await client.put(`/api/calendar-integrations/sources/${sourceId}`, payload); const updatedSource = response.data; if (updatedSource) { sources.value = sources.value.map(source => source.id === updatedSource.id ? updatedSource : source ); } return updatedSource; } catch (updateError) { console.error('Failed to update calendar source:', updateError); error.value = 'Failed to update calendar source.'; throw updateError; } } async function refreshSource(sourceId) { if (!sourceId) { return null; } try { const response = await client.post(`/api/calendar-integrations/sources/${sourceId}/refresh`); const refreshedSource = response.data; if (refreshedSource) { sources.value = sources.value.map(source => source.id === refreshedSource.id ? refreshedSource : source ); } return refreshedSource; } catch (refreshError) { console.error('Failed to refresh calendar source:', refreshError); error.value = 'Failed to refresh calendar source.'; throw refreshError; } } function toggleSourceVisibility(sourceId) { const nextHiddenIds = new Set(hiddenSourceIds.value); if (nextHiddenIds.has(sourceId)) { nextHiddenIds.delete(sourceId); } else { nextHiddenIds.add(sourceId); } hiddenSourceIds.value = nextHiddenIds; } return { sources, events, catalogEntries, hiddenSourceIds, visibleSourceIds, visibleEvents, isLoadingSources, isLoadingEvents, isLoadingCatalog, isCreatingSource, error, sourceById, fetchSources, fetchEvents, searchCatalog, createSource, updateSource, refreshSource, toggleSourceVisibility, }; });