diff options
Diffstat (limited to 'packages/bank-ui/src')
-rw-r--r-- | packages/bank-ui/src/hooks/preferences.ts | 11 | ||||
-rw-r--r-- | packages/bank-ui/src/pages/OperationState/state.ts | 12 | ||||
-rw-r--r-- | packages/bank-ui/src/pages/PaytoWireTransferForm.tsx | 28 | ||||
-rw-r--r-- | packages/bank-ui/src/pages/WalletWithdrawForm.tsx | 20 | ||||
-rw-r--r-- | packages/bank-ui/src/settings.json | 2 | ||||
-rw-r--r-- | packages/bank-ui/src/settings.ts | 16 |
6 files changed, 57 insertions, 32 deletions
diff --git a/packages/bank-ui/src/hooks/preferences.ts b/packages/bank-ui/src/hooks/preferences.ts index 9c60456c7..4cb5e6a95 100644 --- a/packages/bank-ui/src/hooks/preferences.ts +++ b/packages/bank-ui/src/hooks/preferences.ts @@ -31,8 +31,6 @@ interface Preferences { showWithdrawalSuccess: boolean; showDemoDescription: boolean; showInstallWallet: boolean; - maxWithdrawalAmount: number; - fastWithdrawal: boolean; showDebugInfo: boolean; } @@ -41,17 +39,13 @@ export const codecForPreferences = (): Codec<Preferences> => .property("showWithdrawalSuccess", codecForBoolean()) .property("showDemoDescription", codecForBoolean()) .property("showInstallWallet", codecForBoolean()) - .property("fastWithdrawal", codecForBoolean()) .property("showDebugInfo", codecForBoolean()) - .property("maxWithdrawalAmount", codecForNumber()) .build("Settings"); const defaultPreferences: Preferences = { showWithdrawalSuccess: true, showDemoDescription: true, showInstallWallet: true, - maxWithdrawalAmount: 25, - fastWithdrawal: false, showDebugInfo: false, }; @@ -82,7 +76,6 @@ export function usePreferences(): [ export function getAllBooleanPreferences(): Array<keyof Preferences> { return [ - "fastWithdrawal", "showDebugInfo", "showDemoDescription", "showInstallWallet", @@ -95,16 +88,12 @@ export function getLabelForPreferences( i18n: ReturnType<typeof useTranslationContext>["i18n"], ): TranslatedString { switch (k) { - case "maxWithdrawalAmount": - return i18n.str`Max withdrawal amount`; case "showWithdrawalSuccess": return i18n.str`Show withdrawal confirmation`; case "showDemoDescription": return i18n.str`Show demo description`; case "showInstallWallet": return i18n.str`Show install wallet first`; - case "fastWithdrawal": - return i18n.str`Set the withdrawal amount in the wallet`; case "showDebugInfo": return i18n.str`Show debug info`; } diff --git a/packages/bank-ui/src/pages/OperationState/state.ts b/packages/bank-ui/src/pages/OperationState/state.ts index 32d4fea7a..5544c4e23 100644 --- a/packages/bank-ui/src/pages/OperationState/state.ts +++ b/packages/bank-ui/src/pages/OperationState/state.ts @@ -34,6 +34,7 @@ import { useSessionState } from "../../hooks/session.js"; import { useBankState } from "../../hooks/bank-state.js"; import { usePreferences } from "../../hooks/preferences.js"; import { Props, State } from "./index.js"; +import { useSettingsContext } from "../../context/settings.js"; export function useComponentState({ currency, @@ -42,7 +43,8 @@ export function useComponentState({ routeHere, onAuthorizationRequired, }: Props): utils.RecursiveState<State> { - const [settings] = usePreferences(); + const [preference] = usePreferences(); + const settings = useSettingsContext(); const [bankState, updateBankState] = useBankState(); const { state: credentials } = useSessionState(); const creds = credentials.status !== "loggedIn" ? undefined : credentials; @@ -53,14 +55,14 @@ export function useComponentState({ const [failure, setFailure] = useState< TalerCoreBankErrorsByMethod<"createWithdrawal"> | undefined >(); - const amount = settings.maxWithdrawalAmount; + const amount = settings.defaultSuggestedAmount; async function doSilentStart() { // FIXME: if amount is not enough use balance const parsedAmount = Amounts.parseOrThrow(`${currency}:${amount}`); if (!creds) return; const params: TalerCorebankApi.BankAccountCreateWithdrawalRequest = - settings.fastWithdrawal + settings.fastWithdrawalForm ? { suggested_amount: Amounts.stringify(parsedAmount), } @@ -81,7 +83,7 @@ export function useComponentState({ if (withdrawalOperationId === undefined) { doSilentStart(); } - }, [settings.fastWithdrawal, amount]); + }, [settings.fastWithdrawalForm, amount]); if (failure) { return { @@ -182,7 +184,7 @@ export function useComponentState({ } if (data.status === "confirmed") { - if (!settings.showWithdrawalSuccess) { + if (!preference.showWithdrawalSuccess) { updateBankState("currentWithdrawalOperationId", undefined); // onClose() } diff --git a/packages/bank-ui/src/pages/PaytoWireTransferForm.tsx b/packages/bank-ui/src/pages/PaytoWireTransferForm.tsx index 90b41d331..0fb8c0ac1 100644 --- a/packages/bank-ui/src/pages/PaytoWireTransferForm.tsx +++ b/packages/bank-ui/src/pages/PaytoWireTransferForm.tsx @@ -79,6 +79,7 @@ export function PaytoWireTransferForm({ routeHere, onAuthorizationRequired, limit, + balance, }: Props): VNode { const [inputType, setInputType] = useState<"form" | "payto" | "qr">("form"); const isRawPayto = inputType !== "form"; @@ -116,6 +117,11 @@ export function PaytoWireTransferForm({ ? Amounts.zeroOfCurrency(config.currency) : Amounts.parseOrThrow(config.wire_transfer_fees); + const limitWithFee = + Amounts.cmp(limit, wireFee) === 1 + ? Amounts.sub(limit, wireFee).amount + : Amounts.zeroOfAmount(limit); + const errorsWire = undefinedIfEmpty({ account: !account ? i18n.str`Required` @@ -129,7 +135,7 @@ export function PaytoWireTransferForm({ ? i18n.str`Required` : !parsedAmount ? i18n.str`Not valid` - : validateAmount(parsedAmount, limit, wireFee, i18n), + : validateAmount(parsedAmount, limitWithFee, i18n), }); const parsed = !rawPaytoInput ? undefined : parsePaytoUri(rawPaytoInput); @@ -139,7 +145,7 @@ export function PaytoWireTransferForm({ ? i18n.str`Required` : !parsed ? i18n.str`Does not follow the pattern` - : validateRawPayto(parsed, limit, wireFee, url.host, i18n, paytoType), + : validateRawPayto(parsed, limitWithFee, url.host, i18n, paytoType), }); async function doSend() { @@ -627,6 +633,17 @@ export function PaytoWireTransferForm({ </div> </div> )} + {Amounts.cmp(limitWithFee, balance) > 0 ? ( + <p class="mt-2 text-sm text-gray-900"> + <i18n.Translate> + You can transfer{" "} + <RenderAmount + value={limitWithFee} + spec={config.currency_specification} + /> + </i18n.Translate> + </p> + ) : undefined} </div> {Amounts.isZero(wireFee) ? undefined : ( <div class="px-4 my-4"> @@ -800,7 +817,6 @@ export function RenderAmount({ function validateRawPayto( parsed: PaytoUri, limit: AmountJson, - fee: AmountJson, host: string, i18n: InternationalizationAPI, type: "iban" | "x-taler-bank", @@ -844,7 +860,7 @@ function validateRawPayto( if (!amount) { return i18n.str`The "amount" parameter is not valid`; } - result = validateAmount(amount, limit, fee, i18n); + result = validateAmount(amount, limit, i18n); if (result) return result; if (!parsed.params.message) { @@ -860,7 +876,6 @@ function validateRawPayto( function validateAmount( amount: AmountJson, limit: AmountJson, - fee: AmountJson, i18n: InternationalizationAPI, ): TranslatedString | undefined { if (amount.currency !== limit.currency) { @@ -869,8 +884,7 @@ function validateAmount( if (Amounts.isZero(amount)) { return i18n.str`Can't transfer zero amount`; } - const amountWithFee = Amounts.add(amount, fee).amount; - if (Amounts.cmp(limit, amountWithFee) === -1) { + if (Amounts.cmp(limit, amount) === -1) { return i18n.str`Balance is not enough`; } return undefined; diff --git a/packages/bank-ui/src/pages/WalletWithdrawForm.tsx b/packages/bank-ui/src/pages/WalletWithdrawForm.tsx index 39dea018f..7cf2c7881 100644 --- a/packages/bank-ui/src/pages/WalletWithdrawForm.tsx +++ b/packages/bank-ui/src/pages/WalletWithdrawForm.tsx @@ -46,6 +46,7 @@ import { RenderAmount, doAutoFocus, } from "./PaytoWireTransferForm.js"; +import { useSettingsContext } from "../context/settings.js"; const RefAmount = forwardRef(InputAmount); @@ -65,7 +66,7 @@ function OldWithdrawalForm({ routeCancel: RouteDefinition; }): VNode { const { i18n } = useTranslationContext(); - const [settings] = usePreferences(); + const settings = useSettingsContext(); // const walletInegrationApi = useTalerWalletIntegrationAPI() // const { navigateTo } = useNavigationContext(); @@ -80,7 +81,7 @@ function OldWithdrawalForm({ const creds = credentials.status !== "loggedIn" ? undefined : credentials; const [amountStr, setAmountStr] = useState<string | undefined>( - `${settings.maxWithdrawalAmount}`, + `${settings.defaultSuggestedAmount ?? 1}`, ); const [notification, notify, handleError] = useLocalNotification(); @@ -143,7 +144,7 @@ function OldWithdrawalForm({ if (!parsedAmount || !creds) return; await handleError(async () => { const params: TalerCorebankApi.BankAccountCreateWithdrawalRequest = - settings.fastWithdrawal + settings.fastWithdrawalForm ? { suggested_amount: Amounts.stringify(parsedAmount), } @@ -241,9 +242,9 @@ function OldWithdrawalForm({ </i18n.Translate> </p> {Amounts.cmp(limit, balance) > 0 ? ( - <p class="mt-2 text-sm text-gray-500"> + <p class="mt-2 text-sm text-gray-900"> <i18n.Translate> - Your account allows you to withdraw{" "} + You can withdraw{" "} <RenderAmount value={limit} spec={config.currency_specification} @@ -347,7 +348,8 @@ export function WalletWithdrawForm({ routeCancel: RouteDefinition; }): VNode { const { i18n } = useTranslationContext(); - const [settings, updateSettings] = usePreferences(); + const [pref, updatePref] = usePreferences(); + const settings = useSettingsContext(); return ( <div class="grid grid-cols-1 gap-x-8 gap-y-8 pt-6 md:grid-cols-3 bg-gray-100 my-4 px-4 pb-4 rounded-lg"> @@ -364,11 +366,11 @@ export function WalletWithdrawForm({ </div> <div class="col-span-2"> - {settings.showInstallWallet && ( + {pref.showInstallWallet && ( <Attention title={i18n.str`You need a Taler wallet`} onClose={() => { - updateSettings("showInstallWallet", false); + updatePref("showInstallWallet", false); }} > <i18n.Translate> @@ -386,7 +388,7 @@ export function WalletWithdrawForm({ </Attention> )} - {!settings.fastWithdrawal ? ( + {!settings.fastWithdrawalForm ? ( <OldWithdrawalForm focus={focus} routeOperationDetails={routeOperationDetails} diff --git a/packages/bank-ui/src/settings.json b/packages/bank-ui/src/settings.json index df5fe75ce..f14168e77 100644 --- a/packages/bank-ui/src/settings.json +++ b/packages/bank-ui/src/settings.json @@ -2,6 +2,8 @@ "backendBaseURL": "http://bank.taler.test:1180/", "simplePasswordForRandomAccounts": true, "allowRandomAccountCreation": true, + "fastWithdrawalForm": true, + "defaultSuggestedAmount": 11, "bankName": "Taler DEVELOPMENT Bank", "topNavSites": { "Exchange": "http://Exchnage.taler.test:1180/", diff --git a/packages/bank-ui/src/settings.ts b/packages/bank-ui/src/settings.ts index c085c7cd8..6d8f7b850 100644 --- a/packages/bank-ui/src/settings.ts +++ b/packages/bank-ui/src/settings.ts @@ -20,6 +20,7 @@ import { canonicalizeBaseUrl, codecForBoolean, codecForMap, + codecForNumber, codecForString, codecOptional, } from "@gnu-taler/taler-util"; @@ -45,6 +46,17 @@ export interface UiSettings { // - value: link target, where the user is going to be redirected // default: empty list topNavSites?: Record<string, string>; + // Use the withdrawal form which redirect the user to the wallet + // without asking the amount to the user. + // - true: on withdrawal creation the spa will use suggested_amount instead + // of fixed amount + // - false: on withdrawal creation the spa will use fixed amount + // default: false + fastWithdrawalForm?: boolean; + // When the withdrawal form use the suggested amount the bank + // will send a default value that the user can change. + // default: 10 + defaultSuggestedAmount?: number; } /** @@ -56,12 +68,16 @@ const defaultSettings: UiSettings = { simplePasswordForRandomAccounts: false, allowRandomAccountCreation: false, topNavSites: {}, + fastWithdrawalForm: false, + defaultSuggestedAmount: 10, }; const codecForUISettings = (): Codec<UiSettings> => buildCodecForObject<UiSettings>() .property("backendBaseURL", codecOptional(codecForString())) .property("allowRandomAccountCreation", codecOptional(codecForBoolean())) + .property("fastWithdrawalForm", codecOptional(codecForBoolean())) + .property("defaultSuggestedAmount", codecOptional(codecForNumber())) .property( "simplePasswordForRandomAccounts", codecOptional(codecForBoolean()), |