import { AbsoluteTime, AmountJson, Amounts, TalerError, TranslatedString, assertUnreachable } from "@gnu-taler/taler-util"; import { ErrorLoading, Loading, useTranslationContext } from "@gnu-taler/web-util/browser"; import { format } from "date-fns"; import { Fragment, VNode, h } from "preact"; import { useState } from "preact/hooks"; import { useCaseDetails } from "../hooks/useCaseDetails.js"; import { Pages } from "../pages.js"; import { AmlExchangeBackend } from "../types.js"; import { ShowConsolidated } from "./ShowConsolidated.js"; export type AmlEvent = AmlFormEvent | KycCollectionEvent | KycExpirationEvent; type AmlFormEvent = { type: "aml-form"; when: AbsoluteTime; title: TranslatedString; state: AmlExchangeBackend.AmlState; threshold: AmountJson; }; type KycCollectionEvent = { type: "kyc-collection"; when: AbsoluteTime; title: TranslatedString; values: object; provider: string; }; type KycExpirationEvent = { type: "kyc-expiration"; when: AbsoluteTime; title: TranslatedString; fields: string[]; }; type WithTime = { when: AbsoluteTime }; function selectSooner(a: WithTime, b: WithTime) { return AbsoluteTime.cmp(a.when, b.when); } export function getEventsFromAmlHistory( aml: AmlExchangeBackend.AmlDecisionDetail[], kyc: AmlExchangeBackend.KycDetail[], ): AmlEvent[] { const ae: AmlEvent[] = aml.map((a) => { return { type: "aml-form", state: a.new_state, threshold: Amounts.parseOrThrow(a.new_threshold), title: a.justification as TranslatedString, when: { t_ms: a.decision_time.t_s === "never" ? "never" : a.decision_time.t_s * 1000, }, } as AmlEvent; }); const ke = kyc.reduce((prev, k) => { prev.push({ type: "kyc-collection", title: "collection" as TranslatedString, when: AbsoluteTime.fromProtocolTimestamp(k.collection_time), values: !k.attributes ? {} : k.attributes, provider: k.provider_section, }); prev.push({ type: "kyc-expiration", title: "expiration" as TranslatedString, when: AbsoluteTime.fromProtocolTimestamp(k.expiration_time), fields: !k.attributes ? [] : Object.keys(k.attributes), }); return prev; }, [] as AmlEvent[]); return ae.concat(ke).sort(selectSooner); } export function CaseDetails({ account }: { account: string }) { const [selected, setSelected] = useState(undefined); const { i18n } = useTranslationContext(); const details = useCaseDetails(account) if (!details) { return } if (details instanceof TalerError) { return } if (details.type === "fail") { switch (details.case) { case "unauthorized": case "officer-not-found": case "officer-disabled": return
default: assertUnreachable(details) } } const { aml_history, kyc_attributes } = details.body const events = getEventsFromAmlHistory(aml_history, kyc_attributes); return (
New AML form

Case history

    {events.map((e, idx) => { const isLast = events.length - 1 === idx; return (
  • { setSelected(e); }} >
    {!isLast ? ( ) : undefined}
    {(() => { switch (e.type) { case "aml-form": { switch (e.state) { case AmlExchangeBackend.AmlState.normal: { return (
    Normal {e.threshold.currency}{" "} {Amounts.stringifyValue(e.threshold)}
    ); } case AmlExchangeBackend.AmlState.pending: { return (
    Pending {e.threshold.currency}{" "} {Amounts.stringifyValue(e.threshold)}
    ); } case AmlExchangeBackend.AmlState.frozen: { return (
    Frozen {e.threshold.currency}{" "} {Amounts.stringifyValue(e.threshold)}
    ); } } } case "kyc-collection": { return ( // ); } case "kyc-expiration": { // return ; return } } })()}

    {e.title}

    {e.when.t_ms === "never" ? ( "never" ) : ( )}
  • ); })}
{selected && } {selected && }
); } function ShowEventDetails({ event }: { event: AmlEvent }): VNode { return
type {event.type}
; }