diff options
Diffstat (limited to 'packages/demobank-ui/src/hooks')
-rw-r--r-- | packages/demobank-ui/src/hooks/access.ts | 210 | ||||
-rw-r--r-- | packages/demobank-ui/src/hooks/backend.ts | 125 | ||||
-rw-r--r-- | packages/demobank-ui/src/hooks/circuit.ts | 151 |
3 files changed, 309 insertions, 177 deletions
diff --git a/packages/demobank-ui/src/hooks/access.ts b/packages/demobank-ui/src/hooks/access.ts index 4d4574dac..9c162acfe 100644 --- a/packages/demobank-ui/src/hooks/access.ts +++ b/packages/demobank-ui/src/hooks/access.ts @@ -14,91 +14,113 @@ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> */ -import useSWR from "swr"; -import { MAX_RESULT_SIZE, PAGE_SIZE } from "../utils.js"; -import { useEffect, useState } from "preact/hooks"; import { - HttpError, HttpResponse, HttpResponseOk, HttpResponsePaginated, + RequestError, } from "@gnu-taler/web-util/lib/index.browser"; -import { useAuthenticatedBackend, useMatchMutate, usePublicBackend } from "./backend.js"; +import { useEffect, useState } from "preact/hooks"; +import useSWR from "swr"; import { useBackendContext } from "../context/backend.js"; +import { MAX_RESULT_SIZE, PAGE_SIZE } from "../utils.js"; +import { + useAuthenticatedBackend, + useMatchMutate, + usePublicBackend, +} from "./backend.js"; export function useAccessAPI(): AccessAPI { const mutateAll = useMatchMutate(); const { request } = useAuthenticatedBackend(); - const { state } = useBackendContext() + const { state } = useBackendContext(); if (state.status === "loggedOut") { - throw Error("access-api can't be used when the user is not logged In") + throw Error("access-api can't be used when the user is not logged In"); } - const account = state.username + const account = state.username; const createWithdrawal = async ( data: SandboxBackend.Access.BankAccountCreateWithdrawalRequest, - ): Promise<HttpResponseOk<SandboxBackend.Access.BankAccountCreateWithdrawalResponse>> => { - const res = await request<SandboxBackend.Access.BankAccountCreateWithdrawalResponse>(`access-api/accounts/${account}/withdrawals`, { - method: "POST", - data, - contentType: "json" - }); + ): Promise< + HttpResponseOk<SandboxBackend.Access.BankAccountCreateWithdrawalResponse> + > => { + const res = + await request<SandboxBackend.Access.BankAccountCreateWithdrawalResponse>( + `access-api/accounts/${account}/withdrawals`, + { + method: "POST", + data, + contentType: "json", + }, + ); return res; }; - const abortWithdrawal = async ( - id: string, - ): Promise<HttpResponseOk<void>> => { - const res = await request<void>(`access-api/accounts/${account}/withdrawals/${id}`, { - method: "POST", - contentType: "json" - }); + const abortWithdrawal = async (id: string): Promise<HttpResponseOk<void>> => { + const res = await request<void>( + `access-api/accounts/${account}/withdrawals/${id}`, + { + method: "POST", + contentType: "json", + }, + ); await mutateAll(/.*accounts\/.*\/withdrawals\/.*/); return res; }; const confirmWithdrawal = async ( id: string, ): Promise<HttpResponseOk<void>> => { - const res = await request<void>(`access-api/accounts/${account}/withdrawals/${id}`, { - method: "POST", - contentType: "json" - }); + const res = await request<void>( + `access-api/accounts/${account}/withdrawals/${id}`, + { + method: "POST", + contentType: "json", + }, + ); await mutateAll(/.*accounts\/.*\/withdrawals\/.*/); return res; }; const createTransaction = async ( - data: SandboxBackend.Access.CreateBankAccountTransactionCreate + data: SandboxBackend.Access.CreateBankAccountTransactionCreate, ): Promise<HttpResponseOk<void>> => { - const res = await request<void>(`access-api/accounts/${account}/transactions`, { - method: "POST", - data, - contentType: "json" - }); + const res = await request<void>( + `access-api/accounts/${account}/transactions`, + { + method: "POST", + data, + contentType: "json", + }, + ); await mutateAll(/.*accounts\/.*\/transactions.*/); return res; }; - const deleteAccount = async ( - ): Promise<HttpResponseOk<void>> => { + const deleteAccount = async (): Promise<HttpResponseOk<void>> => { const res = await request<void>(`access-api/accounts/${account}`, { method: "DELETE", - contentType: "json" + contentType: "json", }); await mutateAll(/.*accounts\/.*/); return res; }; - return { abortWithdrawal, confirmWithdrawal, createWithdrawal, createTransaction, deleteAccount }; + return { + abortWithdrawal, + confirmWithdrawal, + createWithdrawal, + createTransaction, + deleteAccount, + }; } export function useTestingAPI(): TestingAPI { const mutateAll = useMatchMutate(); const { request: noAuthRequest } = usePublicBackend(); const register = async ( - data: SandboxBackend.Access.BankRegistrationRequest + data: SandboxBackend.Access.BankRegistrationRequest, ): Promise<HttpResponseOk<void>> => { const res = await noAuthRequest<void>(`access-api/testing/register`, { method: "POST", data, - contentType: "json" + contentType: "json", }); await mutateAll(/.*accounts\/.*/); return res; @@ -107,25 +129,22 @@ export function useTestingAPI(): TestingAPI { return { register }; } - export interface TestingAPI { register: ( - data: SandboxBackend.Access.BankRegistrationRequest + data: SandboxBackend.Access.BankRegistrationRequest, ) => Promise<HttpResponseOk<void>>; } export interface AccessAPI { createWithdrawal: ( data: SandboxBackend.Access.BankAccountCreateWithdrawalRequest, - ) => Promise<HttpResponseOk<SandboxBackend.Access.BankAccountCreateWithdrawalResponse>>; - abortWithdrawal: ( - wid: string, - ) => Promise<HttpResponseOk<void>>; - confirmWithdrawal: ( - wid: string - ) => Promise<HttpResponseOk<void>>; + ) => Promise< + HttpResponseOk<SandboxBackend.Access.BankAccountCreateWithdrawalResponse> + >; + abortWithdrawal: (wid: string) => Promise<HttpResponseOk<void>>; + confirmWithdrawal: (wid: string) => Promise<HttpResponseOk<void>>; createTransaction: ( - data: SandboxBackend.Access.CreateBankAccountTransactionCreate + data: SandboxBackend.Access.CreateBankAccountTransactionCreate, ) => Promise<HttpResponseOk<void>>; deleteAccount: () => Promise<HttpResponseOk<void>>; } @@ -135,13 +154,17 @@ export interface InstanceTemplateFilter { position?: string; } - -export function useAccountDetails(account: string): HttpResponse<SandboxBackend.Access.BankAccountBalanceResponse, SandboxBackend.SandboxError> { +export function useAccountDetails( + account: string, +): HttpResponse< + SandboxBackend.Access.BankAccountBalanceResponse, + SandboxBackend.SandboxError +> { const { fetcher } = useAuthenticatedBackend(); const { data, error } = useSWR< HttpResponseOk<SandboxBackend.Access.BankAccountBalanceResponse>, - HttpError<SandboxBackend.SandboxError> + RequestError<SandboxBackend.SandboxError> >([`access-api/accounts/${account}`], fetcher, { refreshInterval: 0, refreshWhenHidden: false, @@ -155,17 +178,23 @@ export function useAccountDetails(account: string): HttpResponse<SandboxBackend. }); if (data) return data; - if (error) return error; + if (error) return error.info; return { loading: true }; } // FIXME: should poll -export function useWithdrawalDetails(account: string, wid: string): HttpResponse<SandboxBackend.Access.BankAccountGetWithdrawalResponse, SandboxBackend.SandboxError> { +export function useWithdrawalDetails( + account: string, + wid: string, +): HttpResponse< + SandboxBackend.Access.BankAccountGetWithdrawalResponse, + SandboxBackend.SandboxError +> { const { fetcher } = useAuthenticatedBackend(); const { data, error } = useSWR< HttpResponseOk<SandboxBackend.Access.BankAccountGetWithdrawalResponse>, - HttpError<SandboxBackend.SandboxError> + RequestError<SandboxBackend.SandboxError> >([`access-api/accounts/${account}/withdrawals/${wid}`], fetcher, { refreshInterval: 1000, refreshWhenHidden: false, @@ -176,21 +205,26 @@ export function useWithdrawalDetails(account: string, wid: string): HttpResponse errorRetryInterval: 1, shouldRetryOnError: false, keepPreviousData: true, - }); // if (isValidating) return { loading: true, data: data?.data }; if (data) return data; - if (error) return error; + if (error) return error.info; return { loading: true }; } -export function useTransactionDetails(account: string, tid: string): HttpResponse<SandboxBackend.Access.BankAccountTransactionInfo, SandboxBackend.SandboxError> { +export function useTransactionDetails( + account: string, + tid: string, +): HttpResponse< + SandboxBackend.Access.BankAccountTransactionInfo, + SandboxBackend.SandboxError +> { const { fetcher } = useAuthenticatedBackend(); const { data, error } = useSWR< HttpResponseOk<SandboxBackend.Access.BankAccountTransactionInfo>, - HttpError<SandboxBackend.SandboxError> + RequestError<SandboxBackend.SandboxError> >([`access-api/accounts/${account}/transactions/${tid}`], fetcher, { refreshInterval: 0, refreshWhenHidden: false, @@ -205,17 +239,20 @@ export function useTransactionDetails(account: string, tid: string): HttpRespons // if (isValidating) return { loading: true, data: data?.data }; if (data) return data; - if (error) return error; + if (error) return error.info; return { loading: true }; } interface PaginationFilter { - page: number, + page: number; } export function usePublicAccounts( args?: PaginationFilter, -): HttpResponsePaginated<SandboxBackend.Access.PublicAccountsResponse, SandboxBackend.SandboxError> { +): HttpResponsePaginated< + SandboxBackend.Access.PublicAccountsResponse, + SandboxBackend.SandboxError +> { const { paginatedFetcher } = usePublicBackend(); const [page, setPage] = useState(1); @@ -226,18 +263,21 @@ export function usePublicAccounts( isValidating: loadingAfter, } = useSWR< HttpResponseOk<SandboxBackend.Access.PublicAccountsResponse>, - HttpError<SandboxBackend.SandboxError> + RequestError<SandboxBackend.SandboxError> >([`public-accounts`, args?.page, PAGE_SIZE], paginatedFetcher); const [lastAfter, setLastAfter] = useState< - HttpResponse<SandboxBackend.Access.PublicAccountsResponse, SandboxBackend.SandboxError> + HttpResponse< + SandboxBackend.Access.PublicAccountsResponse, + SandboxBackend.SandboxError + > >({ loading: true }); useEffect(() => { if (afterData) setLastAfter(afterData); }, [afterData]); - if (afterError) return afterError; + if (afterError) return afterError.info; // if the query returns less that we ask, then we have reach the end or beginning const isReachingEnd = @@ -254,30 +294,33 @@ export function usePublicAccounts( } }, loadMorePrev: () => { - null + null; }, }; - const publicAccounts = !afterData ? [] : (afterData || lastAfter).data.publicAccounts; - if (loadingAfter) - return { loading: true, data: { publicAccounts } }; + const publicAccounts = !afterData + ? [] + : (afterData || lastAfter).data.publicAccounts; + if (loadingAfter) return { loading: true, data: { publicAccounts } }; if (afterData) { return { ok: true, data: { publicAccounts }, ...pagination }; } return { loading: true }; } - /** * FIXME: mutate result when balance change (transaction ) - * @param account - * @param args - * @returns + * @param account + * @param args + * @returns */ export function useTransactions( account: string, args?: PaginationFilter, -): HttpResponsePaginated<SandboxBackend.Access.BankAccountTransactionsResponse, SandboxBackend.SandboxError> { +): HttpResponsePaginated< + SandboxBackend.Access.BankAccountTransactionsResponse, + SandboxBackend.SandboxError +> { const { paginatedFetcher } = useAuthenticatedBackend(); const [page, setPage] = useState(1); @@ -288,18 +331,24 @@ export function useTransactions( isValidating: loadingAfter, } = useSWR< HttpResponseOk<SandboxBackend.Access.BankAccountTransactionsResponse>, - HttpError<SandboxBackend.SandboxError> - >([`access-api/accounts/${account}/transactions`, args?.page, PAGE_SIZE], paginatedFetcher); + RequestError<SandboxBackend.SandboxError> + >( + [`access-api/accounts/${account}/transactions`, args?.page, PAGE_SIZE], + paginatedFetcher, + ); const [lastAfter, setLastAfter] = useState< - HttpResponse<SandboxBackend.Access.BankAccountTransactionsResponse, SandboxBackend.SandboxError> + HttpResponse< + SandboxBackend.Access.BankAccountTransactionsResponse, + SandboxBackend.SandboxError + > >({ loading: true }); useEffect(() => { if (afterData) setLastAfter(afterData); }, [afterData]); - if (afterError) return afterError; + if (afterError) return afterError.info; // if the query returns less that we ask, then we have reach the end or beginning const isReachingEnd = @@ -316,13 +365,14 @@ export function useTransactions( } }, loadMorePrev: () => { - null + null; }, }; - const transactions = !afterData ? [] : (afterData || lastAfter).data.transactions; - if (loadingAfter) - return { loading: true, data: { transactions } }; + const transactions = !afterData + ? [] + : (afterData || lastAfter).data.transactions; + if (loadingAfter) return { loading: true, data: { transactions } }; if (afterData) { return { ok: true, data: { transactions }, ...pagination }; } diff --git a/packages/demobank-ui/src/hooks/backend.ts b/packages/demobank-ui/src/hooks/backend.ts index f4f5ecfd0..e87bdd5fe 100644 --- a/packages/demobank-ui/src/hooks/backend.ts +++ b/packages/demobank-ui/src/hooks/backend.ts @@ -15,7 +15,10 @@ */ import { canonicalizeBaseUrl } from "@gnu-taler/taler-util"; -import { useLocalStorage } from "@gnu-taler/web-util/lib/index.browser"; +import { + RequestError, + useLocalStorage, +} from "@gnu-taler/web-util/lib/index.browser"; import { HttpResponse, HttpResponseOk, @@ -57,7 +60,7 @@ export function getInitialBackendBaseURL(): string { export const defaultState: BackendState = { status: "loggedOut", - url: getInitialBackendBaseURL() + url: getInitialBackendBaseURL(), }; export interface BackendStateHandler { @@ -91,7 +94,12 @@ export function useBackendState(): BackendStateHandler { }, logIn(info) { //admin is defined by the username - const nextState: BackendState = { status: "loggedIn", url: state.url, ...info, isUserAdministrator: info.username === "admin" }; + const nextState: BackendState = { + status: "loggedIn", + url: state.url, + ...info, + isUserAdministrator: info.username === "admin", + }; update(JSON.stringify(nextState)); }, }; @@ -103,24 +111,25 @@ interface useBackendType { options?: RequestOptions, ) => Promise<HttpResponseOk<T>>; fetcher: <T>(endpoint: string) => Promise<HttpResponseOk<T>>; - multiFetcher: <T>(endpoint: string[]) => Promise<HttpResponseOk<T>[]>; - paginatedFetcher: <T>(args: [string, number, number]) => Promise<HttpResponseOk<T>>; - sandboxAccountsFetcher: <T>(args: [string, number, number, string]) => Promise<HttpResponseOk<T>>; + multiFetcher: <T>(endpoint: string[][]) => Promise<HttpResponseOk<T>[]>; + paginatedFetcher: <T>( + args: [string, number, number], + ) => Promise<HttpResponseOk<T>>; + sandboxAccountsFetcher: <T>( + args: [string, number, number, string], + ) => Promise<HttpResponseOk<T>>; } - - export function usePublicBackend(): useBackendType { const { state } = useBackendContext(); const { request: requestHandler } = useApiContext(); - const baseUrl = state.url + const baseUrl = state.url; const request = useCallback( function requestImpl<T>( path: string, options: RequestOptions = {}, ): Promise<HttpResponseOk<T>> { - return requestHandler<T>(baseUrl, path, options); }, [baseUrl], @@ -133,15 +142,21 @@ export function usePublicBackend(): useBackendType { [baseUrl], ); const paginatedFetcher = useCallback( - function fetcherImpl<T>([endpoint, page, size]: [string, number, number]): Promise<HttpResponseOk<T>> { - return requestHandler<T>(baseUrl, endpoint, { params: { page: page || 1, size } }); + function fetcherImpl<T>([endpoint, page, size]: [ + string, + number, + number, + ]): Promise<HttpResponseOk<T>> { + return requestHandler<T>(baseUrl, endpoint, { + params: { page: page || 1, size }, + }); }, [baseUrl], ); const multiFetcher = useCallback( - function multiFetcherImpl<T>( - endpoints: string[], - ): Promise<HttpResponseOk<T>[]> { + function multiFetcherImpl<T>([endpoints]: string[][]): Promise< + HttpResponseOk<T>[] + > { return Promise.all( endpoints.map((endpoint) => requestHandler<T>(baseUrl, endpoint)), ); @@ -149,27 +164,39 @@ export function usePublicBackend(): useBackendType { [baseUrl], ); const sandboxAccountsFetcher = useCallback( - function fetcherImpl<T>([endpoint, page, size, account]: [string, number, number, string]): Promise<HttpResponseOk<T>> { - return requestHandler<T>(baseUrl, endpoint, { params: { page: page || 1, size } }); + function fetcherImpl<T>([endpoint, page, size, account]: [ + string, + number, + number, + string, + ]): Promise<HttpResponseOk<T>> { + return requestHandler<T>(baseUrl, endpoint, { + params: { page: page || 1, size }, + }); }, [baseUrl], ); - return { request, fetcher, paginatedFetcher, multiFetcher, sandboxAccountsFetcher }; + return { + request, + fetcher, + paginatedFetcher, + multiFetcher, + sandboxAccountsFetcher, + }; } export function useAuthenticatedBackend(): useBackendType { const { state } = useBackendContext(); const { request: requestHandler } = useApiContext(); - const creds = state.status === "loggedIn" ? state : undefined - const baseUrl = state.url + const creds = state.status === "loggedIn" ? state : undefined; + const baseUrl = state.url; const request = useCallback( function requestImpl<T>( path: string, options: RequestOptions = {}, ): Promise<HttpResponseOk<T>> { - return requestHandler<T>(baseUrl, path, { basicAuth: creds, ...options }); }, [baseUrl, creds], @@ -182,36 +209,66 @@ export function useAuthenticatedBackend(): useBackendType { [baseUrl, creds], ); const paginatedFetcher = useCallback( - function fetcherImpl<T>([endpoint, page = 0, size]: [string, number, number]): Promise<HttpResponseOk<T>> { - return requestHandler<T>(baseUrl, endpoint, { basicAuth: creds, params: { page, size } }); + function fetcherImpl<T>([endpoint, page = 0, size]: [ + string, + number, + number, + ]): Promise<HttpResponseOk<T>> { + return requestHandler<T>(baseUrl, endpoint, { + basicAuth: creds, + params: { page, size }, + }); }, [baseUrl, creds], ); const multiFetcher = useCallback( - function multiFetcherImpl<T>( - endpoints: string[], - ): Promise<HttpResponseOk<T>[]> { + function multiFetcherImpl<T>([endpoints]: string[][]): Promise< + HttpResponseOk<T>[] + > { + console.log("list size", endpoints.length, endpoints); return Promise.all( - endpoints.map((endpoint) => requestHandler<T>(baseUrl, endpoint, { basicAuth: creds })), + endpoints.map((endpoint) => + requestHandler<T>(baseUrl, endpoint, { basicAuth: creds }), + ), ); }, [baseUrl, creds], ); const sandboxAccountsFetcher = useCallback( - function fetcherImpl<T>([endpoint, page, size, account]: [string, number, number, string]): Promise<HttpResponseOk<T>> { - return requestHandler<T>(baseUrl, endpoint, { basicAuth: creds, params: { page: page || 1, size } }); + function fetcherImpl<T>([endpoint, page, size, account]: [ + string, + number, + number, + string, + ]): Promise<HttpResponseOk<T>> { + return requestHandler<T>(baseUrl, endpoint, { + basicAuth: creds, + params: { page: page || 1, size }, + }); }, [baseUrl], ); - return { request, fetcher, paginatedFetcher, multiFetcher, sandboxAccountsFetcher }; + + return { + request, + fetcher, + paginatedFetcher, + multiFetcher, + sandboxAccountsFetcher, + }; } -export function useBackendConfig(): HttpResponse<SandboxBackend.Config, SandboxBackend.SandboxError> { +export function useBackendConfig(): HttpResponse< + SandboxBackend.Config, + SandboxBackend.SandboxError +> { const { request } = usePublicBackend(); type Type = SandboxBackend.Config; - const [result, setResult] = useState<HttpResponse<Type, SandboxBackend.SandboxError>>({ loading: true }); + const [result, setResult] = useState< + HttpResponse<Type, SandboxBackend.SandboxError> + >({ loading: true }); useEffect(() => { request<Type>(`/config`) @@ -238,10 +295,8 @@ export function useMatchMutate(): ( const allKeys = Array.from(cache.keys()); const keys = allKeys.filter((key) => re.test(key)); const mutations = keys.map((key) => { - mutate(key, value, true); + return mutate(key, value, true); }); return Promise.all(mutations); }; } - - diff --git a/packages/demobank-ui/src/hooks/circuit.ts b/packages/demobank-ui/src/hooks/circuit.ts index 6e9ada601..91922a6ba 100644 --- a/packages/demobank-ui/src/hooks/circuit.ts +++ b/packages/demobank-ui/src/hooks/circuit.ts @@ -15,23 +15,24 @@ */ import { - HttpError, HttpResponse, HttpResponseOk, HttpResponsePaginated, - RequestError + RequestError, + useApiContext, } from "@gnu-taler/web-util/lib/index.browser"; import { useEffect, useMemo, useState } from "preact/hooks"; import useSWR from "swr"; import { useBackendContext } from "../context/backend.js"; import { MAX_RESULT_SIZE, PAGE_SIZE } from "../utils.js"; -import { useAuthenticatedBackend } from "./backend.js"; +import { useAuthenticatedBackend, useMatchMutate } from "./backend.js"; export function useAdminAccountAPI(): AdminAccountAPI { const { request } = useAuthenticatedBackend(); - const { state } = useBackendContext() + const mutateAll = useMatchMutate(); + const { state } = useBackendContext(); if (state.status === "loggedOut") { - throw Error("access-api can't be used when the user is not logged In") + throw Error("access-api can't be used when the user is not logged In"); } const createAccount = async ( @@ -40,8 +41,9 @@ export function useAdminAccountAPI(): AdminAccountAPI { const res = await request<void>(`circuit-api/accounts`, { method: "POST", data, - contentType: "json" + contentType: "json", }); + await mutateAll(/.*circuit-api\/accounts.*/); return res; }; @@ -52,8 +54,9 @@ export function useAdminAccountAPI(): AdminAccountAPI { const res = await request<void>(`circuit-api/accounts/${account}`, { method: "PATCH", data, - contentType: "json" + contentType: "json", }); + await mutateAll(/.*circuit-api\/accounts.*/); return res; }; const deleteAccount = async ( @@ -61,8 +64,9 @@ export function useAdminAccountAPI(): AdminAccountAPI { ): Promise<HttpResponseOk<void>> => { const res = await request<void>(`circuit-api/accounts/${account}`, { method: "DELETE", - contentType: "json" + contentType: "json", }); + await mutateAll(/.*circuit-api\/accounts.*/); return res; }; const changePassword = async ( @@ -72,7 +76,7 @@ export function useAdminAccountAPI(): AdminAccountAPI { const res = await request<void>(`circuit-api/accounts/${account}/auth`, { method: "PATCH", data, - contentType: "json" + contentType: "json", }); return res; }; @@ -82,9 +86,10 @@ export function useAdminAccountAPI(): AdminAccountAPI { export function useCircuitAccountAPI(): CircuitAccountAPI { const { request } = useAuthenticatedBackend(); - const { state } = useBackendContext() + const mutateAll = useMatchMutate(); + const { state } = useBackendContext(); if (state.status === "loggedOut") { - throw Error("access-api can't be used when the user is not logged In") + throw Error("access-api can't be used when the user is not logged In"); } const account = state.username; @@ -94,8 +99,9 @@ export function useCircuitAccountAPI(): CircuitAccountAPI { const res = await request<void>(`circuit-api/accounts/${account}`, { method: "PATCH", data, - contentType: "json" + contentType: "json", }); + await mutateAll(/.*circuit-api\/accounts.*/); return res; }; const changePassword = async ( @@ -104,7 +110,7 @@ export function useCircuitAccountAPI(): CircuitAccountAPI { const res = await request<void>(`circuit-api/accounts/${account}/auth`, { method: "PATCH", data, - contentType: "json" + contentType: "json", }); return res; }; @@ -120,57 +126,72 @@ export interface AdminAccountAPI { updateAccount: ( account: string, - data: SandboxBackend.Circuit.CircuitAccountReconfiguration + data: SandboxBackend.Circuit.CircuitAccountReconfiguration, ) => Promise<HttpResponseOk<void>>; changePassword: ( account: string, - data: SandboxBackend.Circuit.AccountPasswordChange + data: SandboxBackend.Circuit.AccountPasswordChange, ) => Promise<HttpResponseOk<void>>; } export interface CircuitAccountAPI { updateAccount: ( - data: SandboxBackend.Circuit.CircuitAccountReconfiguration + data: SandboxBackend.Circuit.CircuitAccountReconfiguration, ) => Promise<HttpResponseOk<void>>; changePassword: ( - data: SandboxBackend.Circuit.AccountPasswordChange + data: SandboxBackend.Circuit.AccountPasswordChange, ) => Promise<HttpResponseOk<void>>; } - export interface InstanceTemplateFilter { //FIXME: add filter to the template list position?: string; } - -export function useMyAccountDetails(): HttpResponse<SandboxBackend.Circuit.CircuitAccountData, SandboxBackend.SandboxError> { - const { fetcher } = useAuthenticatedBackend(); - const { state } = useBackendContext() - if (state.status === "loggedOut") { - throw Error("can't access my-account-details when logged out") +async function getBusinessStatus( + request: ReturnType<typeof useApiContext>["request"], + url: string, + basicAuth: { username: string; password: string }, +): Promise<boolean> { + try { + const result = await request< + HttpResponseOk<SandboxBackend.Circuit.CircuitAccountData> + >(url, `circuit-api/accounts/${basicAuth.username}`, { basicAuth }); + return result.ok; + } catch (error) { + return false; } - const { data, error } = useSWR< - HttpResponseOk<SandboxBackend.Circuit.CircuitAccountData>, - HttpError<SandboxBackend.SandboxError> - >([`accounts/${state.username}`], fetcher, { - refreshInterval: 0, - refreshWhenHidden: false, - revalidateOnFocus: false, - revalidateOnReconnect: false, - refreshWhenOffline: false, - errorRetryCount: 0, - errorRetryInterval: 1, - shouldRetryOnError: false, - keepPreviousData: true, +} + +export function useBusinessAccountFlag(): boolean | undefined { + const [isBusiness, setIsBusiness] = useState<boolean | undefined>(); + const { state } = useBackendContext(); + const { request } = useApiContext(); + const creds = + state.status === "loggedOut" + ? undefined + : { username: state.username, password: state.password }; + + useEffect(() => { + if (!creds) return; + getBusinessStatus(request, state.url, creds) + .then((result) => { + setIsBusiness(result); + }) + .catch((error) => { + setIsBusiness(false); + }); }); - if (data) return data; - if (error) return error; - return { loading: true }; + return isBusiness; } -export function useAccountDetails(account: string): HttpResponse<SandboxBackend.Circuit.CircuitAccountData, SandboxBackend.SandboxError> { +export function useBusinessAccountDetails( + account: string, +): HttpResponse< + SandboxBackend.Circuit.CircuitAccountData, + SandboxBackend.SandboxError +> { const { fetcher } = useAuthenticatedBackend(); const { data, error } = useSWR< @@ -188,20 +209,22 @@ export function useAccountDetails(account: string): HttpResponse<SandboxBackend. keepPreviousData: true, }); - // if (isValidating) return { loading: true, data: data?.data }; if (data) return data; if (error) return error.info; return { loading: true }; } interface PaginationFilter { - account?: string, - page?: number, + account?: string; + page?: number; } -export function useAccounts( +export function useBusinessAccounts( args?: PaginationFilter, -): HttpResponsePaginated<SandboxBackend.Circuit.CircuitAccounts, SandboxBackend.SandboxError> { +): HttpResponsePaginated< + SandboxBackend.Circuit.CircuitAccounts, + SandboxBackend.SandboxError +> { const { sandboxAccountsFetcher } = useAuthenticatedBackend(); const [page, setPage] = useState(0); @@ -212,17 +235,21 @@ export function useAccounts( } = useSWR< HttpResponseOk<SandboxBackend.Circuit.CircuitAccounts>, RequestError<SandboxBackend.SandboxError> - >([`circuit-api/accounts`, args?.page, PAGE_SIZE, args?.account], sandboxAccountsFetcher, { - refreshInterval: 0, - refreshWhenHidden: false, - revalidateOnFocus: false, - revalidateOnReconnect: false, - refreshWhenOffline: false, - errorRetryCount: 0, - errorRetryInterval: 1, - shouldRetryOnError: false, - keepPreviousData: true, - }); + >( + [`circuit-api/accounts`, args?.page, PAGE_SIZE, args?.account], + sandboxAccountsFetcher, + { + refreshInterval: 0, + refreshWhenHidden: false, + revalidateOnFocus: false, + revalidateOnReconnect: false, + refreshWhenOffline: false, + errorRetryCount: 0, + errorRetryInterval: 1, + shouldRetryOnError: false, + keepPreviousData: true, + }, + ); // const [lastAfter, setLastAfter] = useState< // HttpResponse<SandboxBackend.Circuit.CircuitAccounts, SandboxBackend.SandboxError> @@ -247,18 +274,18 @@ export function useAccounts( } }, loadMorePrev: () => { - null + null; }, }; const result = useMemo(() => { - const customers = !afterData ? [] : (afterData)?.data?.customers ?? []; - return { ok: true as const, data: { customers }, ...pagination } - }, [afterData?.data]) + const customers = !afterData ? [] : afterData?.data?.customers ?? []; + return { ok: true as const, data: { customers }, ...pagination }; + }, [afterData?.data]); if (afterError) return afterError.info; if (afterData) { - return result + return result; } // if (loadingAfter) |