/*
This file is part of GNU Taler
(C) 2022 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
*/
import {
HttpStatusCode,
Logger,
parseWithdrawUri,
stringifyWithdrawUri,
} from "@gnu-taler/taler-util";
import {
ErrorType,
HttpResponse,
HttpResponsePaginated,
useTranslationContext,
} from "@gnu-taler/web-util/lib/index.browser";
import { Fragment, VNode, h } from "preact";
import { StateUpdater } from "preact/hooks";
import { Loading } from "../components/Loading.js";
import { useBackendContext } from "../context/backend.js";
import {
ObservedStateType,
PageStateType,
notifyError,
notifyInfo,
usePageContext,
} from "../context/pageState.js";
import { getInitialBackendBaseURL } from "../hooks/backend.js";
import { AccountPage } from "./AccountPage.js";
import { AdminPage } from "./AdminPage.js";
import { LoginForm } from "./LoginForm.js";
import { WithdrawalQRCode } from "./WithdrawalQRCode.js";
const logger = new Logger("AccountPage");
/**
* show content based on state:
* - LoginForm if the user is not logged in
* - qr code if withdrawal in progress
* - else account information
* Use the handler to catch error cases
*
* @param param0
* @returns
*/
export function HomePage({
onRegister,
onPendingOperationFound,
}: {
onPendingOperationFound: (id: string) => void;
onRegister: () => void;
}): VNode {
const backend = useBackendContext();
const { pageState, pageStateSetter } = usePageContext();
const { i18n } = useTranslationContext();
if (backend.state.status === "loggedOut") {
return ;
}
if (pageState.currentWithdrawalOperationId) {
onPendingOperationFound(pageState.currentWithdrawalOperationId);
return ;
}
if (backend.state.isUserAdministrator) {
return ;
}
return (
);
}
export function WithdrawalOperationPage({
operationId,
onLoadNotOk,
onAbort,
}: {
operationId: string;
onLoadNotOk: () => void;
onAbort: () => void;
}): VNode {
const uri = stringifyWithdrawUri({
bankIntegrationApiBaseUrl: getInitialBackendBaseURL(),
withdrawalOperationId: operationId,
});
const parsedUri = parseWithdrawUri(uri);
const { i18n } = useTranslationContext();
const { pageStateSetter } = usePageContext();
function clearCurrentWithdrawal(): void {
pageStateSetter({});
onAbort();
}
if (!parsedUri) {
notifyError({
title: i18n.str`The Withdrawal URI is not valid: "${uri}"`,
});
return ;
}
return (
{
notifyInfo(i18n.str`Withdrawal confirmed!`);
}}
onAborted={clearCurrentWithdrawal}
onLoadNotOk={onLoadNotOk}
/>
);
}
export function handleNotOkResult(
i18n: ReturnType["i18n"],
onRegister?: () => void,
): (
result:
| HttpResponsePaginated
| HttpResponse,
) => VNode {
return function handleNotOkResult2(
result:
| HttpResponsePaginated
| HttpResponse,
): VNode {
if (result.loading) return ;
if (!result.ok) {
switch (result.type) {
case ErrorType.TIMEOUT: {
notifyError({
title: i18n.str`Request timeout, try again later.`,
});
break;
}
case ErrorType.CLIENT: {
if (result.status === HttpStatusCode.Unauthorized) {
notifyError({
title: i18n.str`Wrong credentials`,
});
return ;
}
const errorData = result.payload;
notifyError({
title: i18n.str`Could not load due to a client error`,
description: errorData.error.description,
debug: JSON.stringify(result),
});
break;
}
case ErrorType.SERVER: {
notifyError({
title: i18n.str`Server returned with error`,
description: result.payload.error.description,
debug: JSON.stringify(result.payload),
});
break;
}
case ErrorType.UNREADABLE: {
notifyError({
title: i18n.str`Unexpected error.`,
description: `Response from ${result.info?.url} is unreadable, http status: ${result.status}`,
debug: JSON.stringify(result),
});
break;
}
case ErrorType.UNEXPECTED: {
notifyError({
title: i18n.str`Unexpected error.`,
description: `Diagnostic from ${result.info?.url} is "${result.message}"`,
debug: JSON.stringify(result),
});
break;
}
default: {
assertUnreachable(result);
}
}
return error
;
}
return ;
};
}
export function assertUnreachable(x: never): never {
throw new Error("Didn't expect to get here");
}