aboutsummaryrefslogtreecommitdiff
path: root/packages/demobank-ui
diff options
context:
space:
mode:
authorSebastian <sebasjm@gmail.com>2023-11-24 15:33:02 -0300
committerSebastian <sebasjm@gmail.com>2023-11-24 15:33:02 -0300
commitc5c0d6502e3fe80c431c6ac33ec162aeb011a312 (patch)
tree79bfaa18f02c3b2eef91d0217ae7812a10d00226 /packages/demobank-ui
parent6f7512be74005f169f98654f11360fd4fff9162f (diff)
downloadwallet-core-c5c0d6502e3fe80c431c6ac33ec162aeb011a312.tar.xz
monitor stats
Diffstat (limited to 'packages/demobank-ui')
-rw-r--r--packages/demobank-ui/src/hooks/circuit.ts33
-rw-r--r--packages/demobank-ui/src/pages/admin/AdminHome.tsx124
2 files changed, 90 insertions, 67 deletions
diff --git a/packages/demobank-ui/src/hooks/circuit.ts b/packages/demobank-ui/src/hooks/circuit.ts
index bb9f5801e..4686969dc 100644
--- a/packages/demobank-ui/src/hooks/circuit.ts
+++ b/packages/demobank-ui/src/hooks/circuit.ts
@@ -284,43 +284,16 @@ export type MonitorMetrics = {
lastMonth: TalerCoreBankResultByMethod<"getMonitor">,
}
-function getTimeframesForDate(time: Date, timeframe: TalerCorebankApi.MonitorTimeframeParam): { current: number, previous: number } {
- switch (timeframe) {
- case TalerCorebankApi.MonitorTimeframeParam.hour: return {
- current: getHours(sub(time, { hours: 1 })),
- previous: getHours(sub(time, { hours: 2 }))
- }
- case TalerCorebankApi.MonitorTimeframeParam.day: return {
- current: getDate(sub(time, { days: 1 })),
- previous: getDate(sub(time, { days: 2 }))
- }
- case TalerCorebankApi.MonitorTimeframeParam.month: return {
- current: getMonth(sub(time, { months: 1 })),
- previous: getMonth(sub(time, { months: 2 }))
- }
- case TalerCorebankApi.MonitorTimeframeParam.year: return {
- current: getYear(sub(time, { years: 1 })),
- previous: getYear(sub(time, { years: 2 }))
- }
- case TalerCorebankApi.MonitorTimeframeParam.decade: return {
- current: getYear(sub(time, { years: 10 })),
- previous: getYear(sub(time, { years: 20 }))
- }
- default: assertUnreachable(timeframe)
- }
-}
-
export type LastMonitor = { current: TalerCoreBankResultByMethod<"getMonitor">, previous: TalerCoreBankResultByMethod<"getMonitor"> }
-export function useLastMonitorInfo(time: Date, timeframe: TalerCorebankApi.MonitorTimeframeParam) {
+export function useLastMonitorInfo(currentMoment: number, previousMoment: number, timeframe: TalerCorebankApi.MonitorTimeframeParam) {
const { api, config } = useBankCoreApiContext();
const { state: credentials } = useBackendState();
const token = credentials.status !== "loggedIn" ? undefined : credentials.token
async function fetcher([token]: [AccessToken]) {
- const params = getTimeframesForDate(time, timeframe)
const [current, previous] = await Promise.all([
- api.getMonitor(token, { timeframe, which: params.current }),
- api.getMonitor(token, { timeframe, which: params.previous }),
+ api.getMonitor(token, { timeframe, which: currentMoment }),
+ api.getMonitor(token, { timeframe, which: previousMoment }),
])
return {
current,
diff --git a/packages/demobank-ui/src/pages/admin/AdminHome.tsx b/packages/demobank-ui/src/pages/admin/AdminHome.tsx
index e9fa1dc47..d1b48fb6d 100644
--- a/packages/demobank-ui/src/pages/admin/AdminHome.tsx
+++ b/packages/demobank-ui/src/pages/admin/AdminHome.tsx
@@ -1,4 +1,4 @@
-import { AmountString, Amounts, TalerCorebankApi, TalerError } from "@gnu-taler/taler-util";
+import { AmountString, Amounts, TalerCorebankApi, TalerError, assertUnreachable } from "@gnu-taler/taler-util";
import { ErrorLoading, useTranslationContext } from "@gnu-taler/web-util/browser";
import { Fragment, VNode, h } from "preact";
import { useState } from "preact/hooks";
@@ -8,6 +8,8 @@ import { RenderAmount } from "../PaytoWireTransferForm.js";
import { WireTransfer } from "../WireTransfer.js";
import { AccountList } from "./AccountList.js";
import { useBankCoreApiContext } from "../../context/config.js";
+import { format, getDate, getHours, getMonth, getYear, setDate, setHours, setMonth, setYear, sub } from "date-fns";
+
/**
* Query account information and show QR code if there is pending withdrawal
@@ -23,7 +25,7 @@ interface Props {
}
export function AdminHome({ onCreateAccount, onRegister, onRemoveAccount, onShowAccountDetails, onShowCashoutForAccount, onUpdateAccountPassword }: Props): VNode {
return <Fragment>
- {/* <Metrics /> */}
+ <Metrics />
<WireTransfer onRegister={onRegister} />
<Transactions account="admin" />
@@ -38,11 +40,53 @@ export function AdminHome({ onCreateAccount, onRegister, onRemoveAccount, onShow
</Fragment>
}
+function getDateForTimeframe(which: number, timeframe: TalerCorebankApi.MonitorTimeframeParam): string {
+ const time = Date.now()
+
+ switch (timeframe) {
+ case TalerCorebankApi.MonitorTimeframeParam.hour: return `${format(setHours(time, which), "HH")}hs`;
+ case TalerCorebankApi.MonitorTimeframeParam.day: return format(setDate(time, which), "EEEE");
+ case TalerCorebankApi.MonitorTimeframeParam.month: return format(setMonth(time, which), "MMMM");
+ case TalerCorebankApi.MonitorTimeframeParam.year: return format(setYear(time, which), "yyyy");
+ case TalerCorebankApi.MonitorTimeframeParam.decade: return format(setYear(time, which), "yyyy");
+ }
+ assertUnreachable(timeframe)
+}
+
+function getTimeframesForDate(time: Date, timeframe: TalerCorebankApi.MonitorTimeframeParam): { current: number, previous: number } {
+ switch (timeframe) {
+ case TalerCorebankApi.MonitorTimeframeParam.hour: return {
+ current: getHours(sub(time, { hours: 1 })),
+ previous: getHours(sub(time, { hours: 2 }))
+ }
+ case TalerCorebankApi.MonitorTimeframeParam.day: return {
+ current: getDate(sub(time, { days: 1 })),
+ previous: getDate(sub(time, { days: 2 }))
+ }
+ case TalerCorebankApi.MonitorTimeframeParam.month: return {
+ current: getMonth(sub(time, { months: 1 })),
+ previous: getMonth(sub(time, { months: 2 }))
+ }
+ case TalerCorebankApi.MonitorTimeframeParam.year: return {
+ current: getYear(sub(time, { years: 1 })),
+ previous: getYear(sub(time, { years: 2 }))
+ }
+ case TalerCorebankApi.MonitorTimeframeParam.decade: return {
+ current: getYear(sub(time, { years: 10 })),
+ previous: getYear(sub(time, { years: 20 }))
+ }
+ default: assertUnreachable(timeframe)
+ }
+}
+
+
function Metrics(): VNode {
const { i18n } = useTranslationContext()
- const [metricType, setMetricType] = useState<TalerCorebankApi.MonitorTimeframeParam>(TalerCorebankApi.MonitorTimeframeParam.day);
+ const [metricType, setMetricType] = useState<TalerCorebankApi.MonitorTimeframeParam>(TalerCorebankApi.MonitorTimeframeParam.hour);
- const resp = useLastMonitorInfo(new Date(), metricType);
+ const params = getTimeframesForDate(new Date(), metricType)
+
+ const resp = useLastMonitorInfo(params.current, params.previous, metricType);
if (!resp) return <Fragment />;
if (resp instanceof TalerError) {
return <ErrorLoading error={resp} />
@@ -54,8 +98,6 @@ function Metrics(): VNode {
return <Fragment />
}
- // const metric = getMetricInfo(metricType, current, previous);
-
return <Fragment>
<div class="sm:hidden">
<label for="tabs" class="sr-only"><i18n.Translate>Select a section</i18n.Translate></label>
@@ -91,10 +133,8 @@ function Metrics(): VNode {
</div>
<div class="w-full flex justify-between">
-
<h1 class="text-base font-semibold leading-7 text-gray-900 mt-5">
-
- Trading volume on Thursday
+ <i18n.Translate>Trading volume on {getDateForTimeframe(params.current, metricType)} compared to {getDateForTimeframe(params.previous, metricType)}</i18n.Translate>
</h1>
<div class="flex items-center justify-between">
{/* <span class="flex flex-grow flex-col">
@@ -121,7 +161,7 @@ function Metrics(): VNode {
</div>
</div>
- <dl class="mt-5 grid grid-cols-1 divide-y divide-gray-200 overflow-hidden rounded-lg bg-white shadow-lg md:grid-cols-3 md:divide-x md:divide-y-0">
+ <dl class="mt-5 grid grid-cols-1 divide-y divide-gray-200 overflow-hidden rounded-lg bg-white shadow-lg md:grid-cols-4 md:divide-x md:divide-y-0">
{resp.current.body.type !== "with-conversions" || resp.previous.body.type !== "with-conversions" ? undefined :
<Fragment>
@@ -147,6 +187,15 @@ function Metrics(): VNode {
}
<div class="px-4 py-5 sm:p-6">
<dt class="text-base font-normal text-gray-900">
+ <i18n.Translate>Payin</i18n.Translate>
+ </dt>
+ <MetricValue
+ current={resp.current.body.talerInVolume}
+ previous={resp.previous.body.talerInVolume}
+ />
+ </div>
+ <div class="px-4 py-5 sm:p-6">
+ <dt class="text-base font-normal text-gray-900">
<i18n.Translate>Payout</i18n.Translate>
</dt>
<MetricValue
@@ -162,7 +211,7 @@ function Metrics(): VNode {
function MetricValue({ current, previous }: { current: AmountString | undefined, previous: AmountString | undefined }): VNode {
const { i18n } = useTranslationContext()
- const {config} = useBankCoreApiContext();
+ const { config } = useBankCoreApiContext();
const cmp = current && previous ? Amounts.cmp(current, previous) : 0;
const currAmount = !current ? undefined : Number.parseFloat(Amounts.stringifyValue(current))
const prevAmount = !previous ? undefined : Number.parseFloat(Amounts.stringifyValue(previous))
@@ -171,34 +220,35 @@ function MetricValue({ current, previous }: { current: AmountString | undefined,
cmp === -1 ? 1 - Math.round(currAmount) / Math.round(prevAmount) :
cmp === 1 ? (Math.round(currAmount) / Math.round(prevAmount)) - 1 : 0;
+ const negative = cmp === 0 ? undefined : cmp === -1
const rateStr = `${(Math.abs(rate) * 100).toFixed(2)}%`
- return <dd class="mt-1 flex justify-between md:block lg:flex">
- <div class="flex justify-start items-baseline text-2xl font-semibold text-indigo-600">
- {!current ? "-" : <RenderAmount value={Amounts.parseOrThrow(current)} spec={config.currency_specification} />}
- </div>
- <div class="flex justify-end items-baseline text-2xl font-semibold text-indigo-600">
- <small class="ml-2 text-sm font-medium text-gray-500">
- <i18n.Translate>from</i18n.Translate> {!previous ? "-" : <RenderAmount value={Amounts.parseOrThrow(previous)} spec={config.currency_specification}/>}
- </small>
- </div>
+ return <Fragment>
- {cmp == 1 &&
- <div class="inline-flex items-baseline rounded-full px-2.5 py-0.5 text-sm font-medium bg-green-100 text-green-800 md:mt-2 lg:mt-0">
- <svg class="-ml-1 mr-0.5 h-5 w-5 flex-shrink-0 self-center text-green-500" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
- <path fill-rule="evenodd" d="M10 17a.75.75 0 01-.75-.75V5.612L5.29 9.77a.75.75 0 01-1.08-1.04l5.25-5.5a.75.75 0 011.08 0l5.25 5.5a.75.75 0 11-1.08 1.04l-3.96-4.158V16.25A.75.75 0 0110 17z" clip-rule="evenodd" />
- </svg>
- <span class="sr-only"><i18n.Translate>Increased by</i18n.Translate></span>
- {rateStr}
+ <dd class="mt-1 flex justify-between md:block lg:flex">
+ <div class="flex justify-start items-baseline text-2xl font-semibold text-indigo-600">
+ {!current ? "-" : <RenderAmount value={Amounts.parseOrThrow(current)} spec={config.currency_specification} />}
</div>
- }
- {cmp == -1 &&
- <div class="inline-flex items-baseline rounded-full px-2.5 py-0.5 text-sm font-medium bg-red-100 text-red-800 md:mt-2 lg:mt-0">
- <svg class="-ml-1 mr-0.5 h-5 w-5 flex-shrink-0 self-center text-red-500" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
- <path fill-rule="evenodd" d="M10 3a.75.75 0 01.75.75v10.638l3.96-4.158a.75.75 0 111.08 1.04l-5.25 5.5a.75.75 0 01-1.08 0l-5.25-5.5a.75.75 0 111.08-1.04l3.96 4.158V3.75A.75.75 0 0110 3z" clip-rule="evenodd" />
- </svg>
- <span class="sr-only"><i18n.Translate>Descreased by</i18n.Translate></span>
- {rateStr}
+ <div class="flex flex-col">
+
+ <div class="flex justify-end items-baseline text-2xl font-semibold text-indigo-600">
+ <small class="ml-2 text-sm font-medium text-gray-500">
+ <i18n.Translate>from</i18n.Translate> {!previous ? "-" : <RenderAmount value={Amounts.parseOrThrow(previous)} spec={config.currency_specification} />}
+ </small>
+ </div>
+ {negative !== undefined &&
+ <span data-negative={negative} class="flex items-center gap-x-1.5 w-fit rounded-md bg-green-100 text-green-800 data-[negative=true]:bg-red-100 px-2 py-1 text-xs font-medium data-[negative=true]:text-red-700 whitespace-pre">
+ <svg class="h-5 w-5 self-center data-[negative=false]:text-green-500 data-[negative=true]:text-red-500" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
+ <path fill-rule="evenodd" d="M10 3a.75.75 0 01.75.75v10.638l3.96-4.158a.75.75 0 111.08 1.04l-5.25 5.5a.75.75 0 01-1.08 0l-5.25-5.5a.75.75 0 111.08-1.04l3.96 4.158V3.75A.75.75 0 0110 3z" clip-rule="evenodd" />
+ </svg>
+ {negative ?
+ <span class="sr-only"><i18n.Translate>Descreased by</i18n.Translate></span> :
+ <span class="sr-only"><i18n.Translate>Increased by</i18n.Translate></span>
+ }
+ {rateStr}
+ </span>
+ }
</div>
- }
- </dd>
+
+ </dd>
+ </Fragment>
}