import { useOrganizationApi } from '~/composables/organization/useOrganizationApi' import type { LegalRole } from '~/server/utils/permissions' import type { ActiveOrganization, CustomInvitation, Invitation, ListMembersOptions, ListMembersQuery, ListMembersResponse, Member, Organization } from '~/types/auth' export const useOrganizationStore = defineStore('Organization', () => { const activeOrganization = ref(null) const organizations = ref([]) const invitations = ref([]) const activeOrganizationMembers = ref([]) const organizationApi = useOrganizationApi() const toast = useToast() async function createOrganization(name: string, slug: string, logo?: string) { const { data: slugCheck, error: slugError } = await organizationApi.checkSlugAvailability(slug) if (slugError) { toast.add({ title: 'Error checking slug availability', description: slugError.message, color: 'error' }) console.error('Error checking slug availability:', slugError) return Promise.reject(slugError) } if (!slugCheck?.status) { toast.add({ title: 'Slug already taken', description: 'Please choose a different slug', color: 'error' }) return Promise.reject() } const { data: createdOrganization, error } = await organizationApi.createOrganization(name, slug, logo) if (error) { toast.add({ title: 'Error creating organization', color: 'error' }) console.error('Error creating organization:', error) return Promise.reject(error) } if (createdOrganization) { organizations.value.push(createdOrganization) toast.add({ title: 'Organization created successfully', color: 'success' }) if (createdOrganization.id) { await setActiveOrganization(createdOrganization.id) } return createdOrganization } } async function deleteOrganization(organizationId?: string) { const idToDelete = organizationId ?? activeOrganization.value?.id if (!idToDelete) { const error = new Error('No organization is selected for deletion') toast.add({ title: 'Error deleting organization', color: 'error' }) console.error('Error deleting organization:', error) return Promise.reject(error) } const { error } = await organizationApi.deleteOrganization(idToDelete) if (error) { toast.add({ title: 'Error deleting organization', color: 'error' }) console.error('Error deleting organization:', error) return Promise.reject(error) } organizations.value = organizations.value.filter((org) => org.id !== organizationId) toast.add({ title: 'Organization deleted successfully', color: 'success' }) } async function getInvitation(invitationId: string): Promise { const { data: invitation, error } = await organizationApi.getInvitation(invitationId) if (error) { toast.add({ title: error.message, color: 'error' }) console.error('Error getting invitation:', error) return Promise.reject(error) } return invitation } async function loadInvitations(organizationId?: string) { const { data: loadedInvitations, error } = await organizationApi.listInvitations(organizationId) if (error) { toast.add({ title: 'Error loading invitations', color: 'error' }) console.error('Error loading invitations:', error) return Promise.reject(error) } if (loadedInvitations) { invitations.value = loadedInvitations } } async function inviteMember(email: string, role: LegalRole) { const { error } = await organizationApi.inviteMember(email, role) if (error) { toast.add({ title: 'Error inviting member', color: 'error' }) console.error('Error inviting member:', error) return Promise.reject(error) } await loadInvitations() toast.add({ title: 'Member invited successfully', color: 'success' }) } async function removeMember(memberId: string) { const { error } = await organizationApi.removeMember(memberId) if (error) { toast.add({ title: 'Error removing member', color: 'error' }) console.error('Error removing member:', error) return Promise.reject(error) } activeOrganizationMembers.value = activeOrganizationMembers.value.filter((member: Member) => member.id !== memberId) toast.add({ title: 'Member removed successfully', color: 'success' }) } async function acceptInvitation(invitationId: string) { const { error } = await organizationApi.acceptInvitation(invitationId) if (error) { toast.add({ title: 'Error accepting invitation', color: 'error' }) console.error('Error accepting invitation:', error) return Promise.reject(error) } await navigateTo('/') await syncUserRoleToBackend() } async function syncUserRoleToBackend() { const { updateUser } = useUser() const { user } = useAuth() if (!user.value?.id) { const error = new Error('No user ID available for role sync') console.warn('No user ID available for role sync') return Promise.reject(error) } // Call updateUser without userDto to trigger JWT-based sync const updatedUser = await updateUser(user.value.id) if (updatedUser) { console.log('Successfully synced user role to backend from JWT') } } async function cancelSentInvitation(invitationId: string) { const { error } = await organizationApi.cancelSentInvitation(invitationId) if (error) { toast.add({ title: 'Error rejecting invitation', color: 'error' }) console.error('Error rejecting invitation:', error) return Promise.reject(error) } invitations.value = invitations.value.filter((invitation) => invitation.id !== invitationId) } async function rejectInvitation(invitationId: string) { const { error } = await organizationApi.rejectInvitation(invitationId) if (error) { toast.add({ title: 'Error rejecting invitation', color: 'error' }) console.error('Error rejecting invitation:', error) return Promise.reject(error) } invitations.value = invitations.value.filter((invitation) => invitation.id !== invitationId) } async function loadOrganizations() { const { data: loadedOrganizations, error } = await organizationApi.loadOrganizations() if (error) { toast.add({ title: 'Error loading organizations', color: 'error' }) console.error('Error loading organizations:', error) return Promise.reject(error) } if (loadedOrganizations) { organizations.value = loadedOrganizations } } async function setActiveOrganization(organizationId: string) { const { data: activeOrganizationToSet, error } = await organizationApi.setActiveOrganization(organizationId) if (error) { toast.add({ title: 'Error setting active organizations', color: 'error' }) console.error('Error setting active organizations:', error) return Promise.reject(error) } activeOrganization.value = activeOrganizationToSet const { data: invitationsToSet, error: invitationsError } = await organizationApi.listInvitations( activeOrganizationToSet?.id ) if (invitationsError) { console.error('Error loading invitations for active organization:', invitationsError) } else { invitations.value = invitationsToSet ?? [] } await loadMembers() } async function loadMembers(options?: Omit, 'organizationId'>) { if (!activeOrganization.value?.id) { const error = new Error('No active organization to load members for') console.error('Error getting members: No active organization') return Promise.reject(error) } const memberOptions: ListMembersOptions = { query: { organizationId: activeOrganization.value.id, ...options } } const { data: response, error } = await organizationApi.listMembers(memberOptions) if (error) { toast.add({ title: 'Error getting members', color: 'error' }) console.error('Error getting members:', error) return Promise.reject(error) } activeOrganizationMembers.value = response?.members ?? [] } return { activeOrganization, activeOrganizationMembers, organizations, createOrganization, deleteOrganization, invitations, getInvitation, inviteMember, removeMember, acceptInvitation, rejectInvitation, cancelSentInvitation, loadOrganizations, setActiveOrganization } })