summaryrefslogtreecommitdiff
path: root/packages/bank-ui/src/pages/admin/AccountForm.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'packages/bank-ui/src/pages/admin/AccountForm.tsx')
-rw-r--r--packages/bank-ui/src/pages/admin/AccountForm.tsx162
1 files changed, 101 insertions, 61 deletions
diff --git a/packages/bank-ui/src/pages/admin/AccountForm.tsx b/packages/bank-ui/src/pages/admin/AccountForm.tsx
index bce7afe11..10b6afdf9 100644
--- a/packages/bank-ui/src/pages/admin/AccountForm.tsx
+++ b/packages/bank-ui/src/pages/admin/AccountForm.tsx
@@ -18,14 +18,12 @@ import {
Amounts,
PaytoString,
TalerCorebankApi,
- TranslatedString,
assertUnreachable,
buildPayto,
parsePaytoUri,
stringifyPaytoUri,
} from "@gnu-taler/taler-util";
import {
- Attention,
CopyButton,
ShowInputErrorLabel,
useTranslationContext,
@@ -41,7 +39,11 @@ import {
validateIBAN,
validateTalerBank,
} from "../../utils.js";
-import { InputAmount, TextField, doAutoFocus } from "../PaytoWireTransferForm.js";
+import {
+ InputAmount,
+ TextField,
+ doAutoFocus,
+} from "../PaytoWireTransferForm.js";
import { getRandomPassword } from "../rnd.js";
const EMAIL_REGEX =
@@ -99,7 +101,10 @@ export function AccountForm<PurposeType extends keyof ChangeByPurposeType>({
ErrorMessageMappingFor<typeof defaultValue> | undefined
>(undefined);
- const paytoType = config.wire_type === "X_TALER_BANK" ? "x-taler-bank" as const : "iban" as const;
+ const paytoType =
+ config.wire_type === "X_TALER_BANK"
+ ? ("x-taler-bank" as const)
+ : ("iban" as const);
const cashoutPaytoType: typeof paytoType = "iban" as const;
const defaultValue: AccountFormData = {
@@ -110,8 +115,10 @@ export function AccountForm<PurposeType extends keyof ChangeByPurposeType>({
isPublic: template?.is_public,
name: template?.name ?? "",
cashout_payto_uri:
- getAccountId(cashoutPaytoType, template?.cashout_payto_uri) ?? ("" as PaytoString),
- payto_uri: getAccountId(paytoType, template?.payto_uri) ?? ("" as PaytoString),
+ getAccountId(cashoutPaytoType, template?.cashout_payto_uri) ??
+ ("" as PaytoString),
+ payto_uri:
+ getAccountId(paytoType, template?.payto_uri) ?? ("" as PaytoString),
email: template?.contact_data?.email ?? "",
phone: template?.contact_data?.phone ?? "",
username: username ?? "",
@@ -130,9 +137,9 @@ export function AccountForm<PurposeType extends keyof ChangeByPurposeType>({
const isCashoutEnabled = config.allow_conversion;
const editableCashout =
- (purpose === "create" ||
- (purpose === "update" &&
- (config.allow_edit_cashout_payto_uri || userIsAdmin)));
+ purpose === "create" ||
+ (purpose === "update" &&
+ (config.allow_edit_cashout_payto_uri || userIsAdmin));
const editableThreshold =
userIsAdmin && (purpose === "create" || purpose === "update");
const editableAccount = purpose === "create" && userIsAdmin;
@@ -141,7 +148,6 @@ export function AccountForm<PurposeType extends keyof ChangeByPurposeType>({
const hasEmail = !!defaultValue.email || !!form.email;
function updateForm(newForm: typeof defaultValue): void {
-
const trimmedAmountStr = newForm.debit_threshold?.trim();
const parsedAmount = Amounts.parse(
`${config.currency}:${trimmedAmountStr}`,
@@ -154,19 +160,25 @@ export function AccountForm<PurposeType extends keyof ChangeByPurposeType>({
? undefined
: !editableCashout
? undefined
- : !newForm.cashout_payto_uri ? undefined
- : cashoutPaytoType === "iban" ? validateIBAN(newForm.cashout_payto_uri, i18n) :
- cashoutPaytoType === "x-taler-bank" ? validateTalerBank(newForm.cashout_payto_uri, i18n) :
- undefined,
+ : !newForm.cashout_payto_uri
+ ? undefined
+ : cashoutPaytoType === "iban"
+ ? validateIBAN(newForm.cashout_payto_uri, i18n)
+ : cashoutPaytoType === "x-taler-bank"
+ ? validateTalerBank(newForm.cashout_payto_uri, i18n)
+ : undefined,
payto_uri: !newForm.payto_uri
? undefined
: !editableAccount
? undefined
- : !newForm.payto_uri ? undefined
- : paytoType === "iban" ? validateIBAN(newForm.payto_uri, i18n) :
- paytoType === "x-taler-bank" ? validateTalerBank(newForm.payto_uri, i18n) :
- undefined,
+ : !newForm.payto_uri
+ ? undefined
+ : paytoType === "iban"
+ ? validateIBAN(newForm.payto_uri, i18n)
+ : paytoType === "x-taler-bank"
+ ? validateTalerBank(newForm.payto_uri, i18n)
+ : undefined,
email: !newForm.email
? undefined
@@ -207,30 +219,38 @@ export function AccountForm<PurposeType extends keyof ChangeByPurposeType>({
onChange(undefined);
} else {
let cashout;
- if (newForm.cashout_payto_uri) switch (cashoutPaytoType) {
- case "x-taler-bank": {
- cashout = buildPayto("x-taler-bank", url.host, newForm.cashout_payto_uri);
- break;
- }
- case "iban": {
- cashout = buildPayto("iban", newForm.cashout_payto_uri, undefined);
- break;
+ if (newForm.cashout_payto_uri)
+ switch (cashoutPaytoType) {
+ case "x-taler-bank": {
+ cashout = buildPayto(
+ "x-taler-bank",
+ url.host,
+ newForm.cashout_payto_uri,
+ );
+ break;
+ }
+ case "iban": {
+ cashout = buildPayto("iban", newForm.cashout_payto_uri, undefined);
+ break;
+ }
+ default:
+ assertUnreachable(cashoutPaytoType);
}
- default: assertUnreachable(cashoutPaytoType)
- }
const cashoutURI = !cashout ? undefined : stringifyPaytoUri(cashout);
let internal;
- if (newForm.payto_uri) switch (paytoType) {
- case "x-taler-bank": {
- internal = buildPayto("x-taler-bank", url.host, newForm.payto_uri);
- break;
- }
- case "iban": {
- internal = buildPayto("iban", newForm.payto_uri, undefined);
- break;
+ if (newForm.payto_uri)
+ switch (paytoType) {
+ case "x-taler-bank": {
+ internal = buildPayto("x-taler-bank", url.host, newForm.payto_uri);
+ break;
+ }
+ case "iban": {
+ internal = buildPayto("iban", newForm.payto_uri, undefined);
+ break;
+ }
+ default:
+ assertUnreachable(paytoType);
}
- default: assertUnreachable(paytoType)
- }
const internalURI = !internal ? undefined : stringifyPaytoUri(internal);
const threshold = !parsedAmount
@@ -247,7 +267,7 @@ export function AccountForm<PurposeType extends keyof ChangeByPurposeType>({
username: newForm.username!,
contact_data: undefinedIfEmpty({
email: !newForm.email ? undefined : newForm.email,
- phone: !newForm.phone ? undefined :newForm.phone,
+ phone: !newForm.phone ? undefined : newForm.phone,
}),
debit_threshold: threshold ?? config.default_debit_threshold,
cashout_payto_uri: cashoutURI,
@@ -270,7 +290,7 @@ export function AccountForm<PurposeType extends keyof ChangeByPurposeType>({
cashout_payto_uri: cashoutURI,
contact_data: undefinedIfEmpty({
email: !newForm.email ? undefined : newForm.email,
- phone: !newForm.phone ? undefined :newForm.phone,
+ phone: !newForm.phone ? undefined : newForm.phone,
}),
debit_threshold: threshold,
is_public: newForm.isPublic,
@@ -370,7 +390,7 @@ export function AccountForm<PurposeType extends keyof ChangeByPurposeType>({
</p>
</div>
- {purpose === "create" ? undefined :
+ {purpose === "create" ? undefined : (
<TextField
id="internal-account"
label={i18n.str`Internal account`}
@@ -379,20 +399,23 @@ export function AccountForm<PurposeType extends keyof ChangeByPurposeType>({
? i18n.str`If empty a random account id will be assigned`
: i18n.str`Share this id to receive bank transfers`
}
-
error={errors?.payto_uri}
onChange={(e) => {
form.payto_uri = e as PaytoString;
updateForm(structuredClone(form));
}}
- rightIcons={<CopyButton
- class="p-2 rounded-full text-black shadow-sm focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 "
- getContent={() => form.payto_uri ?? defaultValue.payto_uri ?? ""}
- />}
+ rightIcons={
+ <CopyButton
+ class="p-2 rounded-full text-black shadow-sm focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 "
+ getContent={() =>
+ form.payto_uri ?? defaultValue.payto_uri ?? ""
+ }
+ />
+ }
value={(form.payto_uri ?? defaultValue.payto_uri) as PaytoString}
disabled={!editableAccount}
/>
- }
+ )}
<div class="sm:col-span-5">
<label
@@ -422,7 +445,9 @@ export function AccountForm<PurposeType extends keyof ChangeByPurposeType>({
/>
</div>
<p class="mt-2 text-sm text-gray-500">
- <i18n.Translate>To be used when second factor authentication is enabled</i18n.Translate>
+ <i18n.Translate>
+ To be used when second factor authentication is enabled
+ </i18n.Translate>
</p>
</div>
@@ -454,7 +479,9 @@ export function AccountForm<PurposeType extends keyof ChangeByPurposeType>({
/>
</div>
<p class="mt-2 text-sm text-gray-500">
- <i18n.Translate>To be used when second factor authentication is enabled</i18n.Translate>
+ <i18n.Translate>
+ To be used when second factor authentication is enabled
+ </i18n.Translate>
</p>
</div>
@@ -468,14 +495,17 @@ export function AccountForm<PurposeType extends keyof ChangeByPurposeType>({
form.cashout_payto_uri = e as PaytoString;
updateForm(structuredClone(form));
}}
- value={(form.cashout_payto_uri ?? defaultValue.cashout_payto_uri) as PaytoString}
+ value={
+ (form.cashout_payto_uri ??
+ defaultValue.cashout_payto_uri) as PaytoString
+ }
disabled={!editableCashout}
/>
)}
{/* channel, not shown if old cashout api */}
{OLD_CASHOUT_API ||
- 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"
@@ -486,7 +516,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;
@@ -544,7 +574,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;
@@ -619,9 +649,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
@@ -633,7 +663,9 @@ export function AccountForm<PurposeType extends keyof ChangeByPurposeType>({
isDirty={form.debit_threshold !== undefined}
/>
<p class="mt-2 text-sm text-gray-500">
- <i18n.Translate>How much the balance can go below zero.</i18n.Translate>
+ <i18n.Translate>
+ How much the balance can go below zero.
+ </i18n.Translate>
</p>
</div>
@@ -673,7 +705,9 @@ export function AccountForm<PurposeType extends keyof ChangeByPurposeType>({
</button>
</div>
<p class="mt-2 text-sm text-gray-500">
- <i18n.Translate>Public accounts have their balance publicly accessible</i18n.Translate>
+ <i18n.Translate>
+ Public accounts have their balance publicly accessible
+ </i18n.Translate>
</p>
</div>
@@ -685,7 +719,9 @@ export function AccountForm<PurposeType extends keyof ChangeByPurposeType>({
class="text-sm text-black font-medium leading-6 "
id="availability-label"
>
- <i18n.Translate>Is this account a payment provider?</i18n.Translate>
+ <i18n.Translate>
+ Is this account a payment provider?
+ </i18n.Translate>
</span>
</span>
<button
@@ -726,13 +762,17 @@ export function AccountForm<PurposeType extends keyof ChangeByPurposeType>({
);
}
-function getAccountId(type: "iban" | "x-taler-bank", s: PaytoString | undefined): string | undefined {
+function getAccountId(
+ type: "iban" | "x-taler-bank",
+ s: PaytoString | undefined,
+): string | undefined {
if (s === undefined) return undefined;
const p = parsePaytoUri(s);
if (p === undefined) return undefined;
if (!p.isKnown) return "<unknown>";
if (type === "iban" && p.targetType === "iban") return p.iban;
- if (type === "x-taler-bank" && p.targetType === "x-taler-bank") return p.account;
+ if (type === "x-taler-bank" && p.targetType === "x-taler-bank")
+ return p.account;
return "<unsupported>";
}