diff options
Diffstat (limited to 'packages/auditor-backoffice-ui/src/hooks/product.ts')
-rw-r--r-- | packages/auditor-backoffice-ui/src/hooks/product.ts | 177 |
1 files changed, 177 insertions, 0 deletions
diff --git a/packages/auditor-backoffice-ui/src/hooks/product.ts b/packages/auditor-backoffice-ui/src/hooks/product.ts new file mode 100644 index 000000000..b8f55cb77 --- /dev/null +++ b/packages/auditor-backoffice-ui/src/hooks/product.ts @@ -0,0 +1,177 @@ +/* + This file is part of GNU Taler + (C) 2021-2023 Taler Systems S.A. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +import { + HttpResponse, + HttpResponseOk, + RequestError, +} from "@gnu-taler/web-util/browser"; +import { AuditorBackend, MerchantBackend, WithId } from "../declaration.js"; +import { useBackendInstanceRequest, useMatchMutate } from "./backend.js"; + +// FIX default import https://github.com/microsoft/TypeScript/issues/49189 +import _useSWR, { SWRHook, useSWRConfig } from "swr"; +const useSWR = _useSWR as unknown as SWRHook; + +export interface ProductAPI { + getProduct: ( + id: string, + ) => Promise<void>; + createProduct: ( + data: MerchantBackend.Products.ProductAddDetail, + ) => Promise<void>; + updateProduct: ( + id: string, + data: MerchantBackend.Products.ProductPatchDetail, + ) => Promise<void>; + deleteProduct: (id: string) => Promise<void>; + lockProduct: ( + id: string, + data: MerchantBackend.Products.LockRequest, + ) => Promise<void>; +} + +export function useProductAPI(): ProductAPI { + const mutateAll = useMatchMutate(); + const { mutate } = useSWRConfig(); + + const { request } = useBackendInstanceRequest(); + + const createProduct = async ( + data: MerchantBackend.Products.ProductAddDetail, + ): Promise<void> => { + const res = await request(`/private/products`, { + method: "POST", + data, + }); + + return await mutateAll(/.*\/private\/products.*/); + }; + + const updateProduct = async ( + productId: string, + data: MerchantBackend.Products.ProductPatchDetail, + ): Promise<void> => { + const r = await request(`/private/products/${productId}`, { + method: "PATCH", + data, + }); + + return await mutateAll(/.*\/private\/products.*/); + }; + + const deleteProduct = async (productId: string): Promise<void> => { + await request(`/private/products/${productId}`, { + method: "DELETE", + }); + await mutate([`/private/products`]); + }; + + const lockProduct = async ( + productId: string, + data: MerchantBackend.Products.LockRequest, + ): Promise<void> => { + await request(`/private/products/${productId}/lock`, { + method: "POST", + data, + }); + + return await mutateAll(/.*"\/private\/products.*/); + }; + + const getProduct = async ( + productId: string, + ): Promise<void> => { + await request(`/private/products/${productId}`, { + method: "GET", + }); + + return + }; + + return { createProduct, updateProduct, deleteProduct, lockProduct, getProduct }; +} + +export function useInstanceProducts(): HttpResponse< + (MerchantBackend.Products.ProductDetail & WithId)[], + MerchantBackend.ErrorDetail +> { + const { fetcher, multiFetcher } = useBackendInstanceRequest(); + + const { data: list, error: listError } = useSWR< + HttpResponseOk<MerchantBackend.Products.InventorySummaryResponse>, + RequestError<MerchantBackend.ErrorDetail> + >([`/private/products`], fetcher, { + refreshInterval: 0, + refreshWhenHidden: false, + revalidateOnFocus: false, + revalidateOnReconnect: false, + refreshWhenOffline: false, + }); + + const paths = (list?.data.products || []).map( + (p) => `/deposit-confirmation/${p.serial_id}`, + ); + const { data: products, error: productError } = useSWR< + HttpResponseOk<AuditorBackend.DepositConfirmation.DepositConfirmationDetail>[], + RequestError<AuditorBackend.ErrorDetail> + >([paths], multiFetcher, { + refreshInterval: 0, + refreshWhenHidden: false, + revalidateOnFocus: false, + revalidateOnReconnect: false, + refreshWhenOffline: false, + }); + + if (listError) return listError.cause; + if (productError) return productError.cause; + + if (products) { + const dataWithId = products.map((d) => { + //take the id from the queried url + return { + ...d.data, + id: d.info?.url.replace(/.*\/private\/products\//, "") || "", + }; + }); + return { ok: true, data: dataWithId }; + } + return { loading: true }; +} + +export function useProductDetails( + productId: string, +): HttpResponse< + MerchantBackend.Products.ProductDetail, + MerchantBackend.ErrorDetail +> { + const { fetcher } = useBackendInstanceRequest(); + + const { data, error, isValidating } = useSWR< + HttpResponseOk<MerchantBackend.Products.ProductDetail>, + RequestError<MerchantBackend.ErrorDetail> + >([`/private/products/${productId}`], fetcher, { + refreshInterval: 0, + refreshWhenHidden: false, + revalidateOnFocus: false, + revalidateOnReconnect: false, + refreshWhenOffline: false, + }); + + if (isValidating) return { loading: true, data: data?.data }; + if (data) return data; + if (error) return error.cause; + return { loading: true }; +} |