taler-typescript-core

Wallet core logic and WebUIs for various components
Log | Files | Refs | Submodules | README | LICENSE

commit 1c7b743ab810ce13fa7c7a7eb1f31ea1abd6ee1a
parent 9e01cb32c4585acb31c1a03ca2d09dfd02660da4
Author: Sebastian <sebasjm@taler-systems.com>
Date:   Fri, 10 Jul 2026 12:49:17 -0300

pretty

Diffstat:
Mpackages/libeufin-bank-webui/src/pages/admin/AccountForm.tsx | 24++++++++++++++----------
Mpackages/taler-merchant-webui/src/Routing.tsx | 12++++++------
Mpackages/taler-merchant-webui/src/components/menu/SideBar.tsx | 37+++++++++++++++++++++----------------
Mpackages/taler-merchant-webui/src/context/currency.ts | 45+++++++++++++++++++++++----------------------
Mpackages/taler-merchant-webui/src/hooks/instance.ts | 3+--
Mpackages/taler-merchant-webui/src/paths/instance/accounts/list/index.tsx | 8++++----
Mpackages/taler-merchant-webui/src/paths/instance/kyc/list/index.tsx | 2+-
Mpackages/taler-util/src/types-taler-corebank.ts | 1-
Mpackages/web-util/src/hooks/useAsync.ts | 9++++++---
9 files changed, 76 insertions(+), 65 deletions(-)

