aboutsummaryrefslogtreecommitdiff
path: root/packages/aml-backoffice-ui/src/pages/CaseDetails.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'packages/aml-backoffice-ui/src/pages/CaseDetails.tsx')
-rw-r--r--packages/aml-backoffice-ui/src/pages/CaseDetails.tsx226
1 files changed, 20 insertions, 206 deletions
diff --git a/packages/aml-backoffice-ui/src/pages/CaseDetails.tsx b/packages/aml-backoffice-ui/src/pages/CaseDetails.tsx
index f618a3592..1f8d6ac5e 100644
--- a/packages/aml-backoffice-ui/src/pages/CaseDetails.tsx
+++ b/packages/aml-backoffice-ui/src/pages/CaseDetails.tsx
@@ -2,24 +2,20 @@ import {
AbsoluteTime,
AmountJson,
Amounts,
- PaytoString,
TalerError,
TranslatedString,
- assertUnreachable,
+ assertUnreachable
} from "@gnu-taler/taler-util";
import { ErrorLoading, Loading, useTranslationContext } from "@gnu-taler/web-util/browser";
-import { ArrowDownCircleIcon, ClockIcon } from "@heroicons/react/20/solid";
import { format } from "date-fns";
import { Fragment, VNode, h } from "preact";
import { useState } from "preact/hooks";
-import { NiceForm } from "../NiceForm.js";
-import { FlexibleForm } from "../forms/index.js";
-import { UIFormField } from "../handlers/forms.js";
import { useCaseDetails } from "../hooks/useCaseDetails.js";
import { Pages } from "../pages.js";
import { AmlExchangeBackend } from "../types.js";
+import { ShowConsolidated } from "./ShowConsolidated.js";
-type AmlEvent = AmlFormEvent | KycCollectionEvent | KycExpirationEvent;
+export type AmlEvent = AmlFormEvent | KycCollectionEvent | KycExpirationEvent;
type AmlFormEvent = {
type: "aml-form";
when: AbsoluteTime;
@@ -47,7 +43,7 @@ function selectSooner(a: WithTime, b: WithTime) {
return AbsoluteTime.cmp(a.when, b.when);
}
-function getEventsFromAmlHistory(
+export function getEventsFromAmlHistory(
aml: AmlExchangeBackend.AmlDecisionDetail[],
kyc: AmlExchangeBackend.KycDetail[],
): AmlEvent[] {
@@ -113,12 +109,16 @@ export function CaseDetails({ account }: { account: string }) {
href={Pages.newFormEntry.url({ account })}
class="m-4 block rounded-md w-fit border-0 px-3 py-2 text-center text-sm bg-indigo-700 text-white shadow-sm hover:bg-indigo-700"
>
- New AML form
+ <i18n.Translate>
+ New AML form
+ </i18n.Translate>
</a>
<header class="flex items-center justify-between border-b border-white/5 px-4 py-4 sm:px-6 sm:py-6 lg:px-8">
<h1 class="text-base font-semibold leading-7 text-black">
- Case history
+ <i18n.Translate>
+ Case history
+ </i18n.Translate>
</h1>
</header>
<div class="flow-root">
@@ -187,11 +187,18 @@ export function CaseDetails({ account }: { account: string }) {
}
case "kyc-collection": {
return (
- <ArrowDownCircleIcon class="h-8 w-8 text-green-700" />
+ // <ArrowDownCircleIcon class="h-8 w-8 text-green-700" />
+ <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6">
+ <path stroke-linecap="round" stroke-linejoin="round" d="M9 12.75l3 3m0 0l3-3m-3 3v-7.5M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
+ </svg>
);
}
case "kyc-expiration": {
- return <ClockIcon class="h-8 w-8 text-gray-700" />;
+ // return <ClockIcon class="h-8 w-8 text-gray-700" />;
+ return <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6">
+ <path stroke-linecap="round" stroke-linejoin="round" d="M12 6v6h4.5m4.5 0a9 9 0 11-18 0 9 9 0 0118 0z" />
+ </svg>
+
}
}
})()}
@@ -217,7 +224,7 @@ export function CaseDetails({ account }: { account: string }) {
</ul>
</div>
{selected && <ShowEventDetails event={selected} />}
- {selected && <ShowConsolidated history={events} until={selected} />}
+ {selected && <ShowConsolidated history={events} until={selected.when} />}
</div>
);
}
@@ -226,197 +233,4 @@ function ShowEventDetails({ event }: { event: AmlEvent }): VNode {
return <div>type {event.type}</div>;
}
-function ShowConsolidated({
- history,
- until,
-}: {
- history: AmlEvent[];
- until: AmlEvent;
-}): VNode {
- const cons = getConsolidated(history, until.when);
-
- const form: FlexibleForm<Consolidated> = {
- versionId: "1",
- behavior: (form) => {
- return {
- aml: {
- threshold: {
- hidden: !form.aml
- },
- since: {
- hidden: !form.aml
- },
- state: {
- hidden: !form.aml
- }
- }
- };
- },
- design: [
- {
- title: "AML" as TranslatedString,
- fields: [
- {
- type: "amount",
- props: {
- label: "Threshold" as TranslatedString,
- name: "aml.threshold",
- },
- },
- {
- type: "choiceHorizontal",
- props: {
- label: "State" as TranslatedString,
- name: "aml.state",
- converter: amlStateConverter,
- choices: [
- {
- label: "Frozen" as TranslatedString,
- value: AmlExchangeBackend.AmlState.frozen,
- },
- {
- label: "Pending" as TranslatedString,
- value: AmlExchangeBackend.AmlState.pending,
- },
- {
- label: "Normal" as TranslatedString,
- value: AmlExchangeBackend.AmlState.normal,
- },
- ],
- },
- },
- ],
- },
- Object.entries(cons.kyc).length > 0
- ? {
- title: "KYC" as TranslatedString,
- fields: Object.entries(cons.kyc).map(([key, field]) => {
- const result: UIFormField = {
- type: "text",
- props: {
- label: key as TranslatedString,
- name: `kyc.${key}.value`,
- help: `${field.provider} since ${field.since.t_ms === "never"
- ? "never"
- : format(field.since.t_ms, "dd/MM/yyyy")
- }` as TranslatedString,
- },
- };
- return result;
- }),
- }
- : undefined,
- ],
- };
- return (
- <Fragment>
- <h1 class="text-base font-semibold leading-7 text-black">
- Consolidated information after{" "}
- {until.when.t_ms === "never"
- ? "never"
- : format(until.when.t_ms, "dd MMMM yyyy")}
- </h1>
- <NiceForm
- key={`${String(Date.now())}`}
- form={form}
- initial={cons}
- onUpdate={() => { }}
- />
- </Fragment>
- );
-}
-interface Consolidated {
- aml: {
- state: AmlExchangeBackend.AmlState;
- threshold: AmountJson;
- since: AbsoluteTime;
- };
- kyc: {
- [field: string]: {
- value: any;
- provider: string;
- since: AbsoluteTime;
- };
- };
-}
-
-function getConsolidated(
- history: AmlEvent[],
- when: AbsoluteTime,
-): Consolidated {
- const initial: Consolidated = {
- aml: {
- state: AmlExchangeBackend.AmlState.normal,
- threshold: {
- currency: "ARS",
- value: 1000,
- fraction: 0,
- },
- since: AbsoluteTime.never()
- },
- kyc: {},
- };
- return history.reduce((prev, cur) => {
- if (AbsoluteTime.cmp(when, cur.when) < 0) {
- return prev;
- }
- switch (cur.type) {
- case "kyc-expiration": {
- cur.fields.forEach((field) => {
- delete prev.kyc[field];
- });
- break;
- }
- case "aml-form": {
- prev.aml = {
- since: cur.when,
- state: cur.state,
- threshold: cur.threshold
- }
- break;
- }
- case "kyc-collection": {
- Object.keys(cur.values).forEach((field) => {
- prev.kyc[field] = {
- value: (cur.values as any)[field],
- provider: cur.provider,
- since: cur.when,
- };
- });
- break;
- }
- }
- return prev;
- }, initial);
-}
-
-export const amlStateConverter = {
- toStringUI: stringifyAmlState,
- fromStringUI: parseAmlState,
-};
-
-function stringifyAmlState(s: AmlExchangeBackend.AmlState | undefined): string {
- if (s === undefined) return "";
- switch (s) {
- case AmlExchangeBackend.AmlState.normal:
- return "normal";
- case AmlExchangeBackend.AmlState.pending:
- return "pending";
- case AmlExchangeBackend.AmlState.frozen:
- return "frozen";
- }
-}
-
-function parseAmlState(s: string | undefined): AmlExchangeBackend.AmlState {
- switch (s) {
- case "normal":
- return AmlExchangeBackend.AmlState.normal;
- case "pending":
- return AmlExchangeBackend.AmlState.pending;
- case "frozen":
- return AmlExchangeBackend.AmlState.frozen;
- default:
- throw Error(`unknown AML state: ${s}`);
- }
-}