aboutsummaryrefslogtreecommitdiff
path: root/packages/aml-backoffice-ui/src/pages
diff options
context:
space:
mode:
Diffstat (limited to 'packages/aml-backoffice-ui/src/pages')
-rw-r--r--packages/aml-backoffice-ui/src/pages/AntiMoneyLaunderingForm.tsx6
-rw-r--r--packages/aml-backoffice-ui/src/pages/CaseDetails.tsx45
-rw-r--r--packages/aml-backoffice-ui/src/pages/Cases.tsx204
-rw-r--r--packages/aml-backoffice-ui/src/pages/NewFormEntry.tsx4
-rw-r--r--packages/aml-backoffice-ui/src/pages/UnlockAccount.tsx3
5 files changed, 140 insertions, 122 deletions
diff --git a/packages/aml-backoffice-ui/src/pages/AntiMoneyLaunderingForm.tsx b/packages/aml-backoffice-ui/src/pages/AntiMoneyLaunderingForm.tsx
index 713c0d7c1..c3fb7dafe 100644
--- a/packages/aml-backoffice-ui/src/pages/AntiMoneyLaunderingForm.tsx
+++ b/packages/aml-backoffice-ui/src/pages/AntiMoneyLaunderingForm.tsx
@@ -11,8 +11,8 @@ import { v1 as form_902_9e_v1 } from "../forms/902_9e.js";
import { v1 as simplest } from "../forms/simplest.js";
import { DocumentDuplicateIcon } from "@heroicons/react/24/solid";
import { AbsoluteTime } from "@gnu-taler/taler-util";
-import { AmlState } from "../types.js";
import { AmountJson, Amounts } from "@gnu-taler/taler-util";
+import { AmlExchangeBackend } from "../types.js";
export function AntiMoneyLaunderingForm({ number }: { number?: string }) {
const selectedForm = Number.parseInt(number ?? "0", 10);
@@ -28,7 +28,7 @@ export function AntiMoneyLaunderingForm({ number }: { number?: string }) {
<NiceForm
initial={storedValue}
form={showingFrom({
- state: AmlState.pending,
+ state: AmlExchangeBackend.AmlState.pending,
threshold: Amounts.parseOrThrow("USD:10"),
})}
onUpdate={() => {}}
@@ -37,7 +37,7 @@ export function AntiMoneyLaunderingForm({ number }: { number?: string }) {
}
export interface State {
- state: AmlState;
+ state: AmlExchangeBackend.AmlState;
threshold: AmountJson;
}
diff --git a/packages/aml-backoffice-ui/src/pages/CaseDetails.tsx b/packages/aml-backoffice-ui/src/pages/CaseDetails.tsx
index e5fb8eaba..d02d8b395 100644
--- a/packages/aml-backoffice-ui/src/pages/CaseDetails.tsx
+++ b/packages/aml-backoffice-ui/src/pages/CaseDetails.tsx
@@ -1,11 +1,5 @@
import { Fragment, VNode, h } from "preact";
import {
- AmlDecisionDetail,
- AmlDecisionDetails,
- AmlState,
- KycDetail,
-} from "../types.js";
-import {
AbsoluteTime,
AmountJson,
Amounts,
@@ -18,8 +12,9 @@ import { NiceForm } from "../NiceForm.js";
import { FlexibleForm } from "../forms/index.js";
import { UIFormField } from "../handlers/forms.js";
import { Pages } from "../pages.js";
+import { AmlExchangeBackend } from "../types.js";
-const response: AmlDecisionDetails = {
+const response: AmlExchangeBackend.AmlDecisionDetails = {
aml_history: [
{
justification: "Lack of documentation",
@@ -81,7 +76,7 @@ type AmlFormEvent = {
type: "aml-form";
when: AbsoluteTime;
title: TranslatedString;
- state: AmlState;
+ state: AmlExchangeBackend.AmlState;
threshold: AmountJson;
};
type KycCollectionEvent = {
@@ -105,8 +100,8 @@ function selectSooner(a: WithTime, b: WithTime) {
}
function getEventsFromAmlHistory(
- aml: AmlDecisionDetail[],
- kyc: KycDetail[],
+ aml: AmlExchangeBackend.AmlDecisionDetail[],
+ kyc: AmlExchangeBackend.KycDetail[],
): AmlEvent[] {
const ae: AmlEvent[] = aml.map((a) => {
return {
@@ -187,7 +182,7 @@ export function CaseDetails({ account }: { account?: string }) {
switch (e.type) {
case "aml-form": {
switch (e.state) {
- case AmlState.normal: {
+ case AmlExchangeBackend.AmlState.normal: {
return (
<div>
<span class="inline-flex items-center rounded-md bg-green-50 px-2 py-1 text-xs font-medium text-green-700 ring-1 ring-inset ring-green-600/20">
@@ -200,7 +195,7 @@ export function CaseDetails({ account }: { account?: string }) {
</div>
);
}
- case AmlState.pending: {
+ case AmlExchangeBackend.AmlState.pending: {
return (
<div>
<span class="inline-flex items-center rounded-md bg-yellow-50 px-2 py-1 text-xs font-medium text-yellow-700 ring-1 ring-inset ring-green-600/20">
@@ -213,7 +208,7 @@ export function CaseDetails({ account }: { account?: string }) {
</div>
);
}
- case AmlState.frozen: {
+ case AmlExchangeBackend.AmlState.frozen: {
return (
<div>
<span class="inline-flex items-center rounded-md bg-red-50 px-2 py-1 text-xs font-medium text-red-700 ring-1 ring-inset ring-green-600/20">
@@ -304,15 +299,15 @@ function ShowConsolidated({
choices: [
{
label: "Frozen" as TranslatedString,
- value: AmlState.frozen,
+ value: AmlExchangeBackend.AmlState.frozen,
},
{
label: "Pending" as TranslatedString,
- value: AmlState.pending,
+ value: AmlExchangeBackend.AmlState.pending,
},
{
label: "Normal" as TranslatedString,
- value: AmlState.normal,
+ value: AmlExchangeBackend.AmlState.normal,
},
],
},
@@ -361,7 +356,7 @@ function ShowConsolidated({
interface Consolidated {
aml: {
- state?: AmlState;
+ state?: AmlExchangeBackend.AmlState;
threshold?: AmountJson;
since: AbsoluteTime;
};
@@ -421,26 +416,26 @@ export const amlStateConverter = {
fromStringUI: parseAmlState,
};
-function stringifyAmlState(s: AmlState | undefined): string {
+function stringifyAmlState(s: AmlExchangeBackend.AmlState | undefined): string {
if (s === undefined) return "";
switch (s) {
- case AmlState.normal:
+ case AmlExchangeBackend.AmlState.normal:
return "normal";
- case AmlState.pending:
+ case AmlExchangeBackend.AmlState.pending:
return "pending";
- case AmlState.frozen:
+ case AmlExchangeBackend.AmlState.frozen:
return "frozen";
}
}
-function parseAmlState(s: string | undefined): AmlState {
+function parseAmlState(s: string | undefined): AmlExchangeBackend.AmlState {
switch (s) {
case "normal":
- return AmlState.normal;
+ return AmlExchangeBackend.AmlState.normal;
case "pending":
- return AmlState.pending;
+ return AmlExchangeBackend.AmlState.pending;
case "frozen":
- return AmlState.frozen;
+ return AmlExchangeBackend.AmlState.frozen;
default:
throw Error(`unknown AML state: ${s}`);
}
diff --git a/packages/aml-backoffice-ui/src/pages/Cases.tsx b/packages/aml-backoffice-ui/src/pages/Cases.tsx
index 28b9d2a88..d96e7a90c 100644
--- a/packages/aml-backoffice-ui/src/pages/Cases.tsx
+++ b/packages/aml-backoffice-ui/src/pages/Cases.tsx
@@ -1,15 +1,18 @@
-import { VNode, h } from "preact";
-import { Pages } from "../pages.js";
-import { AmlRecords, AmlState } from "../types.js";
-import { InputChoiceHorizontal } from "../handlers/InputChoiceHorizontal.js";
-import { createNewForm } from "../handlers/forms.js";
import { TranslatedString } from "@gnu-taler/taler-util";
-import { amlStateConverter as amlStateConverter } from "./CaseDetails.js";
+import { VNode, h } from "preact";
import { useState } from "preact/hooks";
-import { HandleAccountNotReady } from "./HandleAccountNotReady.js";
+import { createNewForm } from "../handlers/forms.js";
+import { useCases } from "../hooks/useCases.js";
import { useOfficer } from "../hooks/useOfficer.js";
+import { Pages } from "../pages.js";
+import { AmlExchangeBackend } from "../types.js";
+import { amlStateConverter } from "./CaseDetails.js";
+import { HandleAccountNotReady } from "./HandleAccountNotReady.js";
+import { buildQuerySignature } from "../account.js";
+import { handleNotOkResult } from "../utils/errors.js";
+import { useTranslationContext } from "@gnu-taler/web-util/browser";
-const response: AmlRecords = {
+const response: AmlExchangeBackend.AmlRecords = {
records: [
{
current_state: 0,
@@ -56,7 +59,7 @@ const response: AmlRecords = {
function doFilter(
list: typeof response.records,
- filter: AmlState | undefined,
+ filter: AmlExchangeBackend.AmlState | undefined,
): typeof response.records {
if (filter === undefined) return list;
return list.filter((r) => r.current_state === filter);
@@ -64,14 +67,27 @@ function doFilter(
export function Cases() {
const officer = useOfficer();
+ const { i18n } = useTranslationContext();
if (officer.state !== "ready") {
return <HandleAccountNotReady officer={officer} />;
}
const form = createNewForm<{
- state: AmlState;
+ state: AmlExchangeBackend.AmlState;
}>();
- const initial = { state: AmlState.pending };
- const [list, setList] = useState(doFilter(response.records, initial.state));
+
+ const signature =
+ officer.state === "ready"
+ ? buildQuerySignature(officer.account.signingKey)
+ : undefined;
+
+ const initial = AmlExchangeBackend.AmlState.pending;
+ const [stateFilter, setStateFilter] = useState(initial);
+ const list = useCases(officer.account.accountId, stateFilter, signature);
+
+ if (!list.ok && !list.loading) {
+ return handleNotOkResult(i18n)(list);
+ }
+
return (
<div>
<div class="px-4 sm:px-6 lg:px-8">
@@ -85,9 +101,9 @@ export function Cases() {
</p>
</div>
<form.Provider
- initialValue={initial}
+ initialValue={{ state: stateFilter }}
onUpdate={(v) => {
- setList(doFilter(response.records, v.state));
+ setStateFilter(v.state ?? initial);
}}
onSubmit={(v) => {}}
>
@@ -98,15 +114,15 @@ export function Cases() {
choices={[
{
label: "Pending" as TranslatedString,
- value: AmlState.pending,
+ value: AmlExchangeBackend.AmlState.pending,
},
{
label: "Frozen" as TranslatedString,
- value: AmlState.frozen,
+ value: AmlExchangeBackend.AmlState.frozen,
},
{
label: "Normal" as TranslatedString,
- value: AmlState.normal,
+ value: AmlExchangeBackend.AmlState.normal,
},
]}
/>
@@ -114,82 +130,86 @@ export function Cases() {
</div>
<div class="mt-8 flow-root">
<div class="-mx-4 -my-2 overflow-x-auto sm:-mx-6 lg:-mx-8">
- <div class="inline-block min-w-full py-2 align-middle sm:px-6 lg:px-8">
- <Pagination />
- <table class="min-w-full divide-y divide-gray-300">
- <thead>
- <tr>
- <th
- scope="col"
- class="px-3 py-3.5 text-left text-sm font-semibold text-gray-900"
- >
- Account Id
- </th>
- <th
- scope="col"
- class="px-3 py-3.5 text-left text-sm font-semibold text-gray-900"
- >
- Status
- </th>
- <th
- scope="col"
- class="px-3 py-3.5 text-left text-sm font-semibold text-gray-900"
- >
- Threshold
- </th>
- </tr>
- </thead>
- <tbody class="divide-y divide-gray-200 bg-white">
- {list.map((r) => {
- return (
- <tr class="hover:bg-gray-100 ">
- <td class="whitespace-nowrap px-3 py-5 text-sm text-gray-500 ">
- <div class="text-gray-900">
- <a
- href={Pages.details.url({ account: r.h_payto })}
- class="text-indigo-600 hover:text-indigo-900"
- >
- {r.h_payto}
- </a>
- </div>
- </td>
- <td class="whitespace-nowrap px-3 py-5 text-sm text-gray-500">
- {((state: AmlState): VNode => {
- switch (state) {
- case AmlState.normal: {
- return (
- <span class="inline-flex items-center rounded-md bg-green-50 px-2 py-1 text-xs font-medium text-green-700 ring-1 ring-inset ring-green-600/20">
- Normal
- </span>
- );
- }
- case AmlState.pending: {
- return (
- <span class="inline-flex items-center rounded-md bg-yellow-50 px-2 py-1 text-xs font-medium text-yellow-700 ring-1 ring-inset ring-green-600/20">
- Pending
- </span>
- );
- }
- case AmlState.frozen: {
- return (
- <span class="inline-flex items-center rounded-md bg-red-50 px-2 py-1 text-xs font-medium text-red-700 ring-1 ring-inset ring-green-600/20">
- Frozen
- </span>
- );
+ {!list.data.records.length ? (
+ <div>empty result </div>
+ ) : (
+ <div class="inline-block min-w-full py-2 align-middle sm:px-6 lg:px-8">
+ <Pagination />
+ <table class="min-w-full divide-y divide-gray-300">
+ <thead>
+ <tr>
+ <th
+ scope="col"
+ class="px-3 py-3.5 text-left text-sm font-semibold text-gray-900"
+ >
+ Account Id
+ </th>
+ <th
+ scope="col"
+ class="px-3 py-3.5 text-left text-sm font-semibold text-gray-900"
+ >
+ Status
+ </th>
+ <th
+ scope="col"
+ class="px-3 py-3.5 text-left text-sm font-semibold text-gray-900"
+ >
+ Threshold
+ </th>
+ </tr>
+ </thead>
+ <tbody class="divide-y divide-gray-200 bg-white">
+ {list.data.records.map((r) => {
+ return (
+ <tr class="hover:bg-gray-100 ">
+ <td class="whitespace-nowrap px-3 py-5 text-sm text-gray-500 ">
+ <div class="text-gray-900">
+ <a
+ href={Pages.details.url({ account: r.h_payto })}
+ class="text-indigo-600 hover:text-indigo-900"
+ >
+ {r.h_payto}
+ </a>
+ </div>
+ </td>
+ <td class="whitespace-nowrap px-3 py-5 text-sm text-gray-500">
+ {((state: AmlExchangeBackend.AmlState): VNode => {
+ switch (state) {
+ case AmlExchangeBackend.AmlState.normal: {
+ return (
+ <span class="inline-flex items-center rounded-md bg-green-50 px-2 py-1 text-xs font-medium text-green-700 ring-1 ring-inset ring-green-600/20">
+ Normal
+ </span>
+ );
+ }
+ case AmlExchangeBackend.AmlState.pending: {
+ return (
+ <span class="inline-flex items-center rounded-md bg-yellow-50 px-2 py-1 text-xs font-medium text-yellow-700 ring-1 ring-inset ring-green-600/20">
+ Pending
+ </span>
+ );
+ }
+ case AmlExchangeBackend.AmlState.frozen: {
+ return (
+ <span class="inline-flex items-center rounded-md bg-red-50 px-2 py-1 text-xs font-medium text-red-700 ring-1 ring-inset ring-green-600/20">
+ Frozen
+ </span>
+ );
+ }
}
- }
- })(r.current_state)}
- </td>
- <td class="whitespace-nowrap px-3 py-5 text-sm text-gray-900">
- {r.threshold}
- </td>
- </tr>
- );
- })}
- </tbody>
- </table>
- <Pagination />
- </div>
+ })(r.current_state)}
+ </td>
+ <td class="whitespace-nowrap px-3 py-5 text-sm text-gray-900">
+ {r.threshold}
+ </td>
+ </tr>
+ );
+ })}
+ </tbody>
+ </table>
+ <Pagination />
+ </div>
+ )}
</div>
</div>
</div>
diff --git a/packages/aml-backoffice-ui/src/pages/NewFormEntry.tsx b/packages/aml-backoffice-ui/src/pages/NewFormEntry.tsx
index fdb255701..bbd04daee 100644
--- a/packages/aml-backoffice-ui/src/pages/NewFormEntry.tsx
+++ b/packages/aml-backoffice-ui/src/pages/NewFormEntry.tsx
@@ -2,8 +2,8 @@ import { VNode, h } from "preact";
import { allForms } from "./AntiMoneyLaunderingForm.js";
import { Pages } from "../pages.js";
import { NiceForm } from "../NiceForm.js";
-import { AmlState } from "../types.js";
import { AbsoluteTime, Amounts } from "@gnu-taler/taler-util";
+import { AmlExchangeBackend } from "../types.js";
export function NewFormEntry({
account,
@@ -27,7 +27,7 @@ export function NewFormEntry({
const initial = {
fullName: "loggedIn_user_fullname",
when: AbsoluteTime.now(),
- state: AmlState.pending,
+ state: AmlExchangeBackend.AmlState.pending,
threshold: Amounts.parseOrThrow("USD:10"),
};
return (
diff --git a/packages/aml-backoffice-ui/src/pages/UnlockAccount.tsx b/packages/aml-backoffice-ui/src/pages/UnlockAccount.tsx
index 2ebac0718..39f8addd3 100644
--- a/packages/aml-backoffice-ui/src/pages/UnlockAccount.tsx
+++ b/packages/aml-backoffice-ui/src/pages/UnlockAccount.tsx
@@ -30,6 +30,9 @@ export function UnlockAccount({
<div class="mt-10 sm:mx-auto sm:w-full sm:max-w-[480px] ">
<div class="bg-gray-100 px-6 py-6 shadow sm:rounded-lg sm:px-12">
<Form.Provider
+ initialValue={{
+ password: "welcometo.5146",
+ }}
onSubmit={async (v) => {
try {
await onAccountUnlocked(v.password!);