Files
cannamanage/cannamanage-frontend/src/services/stock.ts
T
Patrick Plate f42c166329 feat(sprint-5): Phase 2 — React Query API client layer
- @tanstack/react-query with QueryClientProvider in providers/index.tsx
- Typed api-client.ts fetch wrapper with ApiError class + apiDownload
- Service modules: members, distributions, stock, reports, dashboard, portal, staff
- Offline banner component (onlineManager subscription)
- API error boundary with retry button
- Loading skeleton components (card, table, chart, form, dashboard)
- i18n for error/loading states (de/en)
2026-06-12 19:59:41 +02:00

96 lines
2.3 KiB
TypeScript

import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"
import type { Batch, BatchSummary, Strain } from "@/types/api"
import { apiClient } from "@/lib/api-client"
// --- Types ---
export interface BatchesPage {
content: Batch[]
totalElements: number
totalPages: number
number: number
size: number
}
export interface CreateBatchRequest {
strainName: string
thcPercent: number
cbdPercent: number
totalGrams: number
supplier: string
harvestDate: string
notes?: string
}
// --- Query Hooks ---
export function useBatchesQuery(params?: {
page?: number
size?: number
status?: string
}) {
return useQuery({
queryKey: ["batches", params],
queryFn: () =>
apiClient<BatchesPage>("/batches", {
params: {
page: params?.page,
size: params?.size ?? 20,
status: params?.status || undefined,
},
}),
})
}
export function useBatchQuery(id: string) {
return useQuery({
queryKey: ["batches", id],
queryFn: () => apiClient<Batch>(`/batches/${id}`),
enabled: !!id,
})
}
export function useStrainsQuery() {
return useQuery({
queryKey: ["strains"],
queryFn: () => apiClient<Strain[]>("/strains"),
staleTime: 5 * 60 * 1000, // strains rarely change — 5 min stale
})
}
export function useStockSummaryQuery() {
return useQuery({
queryKey: ["batches", "summary"],
queryFn: () => apiClient<BatchSummary[]>("/batches/summary"),
})
}
// --- Mutation Hooks ---
export function useCreateBatchMutation() {
const queryClient = useQueryClient()
return useMutation({
mutationFn: (data: CreateBatchRequest) =>
apiClient<Batch>("/batches", { method: "POST", body: data }),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["batches"] })
queryClient.invalidateQueries({ queryKey: ["dashboard"] })
},
})
}
export function useRecallBatchMutation() {
const queryClient = useQueryClient()
return useMutation({
mutationFn: (id: string) =>
apiClient<Batch>(`/batches/${id}/recall`, { method: "POST" }),
onSuccess: (_data, id) => {
queryClient.invalidateQueries({ queryKey: ["batches"] })
queryClient.invalidateQueries({ queryKey: ["batches", id] })
queryClient.invalidateQueries({ queryKey: ["dashboard"] })
},
})
}