GET /portal/my-shifts aggregates shift assignments across all events the logged-in user is linked to via Person records. Groups by event then date, showing only active assignments (approved/pending_approval) for approved/pending persons. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
87 lines
2.5 KiB
TypeScript
87 lines
2.5 KiB
TypeScript
import { useQuery, useMutation, useQueryClient } from '@tanstack/vue-query'
|
|
import type { Ref } from 'vue'
|
|
import { apiClient } from '@/lib/axios'
|
|
import type { AllMyShiftsEventGroup, AvailableShiftsDay, MyShiftsResponse } from '@/types/portal-shift'
|
|
|
|
interface ApiResponse<T> {
|
|
data: T
|
|
}
|
|
|
|
export function useAllMyShifts() {
|
|
return useQuery({
|
|
queryKey: ['portal-all-my-shifts'],
|
|
queryFn: async () => {
|
|
const { data } = await apiClient.get<ApiResponse<AllMyShiftsEventGroup[]>>(
|
|
'/portal/my-shifts',
|
|
)
|
|
|
|
return data.data
|
|
},
|
|
})
|
|
}
|
|
|
|
export function useAvailableShifts(eventId: Ref<string | null>) {
|
|
return useQuery({
|
|
queryKey: ['available-shifts', eventId],
|
|
queryFn: async () => {
|
|
const { data } = await apiClient.get<ApiResponse<AvailableShiftsDay[]>>(
|
|
`/portal/events/${eventId.value}/available-shifts`,
|
|
)
|
|
|
|
return data.data
|
|
},
|
|
enabled: () => !!eventId.value,
|
|
})
|
|
}
|
|
|
|
export function useMyShifts(eventId: Ref<string | null>) {
|
|
return useQuery({
|
|
queryKey: ['my-shifts', eventId],
|
|
queryFn: async () => {
|
|
const { data } = await apiClient.get<ApiResponse<MyShiftsResponse>>(
|
|
`/portal/events/${eventId.value}/my-shifts`,
|
|
)
|
|
|
|
return data.data
|
|
},
|
|
enabled: () => !!eventId.value,
|
|
})
|
|
}
|
|
|
|
export function useClaimShift(eventId: Ref<string | null>) {
|
|
const queryClient = useQueryClient()
|
|
|
|
return useMutation({
|
|
mutationFn: async (shiftId: string) => {
|
|
const { data } = await apiClient.post<ApiResponse<{ assignment_id: string; status: string; message: string }>>(
|
|
`/portal/events/${eventId.value}/shifts/${shiftId}/claim`,
|
|
)
|
|
|
|
return data.data
|
|
},
|
|
onSuccess: () => {
|
|
queryClient.invalidateQueries({ queryKey: ['available-shifts', eventId] })
|
|
queryClient.invalidateQueries({ queryKey: ['my-shifts', eventId] })
|
|
},
|
|
})
|
|
}
|
|
|
|
export function useCancelAssignment(eventId: Ref<string | null>) {
|
|
const queryClient = useQueryClient()
|
|
|
|
return useMutation({
|
|
mutationFn: async ({ assignmentId, reason }: { assignmentId: string; reason?: string }) => {
|
|
const { data } = await apiClient.post<ApiResponse<{ message: string }>>(
|
|
`/portal/events/${eventId.value}/assignments/${assignmentId}/cancel`,
|
|
reason ? { reason } : {},
|
|
)
|
|
|
|
return data.data
|
|
},
|
|
onSuccess: () => {
|
|
queryClient.invalidateQueries({ queryKey: ['available-shifts', eventId] })
|
|
queryClient.invalidateQueries({ queryKey: ['my-shifts', eventId] })
|
|
},
|
|
})
|
|
}
|