gnunet-svn
[Top][All Lists]
Advanced

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

[taler-wallet-core] 03/04: fix #8781: min cashout ui


From: gnunet
Subject: [taler-wallet-core] 03/04: fix #8781: min cashout ui
Date: Tue, 07 May 2024 17:14:35 +0200

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

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

commit 7b78c1350cfe49e06ce31ed076f69aa9dfac3490
Author: Sebastian <sebasjm@gmail.com>
AuthorDate: Tue May 7 12:09:48 2024 -0300

    fix #8781: min cashout ui
---
 packages/bank-ui/src/Routing.tsx                   | 10 +++-
 packages/bank-ui/src/pages/LoginForm.tsx           |  4 +-
 .../src/pages/account/CashoutListForAccount.tsx    |  3 ++
 packages/bank-ui/src/pages/admin/AccountForm.tsx   |  1 +
 packages/bank-ui/src/pages/admin/AdminHome.tsx     |  5 +-
 .../bank-ui/src/pages/regional/CreateCashout.tsx   | 53 ++++++++++++++--------
 6 files changed, 51 insertions(+), 25 deletions(-)

diff --git a/packages/bank-ui/src/Routing.tsx b/packages/bank-ui/src/Routing.tsx
index 23635d4cd..380b267a2 100644
--- a/packages/bank-ui/src/Routing.tsx
+++ b/packages/bank-ui/src/Routing.tsx
@@ -31,6 +31,7 @@ import {
   HttpStatusCode,
   TranslatedString,
   assertUnreachable,
+  createRFC8959AccessTokenEncoded
 } from "@gnu-taler/taler-util";
 import { useEffect } from "preact/hooks";
 import { useSessionState } from "./hooks/session.js";
