summaryrefslogtreecommitdiff
path: root/packages/taler-wallet-webextension/src/cta/PaymentTemplate/state.ts
diff options
context:
space:
mode:
Diffstat (limited to 'packages/taler-wallet-webextension/src/cta/PaymentTemplate/state.ts')
-rw-r--r--packages/taler-wallet-webextension/src/cta/PaymentTemplate/state.ts128
1 files changed, 117 insertions, 11 deletions
diff --git a/packages/taler-wallet-webextension/src/cta/PaymentTemplate/state.ts b/packages/taler-wallet-webextension/src/cta/PaymentTemplate/state.ts
index f5e6dee61..abcf040b7 100644
--- a/packages/taler-wallet-webextension/src/cta/PaymentTemplate/state.ts
+++ b/packages/taler-wallet-webextension/src/cta/PaymentTemplate/state.ts
@@ -14,27 +14,56 @@
GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
*/
+import { Amounts } from "@gnu-taler/taler-util";
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
-import { alertFromError } from "../../context/alert.js";
+import { useState } from "preact/hooks";
+import { alertFromError, useAlertContext } from "../../context/alert.js";
import { useBackendContext } from "../../context/backend.js";
import { useTranslationContext } from "../../context/translation.js";
import { useAsyncAsHook } from "../../hooks/useAsyncAsHook.js";
+import { AmountFieldHandler, TextFieldHandler } from "../../mui/handlers.js";
import { Props, State } from "./index.js";
-export function useComponentState({ talerTemplateUri }: Props): State {
- // const { pushAlertOnError } = useAlertContext();
+export function useComponentState({
+ talerTemplateUri,
+ cancel,
+ goToWalletManualWithdraw,
+ onSuccess,
+}: Props): State {
const api = useBackendContext();
const { i18n } = useTranslationContext();
+ const { safely } = useAlertContext();
+
+ const url = talerTemplateUri ? new URL(talerTemplateUri) : undefined;
+
+ const amountParam = !url
+ ? undefined
+ : url.searchParams.get("amount") ?? undefined;
+ const summaryParam = !url
+ ? undefined
+ : url.searchParams.get("summary") ?? undefined;
+
+ const parsedAmount = !amountParam ? undefined : Amounts.parse(amountParam);
+ const currency = parsedAmount ? parsedAmount.currency : amountParam;
+
+ const initialAmount =
+ parsedAmount ?? (currency ? Amounts.zeroOfCurrency(currency) : undefined);
+ const [amount, setAmount] = useState(initialAmount);
+ const [summary, setSummary] = useState(summaryParam);
+ const [newOrder, setNewOrder] = useState("");
const hook = useAsyncAsHook(async () => {
if (!talerTemplateUri) throw Error("ERROR_NO-URI-FOR-PAYMENT-TEMPLATE");
- const payStatus = await api.wallet.call(
- WalletApiOperation.PreparePayForTemplate,
- {
- talerPayTemplateUri: talerTemplateUri,
- templateParams: {},
- },
- );
+ let payStatus;
+ if (!amountParam && !summaryParam) {
+ payStatus = await api.wallet.call(
+ WalletApiOperation.PreparePayForTemplate,
+ {
+ talerPayTemplateUri: talerTemplateUri,
+ templateParams: {},
+ },
+ );
+ }
const balance = await api.wallet.call(WalletApiOperation.GetBalances, {});
return { payStatus, balance, uri: talerTemplateUri };
}, []);
@@ -56,8 +85,85 @@ export function useComponentState({ talerTemplateUri }: Props): State {
};
}
+ if (hook.response.payStatus) {
+ return {
+ status: "order-ready",
+ error: undefined,
+ cancel,
+ goToWalletManualWithdraw,
+ onSuccess,
+ talerPayUri: hook.response.payStatus.talerUri!,
+ };
+ }
+
+ if (newOrder) {
+ return {
+ status: "order-ready",
+ error: undefined,
+ cancel,
+ goToWalletManualWithdraw,
+ onSuccess,
+ talerPayUri: newOrder,
+ };
+ }
+
+ async function createOrder() {
+ try {
+ const templateParams: Record<string, string> = {};
+ if (amount) {
+ templateParams["amount"] = Amounts.stringify(amount);
+ }
+ if (summary) {
+ templateParams["summary"] = summary;
+ }
+ const payStatus = await api.wallet.call(
+ WalletApiOperation.PreparePayForTemplate,
+ {
+ talerPayTemplateUri: talerTemplateUri,
+ templateParams,
+ },
+ );
+ setNewOrder(payStatus.talerUri!);
+ } catch (e) {}
+ }
+ const errors = undefinedIfEmpty({
+ amount: amount && Amounts.isZero(amount) ? i18n.str`required` : undefined,
+ summary: !summary ? i18n.str`required` : undefined,
+ });
return {
- status: "ready",
+ status: "fill-template",
error: undefined,
+ currency: currency!, //currency is always not null
+ amount:
+ amount !== undefined
+ ? ({
+ onInput: (a) => {
+ setAmount(a);
+ },
+ value: amount,
+ error: errors?.amount,
+ } as AmountFieldHandler)
+ : undefined,
+ summary:
+ summary !== undefined
+ ? ({
+ onInput: (t) => {
+ setSummary(t);
+ },
+ value: summary,
+ error: errors?.summary,
+ } as TextFieldHandler)
+ : undefined,
+ onCreate: {
+ onClick: errors
+ ? undefined
+ : safely(createOrder, i18n.str`Could not create order`),
+ },
};
}
+
+function undefinedIfEmpty<T extends object>(obj: T): T | undefined {
+ return Object.keys(obj).some((k) => (obj as any)[k] !== undefined)
+ ? obj
+ : undefined;
+}