diff options
Diffstat (limited to 'packages/bank-ui/src/pages/regional/ShowCashoutDetails.tsx')
-rw-r--r-- | packages/bank-ui/src/pages/regional/ShowCashoutDetails.tsx | 194 |
1 files changed, 194 insertions, 0 deletions
diff --git a/packages/bank-ui/src/pages/regional/ShowCashoutDetails.tsx b/packages/bank-ui/src/pages/regional/ShowCashoutDetails.tsx new file mode 100644 index 000000000..aba00ad7a --- /dev/null +++ b/packages/bank-ui/src/pages/regional/ShowCashoutDetails.tsx @@ -0,0 +1,194 @@ +/* + This file is part of GNU Taler + (C) 2022-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/> + */ +import { + AbsoluteTime, + Amounts, + HttpStatusCode, + TalerError, + assertUnreachable, +} from "@gnu-taler/taler-util"; +import { + Attention, + Loading, + useTranslationContext, +} from "@gnu-taler/web-util/browser"; +import { VNode, h } from "preact"; +import { ErrorLoadingWithDebug } from "../../components/ErrorLoadingWithDebug.js"; +import { Time } from "../../components/Time.js"; +import { useCashoutDetails, useConversionInfo } from "../../hooks/regional.js"; +import { RouteDefinition } from "@gnu-taler/web-util/browser"; +import { RenderAmount } from "../PaytoWireTransferForm.js"; + +interface Props { + id: string; + routeClose: RouteDefinition; +} +export function ShowCashoutDetails({ id, routeClose }: Props): VNode { + const { i18n } = useTranslationContext(); + const cid = Number.parseInt(id, 10); + + const result = useCashoutDetails(Number.isNaN(cid) ? undefined : cid); + const info = useConversionInfo(); + + if (Number.isNaN(cid)) { + return ( + <Attention + type="danger" + title={i18n.str`Cashout id should be a number`} + /> + ); + } + if (!result) { + return <Loading />; + } + if (result instanceof TalerError) { + return <ErrorLoadingWithDebug error={result} />; + } + if (result.type === "fail") { + switch (result.case) { + case HttpStatusCode.NotFound: + return ( + <Attention + type="warning" + title={i18n.str`This cashout not found. Maybe already aborted.`} + ></Attention> + ); + case HttpStatusCode.NotImplemented: + return ( + <Attention type="warning" title={i18n.str`Cashout are disabled`}> + <i18n.Translate> + Cashout should be enable by configuration and the conversion rate + should be initialized with fee, ratio and rounding mode. + </i18n.Translate> + </Attention> + ); + default: + assertUnreachable(result); + } + } + if (!info) { + return <Loading />; + } + + if (info instanceof TalerError) { + return <ErrorLoadingWithDebug error={info} />; + } + if (info.type === "fail") { + switch (info.case) { + case HttpStatusCode.NotImplemented: { + return ( + <Attention type="danger" title={i18n.str`Cashout are disabled`}> + <i18n.Translate> + Cashout should be enable by configuration and the conversion rate + should be initialized with fee, ratio and rounding mode. + </i18n.Translate> + </Attention> + ); + } + default: + assertUnreachable(info.case); + } + } + + const { fiat_currency_specification, regional_currency_specification } = + info.body; + + return ( + <div> + <div class="grid grid-cols-1 gap-x-8 gap-y-8 pt-6 md:grid-cols-3 bg-gray-100 my-4 px-4 pb-4 rounded-lg"> + <section class="rounded-sm px-4"> + <h2 id="summary-heading" class="font-medium text-lg"> + <i18n.Translate>Cashout detail</i18n.Translate> + </h2> + <dl class="mt-8 space-y-4"> + <div class="justify-between items-center flex"> + <dt class="text-sm text-gray-600"> + <i18n.Translate>Subject</i18n.Translate> + </dt> + <dd class="text-sm ">{result.body.subject}</dd> + </div> + </dl> + </section> + <div class="bg-white shadow-sm ring-1 ring-gray-900/5 sm:rounded-xl md:col-span-2"> + <div class="px-4 py-6 sm:p-8"> + <div class="grid max-w-2xl grid-cols-1 gap-x-6 gap-y-8 sm:grid-cols-6"> + <div class="sm:col-span-5"> + <dl class="space-y-4"> + {result.body.creation_time.t_s !== "never" ? ( + <div class="justify-between items-center flex "> + <dt class=" text-gray-600"> + <i18n.Translate>Created</i18n.Translate> + </dt> + <dd class="text-sm "> + <Time + format="dd/MM/yyyy HH:mm:ss" + timestamp={AbsoluteTime.fromProtocolTimestamp( + result.body.creation_time, + )} + // relative={Duration.fromSpec({ days: 1 })} + /> + </dd> + </div> + ) : undefined} + + <div class="flex justify-between items-center border-t-2 afu pt-4"> + <dt class="text-gray-600"> + <i18n.Translate>Debited</i18n.Translate> + </dt> + <dd class=" font-medium"> + <RenderAmount + value={Amounts.parseOrThrow(result.body.amount_debit)} + negative + withColor + spec={regional_currency_specification} + /> + </dd> + </div> + + <div class="flex items-center justify-between border-t-2 afu pt-4"> + <dt class="flex items-center text-gray-600"> + <span> + <i18n.Translate>Credited</i18n.Translate> + </span> + </dt> + <dd class="text-sm "> + <RenderAmount + value={Amounts.parseOrThrow(result.body.amount_credit)} + withColor + spec={fiat_currency_specification} + /> + </dd> + </div> + </dl> + </div> + </div> + </div> + </div> + </div> + + <br /> + <div style={{ display: "flex", justifyContent: "space-between" }}> + <a + href={routeClose.url({})} + name="close" + class="text-sm font-semibold leading-6 text-gray-900" + > + <i18n.Translate>Close</i18n.Translate> + </a> + </div> + </div> + ); +} |