@@ -121,7 +122,7 @@ function PublicRounting({
           refreshable: true,
         });
       if (resp.type === "ok") {
-        onLoggedUser(username, resp.body.access_token);
+        onLoggedUser(username, 
createRFC8959AccessTokenEncoded(resp.body.access_token));
       } else {
         switch (resp.case) {
           case HttpStatusCode.Unauthorized:
@@ -394,6 +395,9 @@ function PrivateRouting({
           routeMyAccountDetails={privatePages.myAccountDetails}
           routeMyAccountPassword={privatePages.myAccountPassword}
           routeConversionConfig={privatePages.conversionConfig}
+          onCashout={() =>
+            navigateTo(privatePages.home.url({}))
+          }
           onAuthorizationRequired={() =>
             navigateTo(privatePages.solveSecondFactor.url({}))
           }
@@ -461,6 +465,9 @@ function PrivateRouting({
           routeMyAccountDetails={privatePages.myAccountDetails}
           routeMyAccountPassword={privatePages.myAccountPassword}
           routeConversionConfig={privatePages.conversionConfig}
+          onCashout={() =>
+            navigateTo(privatePages.home.url({}))
+          }
           onAuthorizationRequired={() =>
             navigateTo(privatePages.solveSecondFactor.url({}))
           }
@@ -515,6 +522,7 @@ function PrivateRouting({
           onAuthorizationRequired={() =>
             navigateTo(privatePages.solveSecondFactor.url({}))
           }
+          onCashout={() => navigateTo(privatePages.home.url({}))}
           routeClose={privatePages.home}
         />
       );
diff --git a/packages/bank-ui/src/pages/LoginForm.tsx 
b/packages/bank-ui/src/pages/LoginForm.tsx
index 2f967895c..600025400 100644
--- a/packages/bank-ui/src/pages/LoginForm.tsx
+++ b/packages/bank-ui/src/pages/LoginForm.tsx
@@ -14,7 +14,7 @@
  GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
  */
 
-import { HttpStatusCode } from "@gnu-taler/taler-util";
+import { HttpStatusCode, createRFC8959AccessTokenEncoded, 
createRFC8959AccessTokenPlain } from "@gnu-taler/taler-util";
 import {
   Button,
   LocalNotificationBanner,
@@ -87,7 +87,7 @@ export function LoginForm({
               refreshable: true,
             }),
           (result) => {
-            session.logIn({ username, token: result.body.access_token });
+            session.logIn({ username, token: 
createRFC8959AccessTokenEncoded(result.body.access_token) });
           },
           (fail) => {
             switch (fail.case) {
diff --git a/packages/bank-ui/src/pages/account/CashoutListForAccount.tsx 
b/packages/bank-ui/src/pages/account/CashoutListForAccount.tsx
index 301978eaa..fd6379895 100644
--- a/packages/bank-ui/src/pages/account/CashoutListForAccount.tsx
+++ b/packages/bank-ui/src/pages/account/CashoutListForAccount.tsx
@@ -25,6 +25,7 @@ interface Props {
   account: string;
   routeClose: RouteDefinition;
   onAuthorizationRequired: () => void;
+  onCashout: () => void;
   routeCashoutDetails: RouteDefinition<{ cid: string }>;
   routeMyAccountDetails: RouteDefinition;
   routeMyAccountDelete: RouteDefinition;
@@ -37,6 +38,7 @@ interface Props {
 export function CashoutListForAccount({
   account,
   onAuthorizationRequired,
+  onCashout,
   routeCreateCashout,
   routeCashoutDetails,
   routeMyAccountCashout,
@@ -76,6 +78,7 @@ export function CashoutListForAccount({
         focus
         routeHere={routeCreateCashout}
         routeClose={routeClose}
+        onCashout={onCashout}
         onAuthorizationRequired={onAuthorizationRequired}
         account={account}
       />
diff --git a/packages/bank-ui/src/pages/admin/AccountForm.tsx 
b/packages/bank-ui/src/pages/admin/AccountForm.tsx
index 21e3e6588..ba5da609f 100644
--- a/packages/bank-ui/src/pages/admin/AccountForm.tsx
+++ b/packages/bank-ui/src/pages/admin/AccountForm.tsx
@@ -213,6 +213,7 @@ export function AccountForm<PurposeType extends keyof 
ChangeByPurposeType>({
             : undefined,
       name: !editableName
         ? undefined // disabled
+        : purpose === "update" && newForm.name === undefined ? undefined // 
the field hasn't been changed
         : !newForm.name
           ? i18n.str`Required`
           : undefined,
diff --git a/packages/bank-ui/src/pages/admin/AdminHome.tsx 
b/packages/bank-ui/src/pages/admin/AdminHome.tsx
index acae09b40..34c121235 100644
--- a/packages/bank-ui/src/pages/admin/AdminHome.tsx
+++ b/packages/bank-ui/src/pages/admin/AdminHome.tsx
@@ -276,10 +276,9 @@ function Metrics({
           name="tabs"
           class="block w-full rounded-md border-gray-300 
focus:border-indigo-500 focus:ring-indigo-500"
           onChange={(e) => {
-            // const op = e.currentTarget.value as typeof metricType
             setMetricType(
-              e.currentTarget
-                .value as unknown as TalerCorebankApi.MonitorTimeframeParam,
+              parseInt(e.currentTarget
+                .value, 10) as TalerCorebankApi.MonitorTimeframeParam,
             );
           }}
         >
diff --git a/packages/bank-ui/src/pages/regional/CreateCashout.tsx 
b/packages/bank-ui/src/pages/regional/CreateCashout.tsx
index 8e54bbd4e..c51b96b8b 100644
--- a/packages/bank-ui/src/pages/regional/CreateCashout.tsx
+++ b/packages/bank-ui/src/pages/regional/CreateCashout.tsx
@@ -59,6 +59,7 @@ interface Props {
   account: string;
   focus?: boolean;
   onAuthorizationRequired: () => void;
+  onCashout: () => void;
   routeClose: RouteDefinition;
   routeHere: RouteDefinition;
 }
@@ -76,6 +77,7 @@ type ErrorFrom<T> = {
 export function CreateCashout({
   account: accountName,
   onAuthorizationRequired,
+  onCashout,
   focus,
   routeHere,
   routeClose,
@@ -93,7 +95,6 @@ export function CreateCashout({
   const {
     lib: { bank: api },
     config,
-    hints,
   } = useBankCoreApiContext();
   const [form, setForm] = useState<Partial<FormType>>({ isDebit: true });
   const [notification, notify, handleError] = useLocalNotification();
@@ -167,13 +168,6 @@ export function CreateCashout({
     );
   }
 
-  const account = {
-    balance: Amounts.parseOrThrow(resultAccount.body.balance.amount),
-    balanceIsDebit:
-      resultAccount.body.balance.credit_debit_indicator == "debit",
-    debitThreshold: Amounts.parseOrThrow(resultAccount.body.debit_threshold),
-  };
-
   const {
     fiat_currency,
     regional_currency,
@@ -182,6 +176,15 @@ export function CreateCashout({
   } = info.body;
   const regionalZero = Amounts.zeroOfCurrency(regional_currency);
   const fiatZero = Amounts.zeroOfCurrency(fiat_currency);
+
+  const account = {
+    balance: Amounts.parseOrThrow(resultAccount.body.balance.amount),
+    balanceIsDebit:
+      resultAccount.body.balance.credit_debit_indicator == "debit",
+    debitThreshold: Amounts.parseOrThrow(resultAccount.body.debit_threshold),
+    minCashout: resultAccount.body.min_cashout === undefined ? regionalZero : 
Amounts.parseOrThrow(resultAccount.body.min_cashout)
+  };
+
   const limit = account.balanceIsDebit
     ? Amounts.sub(account.debitThreshold, account.balance).amount
     : Amounts.add(account.balance, account.debitThreshold).amount;
@@ -241,16 +244,23 @@ export function CreateCashout({
         ? i18n.str`Invalid`
         : Amounts.cmp(limit, calc.debit) === -1
           ? i18n.str`Balance is not enough`
-          : form.isDebit &&
-              Amounts.cmp(inputAmount, conversionInfo.cashout_min_amount) < 1
-            ? i18n.str`Needs to be higher than ${
+          : calculationResult === "amount-is-too-small"
+              ? i18n.str`Amount needs to be higher`
+          : Amounts.cmp(calc.debit, conversionInfo.cashout_min_amount) < 0
+            ? i18n.str`No account can't cashout less than ${
                 Amounts.stringifyValueWithSpec(
                   Amounts.parseOrThrow(conversionInfo.cashout_min_amount),
                   regional_currency_specification,
                 ).normal
               }`
-            : calculationResult === "amount-is-too-small"
-              ? i18n.str`Amount needs to be higher`
+              : Amounts.cmp(calc.debit, account.minCashout) < 0
+              ? i18n.str`Your account can't cashout less than ${
+                  Amounts.stringifyValueWithSpec(
+                    Amounts.parseOrThrow(account.minCashout),
+                    regional_currency_specification,
+                  ).normal
+                }`
+              
               : Amounts.isZero(calc.credit)
                 ? i18n.str`The total transfer at destination will be zero`
                 : undefined,
@@ -260,21 +270,17 @@ export function CreateCashout({
   async function createCashout() {
     const request_uid = encodeCrock(getRandomBytes(32));
     await handleError(async () => {
-      // new cashout api doesn't require channel
-      const validChannel =
-        config.supported_tan_channels.length === 0 || form.channel;
-
-      if (!creds || !form.subject || !validChannel) return;
+      if (!creds || !form.subject) return;
       const request = {
         request_uid,
         amount_credit: Amounts.stringify(calc.credit),
         amount_debit: Amounts.stringify(calc.debit),
         subject: form.subject,
-        tan_channel: form.channel,
       };
       const resp = await api.createCashout(creds, request);
       if (resp.type === "ok") {
         notifyInfo(i18n.str`Cashout created`);
+        onCashout();
       } else {
         switch (resp.case) {
           case HttpStatusCode.Accepted: {
@@ -335,6 +341,15 @@ export function CreateCashout({
               debug: resp.detail,
               when: AbsoluteTime.now(),
             });
+          case TalerErrorCode.BANK_CONVERSION_AMOUNT_TO_SMALL:
+            return notify({
+              type: "error",
+              title: i18n.str`The amount is less than the minimum allowed.`,
+              description: resp.detail.hint as TranslatedString,
+              debug: resp.detail,
+              when: AbsoluteTime.now(),
+            });
+
           case TalerErrorCode.BANK_TAN_CHANNEL_SCRIPT_FAILED:
             return notify({
               type: "error",

-- 
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]