/*
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
*/
import {
AbsoluteTime,
AmountString,
Amounts,
CurrencySpecification,
HttpStatusCode,
TalerCorebankApi,
TalerError,
assertUnreachable,
} from "@gnu-taler/taler-util";
import {
Attention,
RouteDefinition,
useBankCoreApiContext,
useTranslationContext,
} from "@gnu-taler/web-util/browser";
import {
format,
sub
} from "date-fns";
import { Fragment, VNode, h } from "preact";
import { useState } from "preact/hooks";
import { ErrorLoadingWithDebug } from "../../components/ErrorLoadingWithDebug.js";
import { Transactions } from "../../components/Transactions/index.js";
import { useConversionInfo, useLastMonitorInfo } from "../../hooks/regional.js";
import { RenderAmount } from "../PaytoWireTransferForm.js";
import { WireTransfer } from "../WireTransfer.js";
import { AccountList } from "./AccountList.js";
/**
* Query account information and show QR code if there is pending withdrawal
*/
interface Props {
routeCreate: RouteDefinition;
routeDownloadStats: RouteDefinition;
routeCreateWireTransfer: RouteDefinition<{
account?: string;
subject?: string;
amount?: string;
}>;
routeShowAccount: RouteDefinition<{ account: string }>;
routeRemoveAccount: RouteDefinition<{ account: string }>;
routeUpdatePasswordAccount: RouteDefinition<{ account: string }>;
routeShowCashoutsAccount: RouteDefinition<{ account: string }>;
onAuthorizationRequired: () => void;
}
export function AdminHome({
routeCreate,
routeRemoveAccount,
routeShowAccount,
routeUpdatePasswordAccount,
routeDownloadStats,
routeCreateWireTransfer,
onAuthorizationRequired,
}: Props): VNode {
return (
);
}
function getDateForTimeframe(
date: AbsoluteTime,
timeframe: TalerCorebankApi.MonitorTimeframeParam,
locale: Locale,
): string {
if (date.t_ms === "never") return "--";
switch (timeframe) {
case TalerCorebankApi.MonitorTimeframeParam.hour:
return `${format(date.t_ms, "HH", { locale })}hs`;
case TalerCorebankApi.MonitorTimeframeParam.day:
return format(date.t_ms, "EEEE", { locale });
case TalerCorebankApi.MonitorTimeframeParam.month:
return format(date.t_ms, "MMMM", { locale });
case TalerCorebankApi.MonitorTimeframeParam.year:
return format(date.t_ms, "yyyy", { locale });
case TalerCorebankApi.MonitorTimeframeParam.decade:
return format(date.t_ms, "yyyy", { locale });
}
assertUnreachable(timeframe);
}
export function getTimeframesForDate(
time: Date,
timeframe: TalerCorebankApi.MonitorTimeframeParam,
): { current: AbsoluteTime; previous: AbsoluteTime } {
switch (timeframe) {
case TalerCorebankApi.MonitorTimeframeParam.hour:
return {
current: AbsoluteTime.fromMilliseconds(
sub(time, { hours: 1 }).getTime(),
),
previous: AbsoluteTime.fromMilliseconds(
sub(time, { hours: 2 }).getTime(),
),
};
case TalerCorebankApi.MonitorTimeframeParam.day:
return {
current: AbsoluteTime.fromMilliseconds(
sub(time, { days: 1 }).getTime(),
),
previous: AbsoluteTime.fromMilliseconds(
sub(time, { days: 4 }).getTime(),
),
};
case TalerCorebankApi.MonitorTimeframeParam.month:
return {
current: AbsoluteTime.fromMilliseconds(
sub(time, { months: 1 }).getTime(),
),
previous: AbsoluteTime.fromMilliseconds(
sub(time, { months: 2 }).getTime(),
),
};
case TalerCorebankApi.MonitorTimeframeParam.year:
return {
current: AbsoluteTime.fromMilliseconds(
sub(time, { years: 1 }).getTime(),
),
previous: AbsoluteTime.fromMilliseconds(
sub(time, { years: 2 }).getTime(),
),
};
case TalerCorebankApi.MonitorTimeframeParam.decade:
return {
current: AbsoluteTime.fromMilliseconds(
sub(time, { years: 10 }).getTime(),
),
previous: AbsoluteTime.fromMilliseconds(
sub(time, { years: 20 }).getTime(),
),
};
default:
assertUnreachable(timeframe);
}
}
function Metrics({
routeDownloadStats,
}: {
routeDownloadStats: RouteDefinition;
}): VNode {
const { i18n, dateLocale } = useTranslationContext();
const [metricType, setMetricType] =
useState(
TalerCorebankApi.MonitorTimeframeParam.hour,
);
const { config } = useBankCoreApiContext();
const respInfo = useConversionInfo();
const params = getTimeframesForDate(new Date(), metricType);
const resp = useLastMonitorInfo(params.current, params.previous, metricType);
if (!resp) return ;
if (resp instanceof TalerError) {
return ;
}
if (!respInfo) return ;
if (respInfo instanceof TalerError) {
return ;
}
if (respInfo.type === "fail") {
switch (respInfo.case) {
case HttpStatusCode.NotImplemented: {
return (
Cashout should be enable by configuration and the conversion rate
should be initialized with fee, ratio and rounding mode.
);
}
default: {
assertUnreachable(respInfo.case);
}
}
}
if (resp.current.type !== "ok") {
switch (resp.current.case) {
case HttpStatusCode.BadRequest:
return (
The request parameters are wrong
);
case HttpStatusCode.Unauthorized:
return (
The user is unauthorized
);
default: {
assertUnreachable(resp.current);
}
}
}
if (resp.previous.type !== "ok") {
switch (resp.previous.case) {
case HttpStatusCode.BadRequest:
return (
The request parameters are wrong
);
case HttpStatusCode.Unauthorized:
return (
The user is unauthorized
);
default: {
assertUnreachable(resp.previous);
}
}
}
return (
Transaction volume report
{/* FIXME: This should be LINKS */}
{i18n.str`Trading volume on ${getDateForTimeframe(
params.current,
metricType,
dateLocale,
)} compared to ${getDateForTimeframe(
params.previous,
metricType,
dateLocale,
)}`}