gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-wallet-core] 06/06: refactoring transaction component to standard


From: gnunet
Subject: [taler-wallet-core] 06/06: refactoring transaction component to standard component with test and examples
Date: Wed, 14 Dec 2022 19:35:51 +0100

This is an automated email from the git hooks/post-receive script.

sebasjm pushed a commit to branch master
in repository wallet-core.

commit 8d8d71807df6b775e5b0335eb1b2526a56d42ac6
Author: Sebastian <sebasjm@gmail.com>
AuthorDate: Wed Dec 14 15:35:28 2022 -0300

    refactoring transaction component to standard component with test and 
examples
---
 packages/demobank-ui/build.mjs                     |  25 ++-
 .../src/components/EmptyComponentExample/index.ts  |  13 +-
 .../src/components/EmptyComponentExample/state.ts  |   4 +-
 .../components/EmptyComponentExample/stories.tsx   |   4 +-
 .../src/components/EmptyComponentExample/views.tsx |  10 +-
 .../index.ts                                       |  29 ++--
 .../src/components/Transactions/state.ts           | 133 ++++++++++++++++
 .../stories.tsx                                    |  22 ++-
 .../src/components/Transactions/test.ts            | 174 +++++++++++++++++++++
 .../src/components/Transactions/views.tsx          |  68 ++++++++
 .../state.ts => index.examples.ts}                 |  10 +-
 .../stories.tsx => endpoints.ts}                   |  24 ++-
 packages/demobank-ui/src/pages/AccountPage.tsx     |   2 +-
 .../demobank-ui/src/pages/PublicHistoriesPage.tsx  |   2 +-
 packages/demobank-ui/src/pages/Transactions.tsx    | 106 -------------
 packages/demobank-ui/src/stories.tsx               |   3 +-
 16 files changed, 473 insertions(+), 156 deletions(-)

diff --git a/packages/demobank-ui/build.mjs b/packages/demobank-ui/build.mjs
index c93b4eb67..f30fe5490 100755
--- a/packages/demobank-ui/build.mjs
+++ b/packages/demobank-ui/build.mjs
@@ -44,7 +44,29 @@ const preactCompatPlugin = {
   },
 };
 
