/* This file is part of GNU Taler (C) 2022 Taler Systems S.A. GNU Taler is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GNU Taler; see the file COPYING. If not, see */ import { canonicalizeBaseUrl, TalerConfigResponse, } from "@gnu-taler/taler-util"; import { Fragment, h, VNode } from "preact"; import { useEffect, useState } from "preact/hooks"; import { ErrorMessage } from "../components/ErrorMessage.js"; import { Input, LightText, SubTitle, Title, WarningBox, } from "../components/styled/index.js"; import { useTranslationContext } from "../context/translation.js"; import { Button } from "../mui/Button.js"; export interface Props { initialValue?: string; expectedCurrency?: string; onCancel: () => Promise; onVerify: (s: string) => Promise; onConfirm: (url: string) => Promise; withError?: string; } function useEndpointStatus( endpoint: string, onVerify: (e: string) => Promise, ): { loading: boolean; error?: string; endpoint: string; result: T | undefined; updateEndpoint: (s: string) => void; } { const [value, setValue] = useState(endpoint); const [dirty, setDirty] = useState(false); const [loading, setLoading] = useState(false); const [result, setResult] = useState(undefined); const [error, setError] = useState(undefined); const [handler, setHandler] = useState(undefined); useEffect(() => { if (!value) return; window.clearTimeout(handler); const h = window.setTimeout(async () => { setDirty(true); setLoading(true); try { const url = canonicalizeBaseUrl(value); const result = await onVerify(url); setResult(result); setError(undefined); setLoading(false); } catch (e) { const errorMessage = e instanceof Error ? e.message : `unknown error: ${e}`; setError(errorMessage); setLoading(false); setResult(undefined); } }, 500); setHandler(h); }, [value, setHandler, onVerify]); return { error: dirty ? error : undefined, loading: loading, result: result, endpoint: value, updateEndpoint: setValue, }; } export function ExchangeSetUrlPage({ initialValue, expectedCurrency, onCancel, onVerify, onConfirm, }: Props): VNode { const { i18n } = useTranslationContext(); const { loading, result, endpoint, updateEndpoint, error } = useEndpointStatus(initialValue ?? "", onVerify); const [confirmationError, setConfirmationError] = useState< string | undefined >(undefined); return (
{!expectedCurrency ? ( <i18n.Translate>Add new exchange</i18n.Translate> ) : ( Add exchange for {expectedCurrency} )} {!result && ( Enter the URL of an exchange you trust. )} {result && ( An exchange has been found! Review the information and click next )} {result && expectedCurrency && expectedCurrency !== result.currency && ( This exchange doesn't match the expected currency {expectedCurrency} )} {error && ( Unable to verify this exchange } description={error} /> )} {confirmationError && ( Unable to add this exchange} description={confirmationError} /> )}

updateEndpoint(e.currentTarget.value)} /> {loading && (

loading...
)} {result && !loading && ( )}

); }