diff options
Diffstat (limited to 'packages/merchant-backoffice-ui/src/hooks/product.ts')
-rw-r--r-- | packages/merchant-backoffice-ui/src/hooks/product.ts | 103 |
1 files changed, 103 insertions, 0 deletions
diff --git a/packages/merchant-backoffice-ui/src/hooks/product.ts b/packages/merchant-backoffice-ui/src/hooks/product.ts new file mode 100644 index 000000000..defda5552 --- /dev/null +++ b/packages/merchant-backoffice-ui/src/hooks/product.ts @@ -0,0 +1,103 @@ +/* + This file is part of GNU Taler + (C) 2021-2024 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/> + */ + +// FIX default import https://github.com/microsoft/TypeScript/issues/49189 +import { AccessToken, OperationOk, TalerHttpError, TalerMerchantApi, TalerMerchantManagementErrorsByMethod, TalerMerchantManagementResultByMethod, opFixedSuccess } from "@gnu-taler/taler-util"; +import { useState } from "preact/hooks"; +import _useSWR, { SWRHook, mutate } from "swr"; +import { useSessionContext } from "../context/session.js"; +import { PAGINATED_LIST_REQUEST } from "../utils/constants.js"; +import { buildPaginatedResult } from "./webhooks.js"; +const useSWR = _useSWR as unknown as SWRHook; + +type ProductWithId = TalerMerchantApi.ProductDetail & { id: string, serial: number }; +function notUndefined(c: ProductWithId | undefined): c is ProductWithId { + return c !== undefined; +} + +export function revalidateInstanceProducts() { + return mutate( + (key) => Array.isArray(key) && key[key.length - 1] === "listProductsWithId", + undefined, + { revalidate: true }, + ); +} +export function useInstanceProducts() { + const { state: session } = useSessionContext(); + const { lib: { instance } } = useSessionContext(); + + const [offset, setOffset] = useState<number | undefined>(); + + async function fetcher([token, bid]: [AccessToken, number]) { + const list = await instance.listProducts(token, { + limit: PAGINATED_LIST_REQUEST, + offset: bid === undefined ? undefined: String(bid), + order: "dec", + }); + if (list.type !== "ok") { + return list; + } + const all: Array<ProductWithId | undefined> = await Promise.all( + list.body.products.map(async (c) => { + const r = await instance.getProductDetails(token, c.product_id); + if (r.type === "fail") { + return undefined; + } + return { ...r.body, id: c.product_id, serial: c.product_serial }; + }), + ); + const products = all.filter(notUndefined); + + return opFixedSuccess({ products }); + } + + const { data, error } = useSWR< + OperationOk<{ products: ProductWithId[] }> | + TalerMerchantManagementErrorsByMethod<"listProducts">, + TalerHttpError + >([session.token, offset, "listProductsWithId"], fetcher); + + if (error) return error; + if (data === undefined) return undefined; + if (data.type !== "ok") return data; + + return buildPaginatedResult(data.body.products, offset, setOffset, (d) => d.serial) +} + +export function revalidateProductDetails() { + return mutate( + (key) => Array.isArray(key) && key[key.length - 1] === "getProductDetails", + undefined, + { revalidate: true }, + ); +} +export function useProductDetails(productId: string) { + const { state: session } = useSessionContext(); + const { lib: { instance } } = useSessionContext(); + + async function fetcher([pid, token]: [string, AccessToken]) { + return await instance.getProductDetails(token, pid); + } + + const { data, error } = useSWR< + TalerMerchantManagementResultByMethod<"getProductDetails">, + TalerHttpError + >([productId, session.token, "getProductDetails"], fetcher); + + if (data) return data; + if (error) return error; + return undefined; +} |