-const entryPoints = ["src/index.tsx", "src/stories.tsx"];
+function getFilesInDirectory(startPath, regex) {
+  if (!fs.existsSync(startPath)) {
+    return;
+  }
+  const files = fs.readdirSync(startPath);
+  const result = files.flatMap(file => {
+    const filename = path.join(startPath, file);
+
+    const stat = fs.lstatSync(filename);
+    if (stat.isDirectory()) {
+      return getFilesInDirectory(filename, regex);
+    }
+    else if (regex.test(filename)) {
+      return filename
+    }
+  }).filter(x => !!x)
+
+  return result
+}
+
+const allTestFiles = getFilesInDirectory(path.join(BASE, 'src'), /.test.ts$/)
+
+const entryPoints = ["src/index.tsx", "src/stories.tsx", ...allTestFiles];
 
 let GIT_ROOT = BASE;
 while (!fs.existsSync(path.join(GIT_ROOT, ".git")) && GIT_ROOT !== "/") {
@@ -128,6 +150,7 @@ export const buildConfig = {
   sourcemap: true,
   jsxFactory: "h",
   jsxFragment: "Fragment",
+  external: ["async_hooks"],
   define: {
     __VERSION__: `"${_package.version}"`,
     __GIT_HASH__: `"${GIT_HASH}"`,
diff --git a/packages/demobank-ui/src/components/EmptyComponentExample/index.ts 
b/packages/demobank-ui/src/components/EmptyComponentExample/index.ts
index 4b7725264..d9f231019 100644
--- a/packages/demobank-ui/src/components/EmptyComponentExample/index.ts
+++ b/packages/demobank-ui/src/components/EmptyComponentExample/index.ts
@@ -15,9 +15,9 @@
  */
 
 import { Loading } from "../../components/Loading.js";
-import { HookError } from "../../hooks/useAsyncAsHook.js";
-import { compose, StateViewMap } from "../../utils/index.js";
-import { wxApi } from "../../wxApi.js";
+import { HookError, utils } from "@gnu-taler/web-util/lib/index.browser";
+//import { compose, StateViewMap } from "../../utils/index.js";
+//import { wxApi } from "../../wxApi.js";
 import { useComponentState } from "./state.js";
 import { LoadingUriView, ReadyView } from "./views.js";
 
@@ -47,14 +47,13 @@ export namespace State {
   }
 }
 
-const viewMapping: StateViewMap<State> = {
+const viewMapping: utils.StateViewMap<State> = {
   loading: Loading,
   "loading-error": LoadingUriView,
   ready: ReadyView,
 };
 
-export const ComponentName = compose(
-  "ComponentName",
-  (p: Props) => useComponentState(p, wxApi),
+export const ComponentName = utils.compose(
+  (p: Props) => useComponentState(p),
   viewMapping,
 );
diff --git a/packages/demobank-ui/src/components/EmptyComponentExample/state.ts 
b/packages/demobank-ui/src/components/EmptyComponentExample/state.ts
index d194b3f97..e147a7ccf 100644
--- a/packages/demobank-ui/src/components/EmptyComponentExample/state.ts
+++ b/packages/demobank-ui/src/components/EmptyComponentExample/state.ts
@@ -14,10 +14,10 @@
  GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
  */
 
-import { wxApi } from "../../wxApi.js";
+// import { wxApi } from "../../wxApi.js";
 import { Props, State } from "./index.js";
 
-export function useComponentState({ p }: Props, api: typeof wxApi): State {
+export function useComponentState({ p }: Props): State {
   return {
     status: "ready",
     error: undefined,
diff --git 
a/packages/demobank-ui/src/components/EmptyComponentExample/stories.tsx 
b/packages/demobank-ui/src/components/EmptyComponentExample/stories.tsx
index 696e424c4..e157e6e6f 100644
--- a/packages/demobank-ui/src/components/EmptyComponentExample/stories.tsx
+++ b/packages/demobank-ui/src/components/EmptyComponentExample/stories.tsx
@@ -19,11 +19,11 @@
  * @author Sebastian Javier Marchano (sebasjm)
  */
 
-import { createExample } from "../../test-utils.js";
+import { tests } from "@gnu-taler/web-util/lib/index.browser";
 import { ReadyView } from "./views.js";
 
 export default {
   title: "example",
 };
 
-export const Ready = createExample(ReadyView, {});
+export const Ready = tests.createExample(ReadyView, {});
diff --git 
a/packages/demobank-ui/src/components/EmptyComponentExample/views.tsx 
b/packages/demobank-ui/src/components/EmptyComponentExample/views.tsx
index 5784a7db5..e125ff415 100644
--- a/packages/demobank-ui/src/components/EmptyComponentExample/views.tsx
+++ b/packages/demobank-ui/src/components/EmptyComponentExample/views.tsx
@@ -15,18 +15,16 @@
  */
 
 import { h, VNode } from "preact";
-import { LoadingError } from "../../components/LoadingError.js";
-import { useTranslationContext } from "../../context/translation.js";
+import { useTranslationContext } from "@gnu-taler/web-util/lib/index.browser";
 import { State } from "./index.js";
 
 export function LoadingUriView({ error }: State.LoadingUriError): VNode {
   const { i18n } = useTranslationContext();
 
   return (
-    <LoadingError
-      title={<i18n.Translate>Could not load</i18n.Translate>}
-      error={error}
-    />
+    <div>
+      <i18n.Translate>Could not load</i18n.Translate>
+    </div>
   );
 }
 
diff --git a/packages/demobank-ui/src/components/EmptyComponentExample/index.ts 
b/packages/demobank-ui/src/components/Transactions/index.ts
similarity index 66%
copy from packages/demobank-ui/src/components/EmptyComponentExample/index.ts
copy to packages/demobank-ui/src/components/Transactions/index.ts
index 4b7725264..618fcfb71 100644
--- a/packages/demobank-ui/src/components/EmptyComponentExample/index.ts
+++ b/packages/demobank-ui/src/components/Transactions/index.ts
@@ -14,15 +14,18 @@
  GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
  */
 
-import { Loading } from "../../components/Loading.js";
-import { HookError } from "../../hooks/useAsyncAsHook.js";
-import { compose, StateViewMap } from "../../utils/index.js";
-import { wxApi } from "../../wxApi.js";
+import { Loading } from "../Loading.js";
+import { HookError, utils } from "@gnu-taler/web-util/lib/index.browser";
+// import { compose, StateViewMap } from "../../utils/index.js";
+// import { wxApi } from "../../wxApi.js";
 import { useComponentState } from "./state.js";
 import { LoadingUriView, ReadyView } from "./views.js";
+import { AbsoluteTime, AmountJson } from "@gnu-taler/taler-util";
 
 export interface Props {
-  p: string;
+  pageNumber: number;
+  accountLabel: string;
+  balanceValue?: string;
 }
 
 export type State = State.Loading | State.LoadingUriError | State.Ready;
@@ -44,17 +47,25 @@ export namespace State {
   export interface Ready extends BaseInfo {
     status: "ready";
     error: undefined;
+    transactions: Transaction[];
   }
 }
 
-const viewMapping: StateViewMap<State> = {
+export interface Transaction {
+  negative: boolean;
+  counterpart: string;
+  when: AbsoluteTime;
+  amount: AmountJson;
+  subject: string;
+}
+
+const viewMapping: utils.StateViewMap<State> = {
   loading: Loading,
   "loading-error": LoadingUriView,
   ready: ReadyView,
 };
 
-export const ComponentName = compose(
-  "ComponentName",
-  (p: Props) => useComponentState(p, wxApi),
+export const Transactions = utils.compose(
+  (p: Props) => useComponentState(p),
   viewMapping,
 );
diff --git a/packages/demobank-ui/src/components/Transactions/state.ts 
b/packages/demobank-ui/src/components/Transactions/state.ts
new file mode 100644
index 000000000..ac76e31e2
--- /dev/null
+++ b/packages/demobank-ui/src/components/Transactions/state.ts
@@ -0,0 +1,133 @@
+/*
+ This file is part of GNU Taler
+ (C) 2022 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 <http://www.gnu.org/licenses/>
+ */
+
+import { AbsoluteTime, Amounts } from "@gnu-taler/taler-util";
+import { parse } from "date-fns";
+import { useEffect } from "preact/hooks";
+import useSWR from "swr";
+import { Props, State } from "./index.js";
+
+export function useComponentState({ accountLabel, pageNumber, balanceValue }: 
Props): State {
+  const { data, error, mutate } = useSWR(
+    `access-api/accounts/${accountLabel}/transactions?page=${pageNumber}`,
+  );
+
+  useEffect(() => {
+    if (balanceValue) {
+      mutate();
+    }
+  }, [balanceValue ?? ""]);
+
+  if (error) {
+    switch (error.status) {
+      case 404:
+        return {
+          status: "loading-error",
+          error: {
+            hasError: true,
+            operational: false,
+            message: `Transactions page ${pageNumber} was not found.`
+          }
+        }
+      case 401:
+        return {
+          status: "loading-error",
+          error: {
+            hasError: true,
+            operational: false,
+            message: "Wrong credentials given."
+          }
+        }
+      default:
+        return {
+          status: "loading-error",
+          error: {
+            hasError: true,
+            operational: false,
+            message: `Transaction page ${pageNumber} could not be retrieved.`
+          } as any
+        }
+    }
+  }
+
+  if (!data) {
+    return {
+      status: "loading",
+      error: undefined
+    }
+  }
+
+
+  const transactions = data.transactions.map((item: unknown) => {
+    if (!item || typeof item !== "object" ||
+      !("direction" in item) ||
+      !("creditorIban" in item) ||
+      !("debtorIban" in item) ||
+      !("date" in item) ||
+      !("subject" in item) ||
+      !("currency" in item) ||
+      !("amount" in item)
+    ) {
+      //not valid
+      return;
+    }
+    const anyItem = item as any;
+    if (
+      !(typeof anyItem.creditorIban === 'string') ||
+      !(typeof anyItem.debtorIban === 'string') ||
+      !(typeof anyItem.date === 'string') ||
+      !(typeof anyItem.subject === 'string') ||
+      !(typeof anyItem.currency === 'string') ||
+      !(typeof anyItem.amount === 'string')
+    ) {
+      return;
+    }
+
+    const negative = anyItem.direction === "DBIT";
+    const counterpart = negative ? anyItem.creditorIban : anyItem.debtorIban;
+    // Pattern:
+    //
+    // DD/MM YYYY subject -5 EUR
+    // DD/MM YYYY subject 5 EUR
+    const dateRegex = /^([0-9]{4})-([0-9]{2})-([0-9]{1,2})/;
+    const dateParse = dateRegex.exec(anyItem.date);
+    const dateStr =
+      dateParse !== null
+        ? `${dateParse[3]}/${dateParse[2]} ${dateParse[1]}`
+        : undefined;
+
+    const date = parse(dateStr ?? "", "dd/MM yyyy", new Date())
+
+    const when: AbsoluteTime = {
+      t_ms: date.getTime()
+    }
+    const amount = 
Amounts.parseOrThrow(`${anyItem.currency}:${anyItem.amount}`);
+    const subject = anyItem.subject;
+    return {
+      negative,
+      counterpart,
+      when,
+      amount,
+      subject,
+    }
+  });
+
+  return {
+    status: "ready",
+    error: undefined,
+    transactions,
+  };
+}
diff --git 
a/packages/demobank-ui/src/components/EmptyComponentExample/stories.tsx 
b/packages/demobank-ui/src/components/Transactions/stories.tsx
similarity index 66%
copy from packages/demobank-ui/src/components/EmptyComponentExample/stories.tsx
copy to packages/demobank-ui/src/components/Transactions/stories.tsx
index 696e424c4..77fdde092 100644
--- a/packages/demobank-ui/src/components/EmptyComponentExample/stories.tsx
+++ b/packages/demobank-ui/src/components/Transactions/stories.tsx
@@ -19,11 +19,27 @@
  * @author Sebastian Javier Marchano (sebasjm)
  */
 
-import { createExample } from "../../test-utils.js";
+import { tests } from "@gnu-taler/web-util/lib/index.browser";
 import { ReadyView } from "./views.js";
 
 export default {
-  title: "example",
+  title: "transaction list",
 };
 
-export const Ready = createExample(ReadyView, {});
+export const Ready = tests.createExample(ReadyView, {
+  transactions: [
+    {
+      amount: {
+        currency: "USD",
+        fraction: 0,
+        value: 1,
+      },
+      counterpart: "ASD",
+      negative: false,
+      subject: "Some",
+      when: {
+        t_ms: new Date().getTime(),
+      },
+    },
+  ],
+});
diff --git a/packages/demobank-ui/src/components/Transactions/test.ts 
b/packages/demobank-ui/src/components/Transactions/test.ts
new file mode 100644
index 000000000..b746f6bb7
--- /dev/null
+++ b/packages/demobank-ui/src/components/Transactions/test.ts
@@ -0,0 +1,174 @@
+/*
+ This file is part of GNU Taler
+ (C) 2022 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 <http://www.gnu.org/licenses/>
+ */
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+import { tests } from "@gnu-taler/web-util/lib/index.browser";
+import { SwrMockEnvironment } from "@gnu-taler/web-util/lib/tests/swr";
+import { expect } from "chai";
+import { TRANSACTION_API_EXAMPLE } from "../../endpoints.js";
+import { Props } from "./index.js";
+import { useComponentState } from "./state.js";
+
+
+describe("Transaction states", () => {
+
+  it("should query backend and render transactions", async () => {
+
+    const env = new SwrMockEnvironment();
+
+    const props: Props = {
+      accountLabel: "myAccount",
+      pageNumber: 0
+    }
+
+    env.addRequestExpectation(TRANSACTION_API_EXAMPLE.LIST_FIRST_PAGE, {
+      response: {
+        "transactions": [
+          {
+            "creditorIban": "DE159593",
+            "creditorBic": "SANDBOXX",
+            "creditorName": "exchange company",
+            "debtorIban": "DE118695",
+            "debtorBic": "SANDBOXX",
+            "debtorName": "Name unknown",
+            "amount": "1",
+            "currency": "KUDOS",
+            "subject": "Taler Withdrawal 
N588V8XE9TR49HKAXFQ20P0EQ0EYW2AC9NNANV8ZP5P59N6N0410",
+            "date": "2022-12-12Z",
+            "uid": "8PPFR9EM",
+            "direction": "DBIT",
+            "pmtInfId": null,
+            "msgId": null
+          },
+          {
+            "creditorIban": "DE159593",
+            "creditorBic": "SANDBOXX",
+            "creditorName": "exchange company",
+            "debtorIban": "DE118695",
+            "debtorBic": "SANDBOXX",
+            "debtorName": "Name unknown",
+            "amount": "5.00",
+            "currency": "KUDOS",
+            "subject": "HNEWWT679TQC5P1BVXJS48FX9NW18FWM6PTK2N80Z8GVT0ACGNK0",
+            "date": "2022-12-07Z",
+            "uid": "7FZJC3RJ",
+            "direction": "DBIT",
+            "pmtInfId": null,
+            "msgId": null
+          },
+          {
+            "creditorIban": "DE118695",
+            "creditorBic": "SANDBOXX",
+            "creditorName": "Name unknown",
+            "debtorIban": "DE579516",
+            "debtorBic": "SANDBOXX",
+            "debtorName": "The Bank",
+            "amount": "100",
+            "currency": "KUDOS",
+            "subject": "Sign-up bonus",
+            "date": "2022-12-07Z",
+            "uid": "I31A06J8",
+            "direction": "CRDT",
+            "pmtInfId": null,
+            "msgId": null
+          }
+        ]
+      }
+    });
+
+    const hookBehavior = await tests.hookBehaveLikeThis(useComponentState, 
props, [
+      ({ status, error }) => {
+
+        expect(status).equals("loading");
+        expect(error).undefined;
+      },
+      ({ status, error }) => {
+
+        expect(status).equals("ready");
+        expect(error).undefined;
+      },
+    ], env.buildTestingContext())
+
+    expect(hookBehavior).deep.eq({ result: "ok" })
+
+    expect(env.assertJustExpectedRequestWereMade()).deep.eq({ result: "ok" })
+  });
+
+  it("should show error message on not found", async () => {
+
+    const env = new SwrMockEnvironment();
+
+    const props: Props = {
+      accountLabel: "myAccount",
+      pageNumber: 0
+    }
+
+    env.addRequestExpectation(TRANSACTION_API_EXAMPLE.LIST_NOT_FOUND, {});
+
+    const hookBehavior = await tests.hookBehaveLikeThis(useComponentState, 
props, [
+      ({ status, error }) => {
+        expect(status).equals("loading");
+        expect(error).undefined;
+      },
+      ({ status, error }) => {
+        expect(status).equals("loading-error");
+        expect(error).deep.eq({
+          hasError: true,
+          operational: false,
+          message: "Transactions page 0 was not found."
+        });
+      },
+    ], env.buildTestingContext())
+
+    expect(hookBehavior).deep.eq({ result: "ok" })
+    expect(env.assertJustExpectedRequestWereMade()).deep.eq({ result: "ok" })
+  });
+
+  it("should show error message on server error", async () => {
+
+    const env = new SwrMockEnvironment(false);
+
+    const props: Props = {
+      accountLabel: "myAccount",
+      pageNumber: 0
+    }
+
+    env.addRequestExpectation(TRANSACTION_API_EXAMPLE.LIST_ERROR, {});
+
+    const hookBehavior = await tests.hookBehaveLikeThis(useComponentState, 
props, [
+      ({ status, error }) => {
+        expect(status).equals("loading");
+        expect(error).undefined;
+      },
+      ({ status, error }) => {
+        expect(status).equals("loading-error");
+        expect(error).deep.equal({
+          hasError: true,
+          operational: false,
+          message: "Transaction page 0 could not be retrieved."
+        });
+      },
+    ], env.buildTestingContext())
+
+    expect(hookBehavior).deep.eq({ result: "ok" })
+    expect(env.assertJustExpectedRequestWereMade()).deep.eq({ result: "ok" })
+  });
+});
+
diff --git a/packages/demobank-ui/src/components/Transactions/views.tsx 
b/packages/demobank-ui/src/components/Transactions/views.tsx
new file mode 100644
index 000000000..b3683b743
--- /dev/null
+++ b/packages/demobank-ui/src/components/Transactions/views.tsx
@@ -0,0 +1,68 @@
+/*
+ This file is part of GNU Taler
+ (C) 2022 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 <http://www.gnu.org/licenses/>
+ */
+
+import { h, VNode } from "preact";
+import { useTranslationContext } from "@gnu-taler/web-util/lib/index.browser";
+import { State } from "./index.js";
+import { format } from "date-fns";
+import { Amounts } from "@gnu-taler/taler-util";
+
+export function LoadingUriView({ error }: State.LoadingUriError): VNode {
+  const { i18n } = useTranslationContext();
+
+  return (
+    <div>
+      <i18n.Translate>Could not load</i18n.Translate>
+    </div>
+  );
+}
+
+export function ReadyView({ transactions }: State.Ready): VNode {
+  const { i18n } = useTranslationContext();
+  return (
+    <div class="results">
+      <table class="pure-table pure-table-striped">
+        <thead>
+          <tr>
+            <th>{i18n.str`Date`}</th>
+            <th>{i18n.str`Amount`}</th>
+            <th>{i18n.str`Counterpart`}</th>
+            <th>{i18n.str`Subject`}</th>
+          </tr>
+        </thead>
+        <tbody>
+          {transactions.map((item, idx) => {
+            return (
+              <tr key={idx}>
+                <td>
+                  {item.when.t_ms === "never"
+                    ? "never"
+                    : format(item.when.t_ms, "dd/MM/yyyy")}
+                </td>
+                <td>
+                  {item.negative ? "-" : ""}
+                  {Amounts.stringifyValue(item.amount)} {item.amount.currency}
+                </td>
+                <td>{item.counterpart}</td>
+                <td>{item.subject}</td>
+              </tr>
+            );
+          })}
+        </tbody>
+      </table>
+    </div>
+  );
+}
diff --git a/packages/demobank-ui/src/components/EmptyComponentExample/state.ts 
b/packages/demobank-ui/src/components/index.examples.ts
similarity index 75%
copy from packages/demobank-ui/src/components/EmptyComponentExample/state.ts
copy to packages/demobank-ui/src/components/index.examples.ts
index d194b3f97..a741b413d 100644
--- a/packages/demobank-ui/src/components/EmptyComponentExample/state.ts
+++ b/packages/demobank-ui/src/components/index.examples.ts
@@ -14,12 +14,4 @@
  GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
  */
 
-import { wxApi } from "../../wxApi.js";
-import { Props, State } from "./index.js";
-
-export function useComponentState({ p }: Props, api: typeof wxApi): State {
-  return {
-    status: "ready",
-    error: undefined,
-  };
-}
+export * as tx from "./Transactions/stories.js";
\ No newline at end of file
diff --git 
a/packages/demobank-ui/src/components/EmptyComponentExample/stories.tsx 
b/packages/demobank-ui/src/endpoints.ts
similarity index 64%
copy from packages/demobank-ui/src/components/EmptyComponentExample/stories.tsx
copy to packages/demobank-ui/src/endpoints.ts
index 696e424c4..0130e94f8 100644
--- a/packages/demobank-ui/src/components/EmptyComponentExample/stories.tsx
+++ b/packages/demobank-ui/src/endpoints.ts
@@ -19,11 +19,19 @@
  * @author Sebastian Javier Marchano (sebasjm)
  */
 
-import { createExample } from "../../test-utils.js";
-import { ReadyView } from "./views.js";
-
-export default {
-  title: "example",
-};
-
-export const Ready = createExample(ReadyView, {});
+export const TRANSACTION_API_EXAMPLE = {
+  LIST_FIRST_PAGE: {
+    method: "get" as const,
+    url: "access-api/accounts/myAccount/transactions?page=0",
+  },
+  LIST_ERROR: {
+    method: "get" as const,
+    url: "access-api/accounts/myAccount/transactions?page=0",
+    code: 500
+  },
+  LIST_NOT_FOUND: {
+    method: "get" as const,
+    url: "access-api/accounts/myAccount/transactions?page=0",
+    code: 404
+  }
+}
\ No newline at end of file
diff --git a/packages/demobank-ui/src/pages/AccountPage.tsx 
b/packages/demobank-ui/src/pages/AccountPage.tsx
index 7ec4d36fb..5dd820b53 100644
--- a/packages/demobank-ui/src/pages/AccountPage.tsx
+++ b/packages/demobank-ui/src/pages/AccountPage.tsx
@@ -27,7 +27,7 @@ import { getIbanFromPayto, prepareHeaders } from 
"../utils.js";
 import { BankFrame } from "./BankFrame.js";
 import { LoginForm } from "./LoginForm.js";
 import { PaymentOptions } from "./PaymentOptions.js";
-import { Transactions } from "./Transactions.js";
+import { Transactions } from "../components/Transactions/index.js";
 import { WithdrawalQRCode } from "./WithdrawalQRCode.js";
 
 export function AccountPage(): VNode {
diff --git a/packages/demobank-ui/src/pages/PublicHistoriesPage.tsx 
b/packages/demobank-ui/src/pages/PublicHistoriesPage.tsx
index be9f4aee1..7bf5c41c7 100644
--- a/packages/demobank-ui/src/pages/PublicHistoriesPage.tsx
+++ b/packages/demobank-ui/src/pages/PublicHistoriesPage.tsx
@@ -24,7 +24,7 @@ import { PageStateType, usePageContext } from 
"../context/pageState.js";
 import { useTranslationContext } from "@gnu-taler/web-util/lib/index.browser";
 import { getBankBackendBaseUrl } from "../utils.js";
 import { BankFrame } from "./BankFrame.js";
-import { Transactions } from "./Transactions.js";
+import { Transactions } from "../components/Transactions/index.js";
 
 const logger = new Logger("PublicHistoriesPage");
 
diff --git a/packages/demobank-ui/src/pages/Transactions.tsx 
b/packages/demobank-ui/src/pages/Transactions.tsx
deleted file mode 100644
index ca88abd4d..000000000
--- a/packages/demobank-ui/src/pages/Transactions.tsx
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- This file is part of GNU Taler
- (C) 2022 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 <http://www.gnu.org/licenses/>
- */
-
-import { Logger } from "@gnu-taler/taler-util";
-import { h, VNode } from "preact";
-import { useEffect } from "preact/hooks";
-import useSWR from "swr";
-import { useTranslationContext } from "@gnu-taler/web-util/lib/index.browser";
-
-const logger = new Logger("Transactions");
-/**
- * Show one page of transactions.
- */
-export function Transactions({
-  pageNumber,
-  accountLabel,
-  balanceValue,
-}: {
-  pageNumber: number;
-  accountLabel: string;
-  balanceValue?: string;
-}): VNode {
-  const { i18n } = useTranslationContext();
-  const { data, error, mutate } = useSWR(
-    `access-api/accounts/${accountLabel}/transactions?page=${pageNumber}`,
-  );
-  useEffect(() => {
-    if (balanceValue) {
-      mutate();
-    }
-  }, [balanceValue ?? ""]);
-  if (typeof error !== "undefined") {
-    logger.error("transactions not found error", error);
-    switch (error.status) {
-      case 404: {
-        return <p>Transactions page {pageNumber} was not found.</p>;
-      }
-      case 401: {
-        return <p>Wrong credentials given.</p>;
-      }
-      default: {
-        return <p>Transaction page {pageNumber} could not be retrieved.</p>;
-      }
-    }
-  }
-  if (!data) {
-    logger.trace(`History data of ${accountLabel} not arrived`);
-    return <p>Transactions page loading...</p>;
-  }
-  logger.trace(`History data of ${accountLabel}`, data);
-  return (
-    <div class="results">
-      <table class="pure-table pure-table-striped">
-        <thead>
-          <tr>
-            <th>{i18n.str`Date`}</th>
-            <th>{i18n.str`Amount`}</th>
-            <th>{i18n.str`Counterpart`}</th>
-            <th>{i18n.str`Subject`}</th>
-          </tr>
-        </thead>
-        <tbody>
-          {data.transactions.map((item: any, idx: number) => {
-            const sign = item.direction == "DBIT" ? "-" : "";
-            const counterpart =
-              item.direction == "DBIT" ? item.creditorIban : item.debtorIban;
-            // Pattern:
-            //
-            // DD/MM YYYY subject -5 EUR
-            // DD/MM YYYY subject 5 EUR
-            const dateRegex = /^([0-9]{4})-([0-9]{2})-([0-9]{1,2})/;
-            const dateParse = dateRegex.exec(item.date);
-            const date =
-              dateParse !== null
-                ? `${dateParse[3]}/${dateParse[2]} ${dateParse[1]}`
-                : "date not found";
-            return (
-              <tr key={idx}>
-                <td>{date}</td>
-                <td>
-                  {sign}
-                  {item.amount} {item.currency}
-                </td>
-                <td>{counterpart}</td>
-                <td>{item.subject}</td>
-              </tr>
-            );
-          })}
-        </tbody>
-      </table>
-    </div>
-  );
-}
diff --git a/packages/demobank-ui/src/stories.tsx 
b/packages/demobank-ui/src/stories.tsx
index 611d63879..a8ebcd867 100644
--- a/packages/demobank-ui/src/stories.tsx
+++ b/packages/demobank-ui/src/stories.tsx
@@ -21,6 +21,7 @@
 import { strings } from "./i18n/strings.js";
 
 import * as pages from "./pages/index.stories.js";
+import * as components from "./components/index.examples.js";
 
 import { renderStories } from "@gnu-taler/web-util/lib/index.browser";
 
@@ -32,7 +33,7 @@ function SortStories(a: any, b: any): number {
 
 function main(): void {
   renderStories(
-    { pages },
+    { pages, components },
     {
       strings,
     },

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]