diff --git a/packages/libeufin-bank-webui/src/pages/admin/AccountForm.tsx b/packages/libeufin-bank-webui/src/pages/admin/AccountForm.tsx @@ -115,8 +115,8 @@ export function AccountForm<PurposeType extends keyof ChangeByPurposeType>({ const defaultValue: AccountFormData = { debit_threshold: Amounts.stringifyValue( template?.debit_threshold ?? - config.default_debit_threshold ?? - `${config.currency}:0`, + config.default_debit_threshold ?? + `${config.currency}:0`, ), isExchange: template?.is_taler_exchange, isPublic: template?.is_public, @@ -293,7 +293,8 @@ export function AccountForm<PurposeType extends keyof ChangeByPurposeType>({ is_public: newForm.isPublic, is_taler_exchange: newForm.isExchange, tan_channels: - newForm.tan_channel === undefined || newForm.tan_channel === "remove" + newForm.tan_channel === undefined || + newForm.tan_channel === "remove" ? undefined : [newForm.tan_channel], }; @@ -314,7 +315,10 @@ export function AccountForm<PurposeType extends keyof ChangeByPurposeType>({ is_public: newForm.isPublic, name: newForm.name, tan_channels: - newForm.tan_channel === "remove" || newForm.tan_channel === undefined ? undefined : [newForm.tan_channel], + newForm.tan_channel === "remove" || + newForm.tan_channel === undefined + ? undefined + : [newForm.tan_channel], }; callback(result); return; @@ -504,7 +508,7 @@ export function AccountForm<PurposeType extends keyof ChangeByPurposeType>({ </div> {!config.supported_tan_channels || - config.supported_tan_channels.length === 0 ? undefined : ( + config.supported_tan_channels.length === 0 ? undefined : ( <div class="sm:col-span-5"> <label class="block text-sm font-medium leading-6 text-gray-900" @@ -515,7 +519,7 @@ export function AccountForm<PurposeType extends keyof ChangeByPurposeType>({ <div class="mt-2 max-w-xl text-sm text-gray-500"> <div class="px-4 mt-4 grid grid-cols-1 gap-y-6"> {config.supported_tan_channels.indexOf(TanChannel.EMAIL) === - -1 ? undefined : ( + -1 ? undefined : ( <label onClick={(e) => { if (!hasEmail) return; @@ -573,7 +577,7 @@ export function AccountForm<PurposeType extends keyof ChangeByPurposeType>({ )} {config.supported_tan_channels.indexOf(TanChannel.SMS) === - -1 ? undefined : ( + -1 ? undefined : ( <label onClick={(e) => { if (!hasPhone) return; @@ -666,9 +670,9 @@ export function AccountForm<PurposeType extends keyof ChangeByPurposeType>({ !editableThreshold ? undefined : (e) => { - form.debit_threshold = e as AmountString; - updateForm(structuredClone(form)); - } + form.debit_threshold = e as AmountString; + updateForm(structuredClone(form)); + } } /> <ShowInputErrorLabel diff --git a/packages/taler-merchant-webui/src/Routing.tsx b/packages/taler-merchant-webui/src/Routing.tsx @@ -179,7 +179,7 @@ export enum AdminPaths { update_instance_auth = "/instance/:id/token", } -export interface Props { } +export interface Props {} export const privatePages = { home: urlPattern(/\/home/, () => "#/home"), @@ -355,7 +355,7 @@ export function Routing(_p: Props): VNode { onBack={() => { route(`/`); }} - onConfirm={() => { }} + onConfirm={() => {}} /> {/** * Update instance page @@ -829,9 +829,9 @@ export function Routing(_p: Props): VNode { <Route path={InstancePaths.kyc} component={ListKYCPage} - // onSelect={(id: string) => { - // route(InstancePaths.bank_update.replace(":bid", id)); - // }} + // onSelect={(id: string) => { + // route(InstancePaths.bank_update.replace(":bid", id)); + // }} /> <Route path={InstancePaths.interface} component={Settings} /> {/** @@ -914,7 +914,7 @@ function BankAccountBanner(): VNode { } function KycBanner(): VNode { - const { kycStatus } = useCurrenciesContext() + const { kycStatus } = useCurrenciesContext(); const { i18n } = useTranslationContext(); const [prefs, updatePref] = usePreference(); diff --git a/packages/taler-merchant-webui/src/components/menu/SideBar.tsx b/packages/taler-merchant-webui/src/components/menu/SideBar.tsx @@ -50,7 +50,12 @@ export function Sidebar({ mobile }: Props): VNode { const { isTestingEnvironment } = useSettingsContext(); - const { list: cList, switchCurrency, currency, kycStatus } = useCurrenciesContext(); + const { + list: cList, + switchCurrency, + currency, + kycStatus, + } = useCurrenciesContext(); const hideKycMenuItem = kycStatus.worst === MerchantAccountKycStatusSimplified.OK && @@ -247,13 +252,13 @@ export function Sidebar({ mobile }: Props): VNode { point={UIElement.sidebar_kycStatus} class={ kycStatus.worst === - MerchantAccountKycStatusSimplified.WARNING + MerchantAccountKycStatusSimplified.WARNING ? "is-warning" : kycStatus.worst === - MerchantAccountKycStatusSimplified.ERROR + MerchantAccountKycStatusSimplified.ERROR ? "is-error" : kycStatus.worst === - MerchantAccountKycStatusSimplified.ACTION_REQUIRED + MerchantAccountKycStatusSimplified.ACTION_REQUIRED ? "is-warning" : undefined } @@ -263,23 +268,23 @@ export function Sidebar({ mobile }: Props): VNode { class="has-icon" style={ kycStatus.worst === - MerchantAccountKycStatusSimplified.WARNING + MerchantAccountKycStatusSimplified.WARNING ? { - backgroundColor: "darkorange", - color: "black", - } - : kycStatus.worst === - MerchantAccountKycStatusSimplified.ERROR - ? { - backgroundColor: "#e93c3c", + backgroundColor: "darkorange", color: "black", } - : kycStatus.worst === - MerchantAccountKycStatusSimplified.ACTION_REQUIRED - ? { - backgroundColor: "darkorange", + : kycStatus.worst === + MerchantAccountKycStatusSimplified.ERROR + ? { + backgroundColor: "#e93c3c", color: "black", } + : kycStatus.worst === + MerchantAccountKycStatusSimplified.ACTION_REQUIRED + ? { + backgroundColor: "darkorange", + color: "black", + } : undefined } > diff --git a/packages/taler-merchant-webui/src/context/currency.ts b/packages/taler-merchant-webui/src/context/currency.ts @@ -25,7 +25,7 @@ import { ComponentChildren, createContext, h, VNode } from "preact"; import { useContext, useState } from "preact/hooks"; import { useInstanceKYCDetails, - useInstanceKYCDetailsLongPolling + useInstanceKYCDetailsLongPolling, } from "../hooks/instance.js"; import { useSessionContext } from "./session.js"; @@ -50,19 +50,18 @@ const initial: Type = { verificationRequired: false, }, currency: undefined, - switchCurrency(id) { }, + switchCurrency(id) {}, }; const Context = createContext<Type>(initial); export const useCurrenciesContext = (): Type => useContext(Context); - export type KycStatusMap = { - best?: MerchantAccountKycStatusSimplified, - worst?: MerchantAccountKycStatusSimplified, - byAccount: { [payto: string]: MerchantAccountKycStatusSimplified }, + best?: MerchantAccountKycStatusSimplified; + worst?: MerchantAccountKycStatusSimplified; + byAccount: { [payto: string]: MerchantAccountKycStatusSimplified }; verificationRequired: boolean; -} +}; export const CurrenciesProvider = ({ children, @@ -76,10 +75,11 @@ export const CurrenciesProvider = ({ const kycResult = useInstanceKYCDetailsLongPolling(); - - const kycData = (kycResult instanceof TalerError || !kycResult || kycResult.type === "fail" - ? undefined - : kycResult.body)?.kyc_data ?? [] + const kycData = + (kycResult instanceof TalerError || !kycResult || kycResult.type === "fail" + ? undefined + : kycResult.body + )?.kyc_data ?? []; const readyToBeUsed = Object.keys( kycData.reduce( @@ -100,21 +100,24 @@ export const CurrenciesProvider = ({ const fromDefault = !firstCurrency ? undefined : { - ...config.currencies[firstCurrency], - id: firstCurrency, - }; + ...config.currencies[firstCurrency], + id: firstCurrency, + }; const kycStatus = kycData.reduce( (prev, cur) => { const st = getMerchantAccountKycStatusSimplified(cur.status); - prev.byAccount[cur.payto_uri] = st + prev.byAccount[cur.payto_uri] = st; if (prev.best === undefined || st < prev.best) { - prev.best = st - }; + prev.best = st; + } if (prev.worst === undefined || st > prev.worst) { - prev.worst = st - }; - prev.verificationRequired = prev.verificationRequired || cur.payto_kycauths !== undefined || cur.access_token !== undefined + prev.worst = st; + } + prev.verificationRequired = + prev.verificationRequired || + cur.payto_kycauths !== undefined || + cur.access_token !== undefined; return prev; }, { @@ -142,7 +145,6 @@ export const CurrenciesProvider = ({ }); }; - // export function useInstanceKYCSimplifiedWorstStatusLongPolling( // account?: Paytos.URI, // ) { @@ -183,4 +185,3 @@ export const CurrenciesProvider = ({ // : []; // } - diff --git a/packages/taler-merchant-webui/src/hooks/instance.ts b/packages/taler-merchant-webui/src/hooks/instance.ts @@ -17,7 +17,7 @@ import { AccessToken, TalerHttpError, - TalerMerchantManagementResultByMethod + TalerMerchantManagementResultByMethod, } from "@gnu-taler/taler-util"; import { LONG_POLL_DELAY, useLongPolling } from "@gnu-taler/web-util/browser"; import { useSessionContext } from "../context/session.js"; @@ -108,7 +108,6 @@ export function useInstanceKYCDetailsLongPolling() { return result; } - export function useInstanceKYCDetails() { const { state, lib } = useSessionContext(); const token = state.token; diff --git a/packages/taler-merchant-webui/src/paths/instance/accounts/list/index.tsx b/packages/taler-merchant-webui/src/paths/instance/accounts/list/index.tsx @@ -77,8 +77,8 @@ export function UnableToUseBankAccountWarning({ account: Paytos.URI; }): VNode { const { i18n } = useTranslationContext(); - const {kycStatus} = useCurrenciesContext() - const status = kycStatus.byAccount[Paytos.toFullString(account)] + const { kycStatus } = useCurrenciesContext(); + const status = kycStatus.byAccount[Paytos.toFullString(account)]; switch (status) { case MerchantAccountKycStatusSimplified.ACTION_REQUIRED: case MerchantAccountKycStatusSimplified.WARNING: @@ -111,8 +111,8 @@ export function UnableToUseBankAccountWarning({ export function LimitedKycActionWarning(): VNode { const { i18n } = useTranslationContext(); - const {kycStatus} = useCurrenciesContext() - const status = kycStatus.best + const { kycStatus } = useCurrenciesContext(); + const status = kycStatus.best; switch (status) { case MerchantAccountKycStatusSimplified.WARNING: diff --git a/packages/taler-merchant-webui/src/paths/instance/kyc/list/index.tsx b/packages/taler-merchant-webui/src/paths/instance/kyc/list/index.tsx @@ -49,7 +49,7 @@ interface Props { } export default function ListKYC(_p: Props): VNode { - const { kycResult: result } = useCurrenciesContext() + const { kycResult: result } = useCurrenciesContext(); const [showingInstructions, setShowingInstructions] = useState< TalerMerchantApi.MerchantAccountKycRedirect | undefined >(undefined); diff --git a/packages/taler-util/src/types-taler-corebank.ts b/packages/taler-util/src/types-taler-corebank.ts @@ -361,7 +361,6 @@ export interface AccountReconfiguration { // Sending null or an empty array will disable 2FA // @since **v10** tan_channels?: TanChannel[] | null; - } export interface AccountPasswordChange { diff --git a/packages/web-util/src/hooks/useAsync.ts b/packages/web-util/src/hooks/useAsync.ts @@ -88,9 +88,12 @@ export function useLongPolling<Res>( ) { const minTime = opts?.minTime ?? 1000; - const [result, setResult] = useState<{ counter: number, prevResult: Res }>({ counter: 0, prevResult: initial }); + const [result, setResult] = useState<{ counter: number; prevResult: Res }>({ + counter: 0, + prevResult: initial, + }); function retry(prevResult: Res) { - setResult(prev => ({ counter: prev.counter + 1, prevResult })) + setResult((prev) => ({ counter: prev.counter + 1, prevResult })); } useEffect(() => { retry(initial); @@ -134,7 +137,7 @@ export function useLongPolling<Res>( }); } - return () => { }; + return () => {}; }, [result.counter]); /**