more ui
This commit is contained in:
parent
15af6c619d
commit
ae49194d42
@ -15,15 +15,24 @@
|
||||
GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
import { useTranslationContext } from "@gnu-taler/web-util/browser";
|
||||
import { HttpError, useTranslationContext } from "@gnu-taler/web-util/browser";
|
||||
import { h, VNode } from "preact";
|
||||
|
||||
export function ErrorLoading(): VNode {
|
||||
export function ErrorLoading({ error }: { error: HttpError<SandboxBackend.SandboxError> }): VNode {
|
||||
const { i18n } = useTranslationContext()
|
||||
return (
|
||||
<div><i18n.Translate>
|
||||
Could not complete the request
|
||||
</i18n.Translate>
|
||||
<div><div class="rounded-md bg-red-50 p-4">
|
||||
<div class="flex">
|
||||
<div class="flex-shrink-0">
|
||||
<svg class="h-5 w-5 text-red-400" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
|
||||
<path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.28 7.22a.75.75 0 00-1.06 1.06L8.94 10l-1.72 1.72a.75.75 0 101.06 1.06L10 11.06l1.72 1.72a.75.75 0 101.06-1.06L11.06 10l1.72-1.72a.75.75 0 00-1.06-1.06L10 8.94 8.28 7.22z" clip-rule="evenodd" />
|
||||
</svg>
|
||||
</div>
|
||||
<div class="ml-3 flex-1 md:flex md:justify-between">
|
||||
<p class="text-sm font-medium text-red-800">{error.message}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -23,7 +23,6 @@ import { BusinessAccount } from "../pages/business/Home.js";
|
||||
import { HomePage, WithdrawalOperationPage } from "../pages/HomePage.js";
|
||||
import { PublicHistoriesPage } from "../pages/PublicHistoriesPage.js";
|
||||
import { RegistrationPage } from "../pages/RegistrationPage.js";
|
||||
import { Test } from "../pages/Test.js";
|
||||
import { useBackendContext } from "../context/backend.js";
|
||||
import { LoginForm } from "../pages/LoginForm.js";
|
||||
import { AdminHome } from "../pages/admin/Home.js";
|
||||
@ -69,6 +68,9 @@ export function Routing(): VNode {
|
||||
onComplete={() => {
|
||||
route("/account");
|
||||
}}
|
||||
onCancel={() => {
|
||||
route("/account");
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
|
@ -32,6 +32,7 @@ export function LoadingUriView({ error }: State.LoadingUriError): VNode {
|
||||
|
||||
export function ReadyView({ transactions }: State.Ready): VNode {
|
||||
const { i18n } = useTranslationContext();
|
||||
if (!transactions.length) return <div />
|
||||
const txByDate = transactions.reduce((prev, cur) => {
|
||||
const d = cur.when.t_ms === "never"
|
||||
? ""
|
||||
|
@ -94,7 +94,7 @@ export function useAccessAnonAPI(): AccessAnonAPI {
|
||||
const { request } = useAuthenticatedBackend();
|
||||
|
||||
const abortWithdrawal = async (id: string): Promise<HttpResponseOk<void>> => {
|
||||
const res = await request<void>(`accounts/withdrawals/${id}/abort`, {
|
||||
const res = await request<void>(`withdrawals/${id}/abort`, {
|
||||
method: "POST",
|
||||
contentType: "json",
|
||||
});
|
||||
|
@ -18,7 +18,7 @@ import { HttpError, HttpResponseOk, HttpResponsePaginated, utils } from "@gnu-ta
|
||||
import { AbsoluteTime, AmountJson, PaytoUriIBAN, PaytoUriTalerBank } from "@gnu-taler/taler-util";
|
||||
import { Loading } from "../../components/Loading.js";
|
||||
import { useComponentState } from "./state.js";
|
||||
import { ReadyView, InvalidIbanView} from "./views.js";
|
||||
import { ReadyView, InvalidIbanView } from "./views.js";
|
||||
import { VNode } from "preact";
|
||||
import { LoginForm } from "../LoginForm.js";
|
||||
import { ErrorLoading } from "../../components/ErrorLoading.js";
|
||||
@ -29,7 +29,7 @@ export interface Props {
|
||||
error: HttpResponsePaginated<T, SandboxBackend.SandboxError>,
|
||||
) => VNode;
|
||||
goToBusinessAccount: () => void;
|
||||
goToConfirmOperation: (id:string) => void;
|
||||
goToConfirmOperation: (id: string) => void;
|
||||
}
|
||||
|
||||
export type State = State.Loading | State.LoadingError | State.Ready | State.InvalidIban | State.UserNotFound;
|
||||
@ -48,14 +48,14 @@ export namespace State {
|
||||
export interface BaseInfo {
|
||||
error: undefined;
|
||||
}
|
||||
|
||||
|
||||
export interface Ready extends BaseInfo {
|
||||
status: "ready";
|
||||
error: undefined;
|
||||
account: string,
|
||||
account: string,
|
||||
limit: AmountJson,
|
||||
goToBusinessAccount: () => void;
|
||||
goToConfirmOperation: (id:string) => void;
|
||||
goToConfirmOperation: (id: string) => void;
|
||||
}
|
||||
|
||||
export interface InvalidIban {
|
||||
|
@ -48,6 +48,13 @@ export function useComponentState({ account, goToBusinessAccount, goToConfirmOpe
|
||||
error: result,
|
||||
};
|
||||
}
|
||||
if (result.status === HttpStatusCode.Unauthorized) {
|
||||
notifyError(i18n.str`Require login`, undefined);
|
||||
return {
|
||||
status: "error-user-not-found",
|
||||
error: result,
|
||||
};
|
||||
}
|
||||
return {
|
||||
status: "loading-error",
|
||||
error: result,
|
||||
|
@ -344,8 +344,6 @@ function StatusBanner(): VNode {
|
||||
class="fixed top-10 z-20 ml-4 mr-4"
|
||||
> {
|
||||
notifs.map(n => {
|
||||
const info = n.message.type === "info" ? n.message : undefined
|
||||
const error = n.message.type === "error" ? n.message : undefined
|
||||
switch (n.message.type) {
|
||||
case "error":
|
||||
return <div class="rounded-md bg-red-50 p-4">
|
||||
@ -478,8 +476,7 @@ function AccountBalance({ account }: { account: string }): VNode {
|
||||
|
||||
// FIXME: balance
|
||||
return <div>
|
||||
{Amounts.currencyOf(result.data.balance)}
|
||||
{Amounts.stringifyValue(result.data.balance)}
|
||||
{Amounts.currencyOf(result.data.balance)} {Amounts.stringifyValue(result.data.balance)}
|
||||
{/* {Amounts.currencyOf(result.data.balance.amount)}
|
||||
{result.data.balance.credit_debit_indicator === "debit" ? "-" : ""}
|
||||
{Amounts.stringifyValue(result.data.balance.amount)} */}
|
||||
|
@ -59,7 +59,7 @@ export function HomePage({
|
||||
account: string,
|
||||
onRegister: () => void;
|
||||
goToBusinessAccount: () => void;
|
||||
goToConfirmOperation: (id:string) => void;
|
||||
goToConfirmOperation: (id: string) => void;
|
||||
}): VNode {
|
||||
const { i18n } = useTranslationContext();
|
||||
|
||||
@ -84,7 +84,7 @@ export function WithdrawalOperationPage({
|
||||
//or return withdrawal uri from response
|
||||
const baseUrl = getInitialBackendBaseURL()
|
||||
const uri = stringifyWithdrawUri({
|
||||
bankIntegrationApiBaseUrl: `${baseUrl}/integration-api`,
|
||||
bankIntegrationApiBaseUrl: `${baseUrl}/taler-integration`,
|
||||
withdrawalOperationId: operationId,
|
||||
});
|
||||
const parsedUri = parseWithdrawUri(uri);
|
||||
@ -98,7 +98,7 @@ export function WithdrawalOperationPage({
|
||||
);
|
||||
return <Loading />;
|
||||
}
|
||||
|
||||
|
||||
return (
|
||||
<WithdrawalQRCode
|
||||
withdrawUri={parsedUri}
|
||||
@ -121,7 +121,7 @@ export function handleNotOkResult(
|
||||
return function handleNotOkResult2<T>(
|
||||
result:
|
||||
| HttpResponsePaginated<T, SandboxBackend.SandboxError | undefined>
|
||||
| HttpResponse<T, SandboxBackend.SandboxError| undefined>,
|
||||
| HttpResponse<T, SandboxBackend.SandboxError | undefined>,
|
||||
): VNode {
|
||||
if (result.loading) return <Loading />;
|
||||
if (!result.ok) {
|
||||
|
@ -49,7 +49,7 @@ export function LoginForm({ onRegister }: { onRegister?: () => void }): VNode {
|
||||
? i18n.str`Missing username`
|
||||
// : !USERNAME_REGEX.test(username)
|
||||
// ? i18n.str`Use letters and numbers only, and start with a lowercase letter`
|
||||
: undefined,
|
||||
: undefined,
|
||||
password: !password ? i18n.str`Missing password` : undefined,
|
||||
}) ?? busy;
|
||||
|
||||
@ -213,7 +213,7 @@ export function LoginForm({ onRegister }: { onRegister?: () => void }): VNode {
|
||||
{bankUiSettings.allowRegistrations && onRegister &&
|
||||
<p class="mt-10 text-center text-sm text-gray-500 border-t">
|
||||
<button type="submit"
|
||||
class="flex mt-4 w-full justify-center rounded-md bg-green-600 px-3 py-1.5 text-sm font-semibold leading-6 text-white shadow-sm hover:bg-green-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-green-600"
|
||||
class="flex mt-4 rounded-md bg-blue-600 px-3 py-1.5 text-sm font-semibold leading-6 text-white shadow-sm hover:bg-blue-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-600"
|
||||
onClick={(e) => {
|
||||
e.preventDefault()
|
||||
onRegister()
|
||||
|
@ -14,19 +14,16 @@
|
||||
GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
import { HttpError, HttpResponseOk, HttpResponsePaginated, utils } from "@gnu-taler/web-util/browser";
|
||||
import { AbsoluteTime, AmountJson, PaytoUriIBAN, PaytoUriTalerBank, WithdrawUriResult } from "@gnu-taler/taler-util";
|
||||
import { AbsoluteTime, AmountJson, WithdrawUriResult } from "@gnu-taler/taler-util";
|
||||
import { HttpError, utils } from "@gnu-taler/web-util/browser";
|
||||
import { ErrorLoading } from "../../components/ErrorLoading.js";
|
||||
import { Loading } from "../../components/Loading.js";
|
||||
import { useComponentState } from "./state.js";
|
||||
import { ReadyView, AbortedView, ConfirmedView, InvalidPaytoView, InvalidReserveView, InvalidWithdrawalView, NeedConfirmationView } from "./views.js";
|
||||
import { VNode } from "preact";
|
||||
import { LoginForm } from "../LoginForm.js";
|
||||
import { ErrorLoading } from "../../components/ErrorLoading.js";
|
||||
import { AbortedView, ConfirmedView, InvalidPaytoView, InvalidReserveView, InvalidWithdrawalView, NeedConfirmationView, ReadyView } from "./views.js";
|
||||
|
||||
export interface Props {
|
||||
currency: string;
|
||||
onClose: () => void;
|
||||
goToConfirmOperation: (id: string) => void;
|
||||
}
|
||||
|
||||
export type State = State.Loading |
|
||||
|
@ -15,16 +15,15 @@
|
||||
*/
|
||||
|
||||
import { Amounts, HttpStatusCode, TranslatedString, parsePaytoUri, parseWithdrawUri, stringifyWithdrawUri } from "@gnu-taler/taler-util";
|
||||
import { ErrorType, RequestError, notify, notifyError, notifyInfo, useTranslationContext, utils } from "@gnu-taler/web-util/browser";
|
||||
import { useBackendContext } from "../../context/backend.js";
|
||||
import { useAccessAPI, useAccessAnonAPI, useAccountDetails, useWithdrawalDetails } from "../../hooks/access.js";
|
||||
import { Props, State } from "./index.js";
|
||||
import { useSettings } from "../../hooks/settings.js";
|
||||
import { buildRequestErrorMessage, undefinedIfEmpty } from "../../utils.js";
|
||||
import { useEffect, useMemo, useState } from "preact/hooks";
|
||||
import { RequestError, notify, notifyError, notifyInfo, useTranslationContext, utils } from "@gnu-taler/web-util/browser";
|
||||
import { useEffect, useState } from "preact/hooks";
|
||||
import { useAccessAPI, useAccessAnonAPI, useWithdrawalDetails } from "../../hooks/access.js";
|
||||
import { getInitialBackendBaseURL } from "../../hooks/backend.js";
|
||||
import { useSettings } from "../../hooks/settings.js";
|
||||
import { buildRequestErrorMessage } from "../../utils.js";
|
||||
import { Props, State } from "./index.js";
|
||||
|
||||
export function useComponentState({ currency, onClose,goToConfirmOperation }: Props): utils.RecursiveState<State> {
|
||||
export function useComponentState({ currency, onClose }: Props): utils.RecursiveState<State> {
|
||||
const { i18n } = useTranslationContext();
|
||||
const [settings, updateSettings] = useSettings()
|
||||
const { createWithdrawal } = useAccessAPI();
|
||||
@ -142,8 +141,8 @@ export function useComponentState({ currency, onClose,goToConfirmOperation }: Pr
|
||||
}
|
||||
}
|
||||
setBusy(undefined)
|
||||
}
|
||||
const bankIntegrationApiBaseUrl = `${baseUrl}/integration-api`
|
||||
}
|
||||
const bankIntegrationApiBaseUrl = `${baseUrl}/taler-integration`
|
||||
const uri = stringifyWithdrawUri({
|
||||
bankIntegrationApiBaseUrl,
|
||||
withdrawalOperationId,
|
||||
@ -160,7 +159,13 @@ export function useComponentState({ currency, onClose,goToConfirmOperation }: Pr
|
||||
|
||||
return (): utils.RecursiveState<State> => {
|
||||
const result = useWithdrawalDetails(withdrawalOperationId);
|
||||
const shouldCreateNewOperation = !result.ok && !result.loading && result.info.status === HttpStatusCode.NotFound
|
||||
|
||||
useEffect(() => {
|
||||
if (shouldCreateNewOperation) {
|
||||
doSilentStart()
|
||||
}
|
||||
}, [])
|
||||
if (!result.ok) {
|
||||
if (result.loading) {
|
||||
return {
|
||||
@ -168,6 +173,12 @@ export function useComponentState({ currency, onClose,goToConfirmOperation }: Pr
|
||||
error: undefined
|
||||
}
|
||||
}
|
||||
if (result.info.status === HttpStatusCode.NotFound) {
|
||||
return {
|
||||
status: "loading",
|
||||
error: undefined,
|
||||
}
|
||||
}
|
||||
return {
|
||||
status: "loading-error",
|
||||
error: result
|
||||
@ -178,7 +189,10 @@ export function useComponentState({ currency, onClose,goToConfirmOperation }: Pr
|
||||
return {
|
||||
status: "aborted",
|
||||
error: undefined,
|
||||
onClose,
|
||||
onClose: async () => {
|
||||
updateSettings("currentWithdrawalOperationId", undefined)
|
||||
onClose()
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -256,6 +256,7 @@ export function AbortedView({ error, onClose }: State.Aborted) {
|
||||
<div>aborted</div>
|
||||
);
|
||||
}
|
||||
|
||||
export function ConfirmedView({ error, onClose }: State.Confirmed) {
|
||||
const { i18n } = useTranslationContext();
|
||||
const [settings, updateSettings] = useSettings()
|
||||
@ -325,8 +326,17 @@ export function ReadyView({ uri, onClose }: State.Ready): VNode<{}> {
|
||||
document.title = `${document.title} ${uri.withdrawalOperationId}`;
|
||||
}, []);
|
||||
const talerWithdrawUri = stringifyWithdrawUri(uri);
|
||||
const [show, setShow] = useState(false)
|
||||
return <Fragment>
|
||||
<div class="flex justify-end mt-4">
|
||||
<button type="button"
|
||||
class="inline-flex items-center rounded-md bg-red-600 px-3 py-2 text-sm font-semibold text-white shadow-sm hover:bg-red-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-red-500"
|
||||
onClick={() => {
|
||||
onClose()
|
||||
}}
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="bg-white shadow sm:rounded-lg mt-4">
|
||||
<div class="p-4">
|
||||
@ -360,39 +370,13 @@ export function ReadyView({ uri, onClose }: State.Ready): VNode<{}> {
|
||||
<i18n.Translate>Scan the QR code with your mobile device.</i18n.Translate>
|
||||
</p>
|
||||
</div>
|
||||
<div class="mt-5 sm:ml-6 sm:mt-0 sm:flex sm:flex-shrink-0 sm:items-center">
|
||||
<button type="button"
|
||||
class="inline-flex items-center rounded-md bg-indigo-600 px-3 py-2 text-sm font-semibold text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-500"
|
||||
onClick={() => {
|
||||
setShow(!show)
|
||||
}}
|
||||
>
|
||||
{!show ?
|
||||
<i18n.Translate>Show QR</i18n.Translate>
|
||||
:
|
||||
<i18n.Translate>Hide QR</i18n.Translate>
|
||||
}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
{show &&
|
||||
<div class="mt-2 max-w-md ml-auto mr-auto">
|
||||
<QR text={talerWithdrawUri} />
|
||||
</div>
|
||||
}
|
||||
<div class="mt-2 max-w-md ml-auto mr-auto">
|
||||
<QR text={talerWithdrawUri} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end mt-4">
|
||||
<button type="button"
|
||||
class="inline-flex items-center rounded-md bg-red-600 px-3 py-2 text-sm font-semibold text-white shadow-sm hover:bg-red-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-red-500"
|
||||
onClick={() => {
|
||||
onClose()
|
||||
}}
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
</div>
|
||||
</Fragment>
|
||||
|
||||
}
|
||||
|
@ -56,11 +56,11 @@ export function PaymentOptions({ limit, goToConfirmOperation }: { limit: AmountJ
|
||||
<i18n.Translate>Withdraw digital money into your mobile wallet or browser extension</i18n.Translate>
|
||||
</span>
|
||||
{!!settings.currentWithdrawalOperationId &&
|
||||
<span class="inline-flex items-center gap-x-1.5 rounded-full bg-green-100 px-1.5 py-0.5 text-xs font-medium text-green-700">
|
||||
<span class="inline-flex items-center gap-x-1.5 w-fit rounded-full bg-green-100 px-2 py-1 text-xs font-medium text-green-700">
|
||||
<svg class="h-1.5 w-1.5 fill-green-500" viewBox="0 0 6 6" aria-hidden="true">
|
||||
<circle cx="3" cy="3" r="3" />
|
||||
</svg>
|
||||
<i18n.Translate>Operation in progress</i18n.Translate>
|
||||
<i18n.Translate>operation ready</i18n.Translate>
|
||||
</span>
|
||||
}
|
||||
</span>
|
||||
|
@ -33,8 +33,10 @@ const logger = new Logger("RegistrationPage");
|
||||
|
||||
export function RegistrationPage({
|
||||
onComplete,
|
||||
onCancel
|
||||
}: {
|
||||
onComplete: () => void;
|
||||
onCancel: () => void;
|
||||
}): VNode {
|
||||
const { i18n } = useTranslationContext();
|
||||
if (!bankUiSettings.allowRegistrations) {
|
||||
@ -42,7 +44,7 @@ export function RegistrationPage({
|
||||
<p>{i18n.str`Currently, the bank is not accepting new registrations!`}</p>
|
||||
);
|
||||
}
|
||||
return <RegistrationForm onComplete={onComplete} />;
|
||||
return <RegistrationForm onComplete={onComplete} onCancel={onCancel} />;
|
||||
}
|
||||
|
||||
export const USERNAME_REGEX = /^[a-z][a-zA-Z0-9-]*$/;
|
||||
@ -50,7 +52,7 @@ export const USERNAME_REGEX = /^[a-z][a-zA-Z0-9-]*$/;
|
||||
/**
|
||||
* Collect and submit registration data.
|
||||
*/
|
||||
function RegistrationForm({ onComplete }: { onComplete: () => void }): VNode {
|
||||
function RegistrationForm({ onComplete, onCancel }: { onComplete: () => void, onCancel: () => void }): VNode {
|
||||
const backend = useBackendContext();
|
||||
const [username, setUsername] = useState<string | undefined>();
|
||||
const [name, setName] = useState<string | undefined>();
|
||||
@ -168,9 +170,38 @@ function RegistrationForm({ onComplete }: { onComplete: () => void }): VNode {
|
||||
autoCapitalize="none"
|
||||
autoCorrect="off"
|
||||
>
|
||||
<div>
|
||||
<label for="name" class="block text-sm font-medium leading-6 text-gray-900">
|
||||
<i18n.Translate>Name</i18n.Translate>
|
||||
<b style={{ color: "red" }}> *</b>
|
||||
</label>
|
||||
<div class="mt-2">
|
||||
<input
|
||||
autoFocus
|
||||
type="text"
|
||||
name="name"
|
||||
id="name"
|
||||
class="block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6"
|
||||
value={name ?? ""}
|
||||
enterkeyhint="next"
|
||||
placeholder="your name"
|
||||
autocomplete="name"
|
||||
required
|
||||
onInput={(e): void => {
|
||||
setName(e.currentTarget.value);
|
||||
}}
|
||||
/>
|
||||
<ShowInputErrorLabel
|
||||
message={errors?.name}
|
||||
isDirty={name !== undefined}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="username" class="block text-sm font-medium leading-6 text-gray-900">
|
||||
<i18n.Translate>Username</i18n.Translate>
|
||||
<b style={{ color: "red" }}> *</b>
|
||||
</label>
|
||||
<div class="mt-2">
|
||||
<input
|
||||
@ -197,7 +228,10 @@ function RegistrationForm({ onComplete }: { onComplete: () => void }): VNode {
|
||||
|
||||
<div>
|
||||
<div class="flex items-center justify-between">
|
||||
<label for="password" class="block text-sm font-medium leading-6 text-gray-900">Password</label>
|
||||
<label for="password" class="block text-sm font-medium leading-6 text-gray-900">
|
||||
Password
|
||||
<b style={{ color: "red" }}> *</b>
|
||||
</label>
|
||||
</div>
|
||||
<div class="mt-2">
|
||||
<input
|
||||
@ -223,7 +257,10 @@ function RegistrationForm({ onComplete }: { onComplete: () => void }): VNode {
|
||||
|
||||
<div>
|
||||
<div class="flex items-center justify-between">
|
||||
<label for="register-repeat" class="block text-sm font-medium leading-6 text-gray-900">Repeat assword</label>
|
||||
<label for="register-repeat" class="block text-sm font-medium leading-6 text-gray-900">
|
||||
Repeat assword
|
||||
<b style={{ color: "red" }}> *</b>
|
||||
</label>
|
||||
</div>
|
||||
<div class="mt-2">
|
||||
<input
|
||||
@ -247,9 +284,18 @@ function RegistrationForm({ onComplete }: { onComplete: () => void }): VNode {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div class="flex w-full justify-between">
|
||||
<button type="submit"
|
||||
class="flex w-full justify-center rounded-md bg-indigo-600 disabled:bg-gray-300 px-3 py-1.5 text-sm font-semibold leading-6 text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600"
|
||||
class="ring-1 ring-gray-600 rounded-md bg-white disabled:bg-gray-300 px-3 py-1.5 text-sm font-semibold leading-6 text-black shadow-sm hover:bg-white-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2"
|
||||
onClick={(e) => {
|
||||
e.preventDefault()
|
||||
onCancel()
|
||||
}}
|
||||
>
|
||||
<i18n.Translate>Cancel</i18n.Translate>
|
||||
</button>
|
||||
<button type="submit"
|
||||
class=" rounded-md bg-indigo-600 disabled:bg-gray-300 px-3 py-1.5 text-sm font-semibold leading-6 text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600"
|
||||
disabled={!!errors}
|
||||
onClick={(e) => {
|
||||
e.preventDefault()
|
||||
|
@ -1,5 +0,0 @@
|
||||
import { VNode, h } from "preact";
|
||||
|
||||
export function Test(): VNode {
|
||||
return <div >hola</div>
|
||||
}
|
@ -307,7 +307,6 @@ export function WalletWithdrawForm({
|
||||
<OperationState
|
||||
currency={limit.currency}
|
||||
onClose={onCancel}
|
||||
goToConfirmOperation={goToConfirmOperation}
|
||||
/>
|
||||
}
|
||||
</div>
|
||||
|
@ -78,7 +78,7 @@ export interface DetailsMap {
|
||||
stack?: string;
|
||||
};
|
||||
[TalerErrorCode.WALLET_BANK_INTEGRATION_PROTOCOL_VERSION_INCOMPATIBLE]: {
|
||||
exchangeProtocolVersion: string;
|
||||
bankProtocolVersion: string;
|
||||
walletProtocolVersion: string;
|
||||
};
|
||||
[TalerErrorCode.WALLET_CORE_API_OPERATION_UNKNOWN]: {
|
||||
|
@ -570,7 +570,7 @@ export async function getBankWithdrawalInfo(
|
||||
throw TalerError.fromDetail(
|
||||
TalerErrorCode.WALLET_BANK_INTEGRATION_PROTOCOL_VERSION_INCOMPATIBLE,
|
||||
{
|
||||
exchangeProtocolVersion: config.version,
|
||||
bankProtocolVersion: config.version,
|
||||
walletProtocolVersion: WALLET_BANK_INTEGRATION_PROTOCOL_VERSION,
|
||||
},
|
||||
"bank integration protocol version not compatible with wallet",
|
||||
@ -813,10 +813,10 @@ async function handleKycRequired(
|
||||
amlStatus === AmlStatus.normal || amlStatus === undefined
|
||||
? WithdrawalGroupStatus.PendingKyc
|
||||
: amlStatus === AmlStatus.pending
|
||||
? WithdrawalGroupStatus.PendingAml
|
||||
: amlStatus === AmlStatus.fronzen
|
||||
? WithdrawalGroupStatus.SuspendedAml
|
||||
: assertUnreachable(amlStatus);
|
||||
? WithdrawalGroupStatus.PendingAml
|
||||
: amlStatus === AmlStatus.fronzen
|
||||
? WithdrawalGroupStatus.SuspendedAml
|
||||
: assertUnreachable(amlStatus);
|
||||
|
||||
await tx.withdrawalGroups.put(wg2);
|
||||
const newTxState = computeWithdrawalTransactionStatus(wg2);
|
||||
@ -1145,8 +1145,7 @@ export async function updateWithdrawalDenoms(
|
||||
denom.verificationStatus === DenominationVerificationStatus.Unverified
|
||||
) {
|
||||
logger.trace(
|
||||
`Validating denomination (${current + 1}/${
|
||||
denominations.length
|
||||
`Validating denomination (${current + 1}/${denominations.length
|
||||
}) signature of ${denom.denomPubHash}`,
|
||||
);
|
||||
let valid = false;
|
||||
@ -1240,7 +1239,7 @@ async function queryReserve(
|
||||
if (
|
||||
resp.status === 404 &&
|
||||
result.talerErrorResponse.code ===
|
||||
TalerErrorCode.EXCHANGE_RESERVES_STATUS_UNKNOWN
|
||||
TalerErrorCode.EXCHANGE_RESERVES_STATUS_UNKNOWN
|
||||
) {
|
||||
return { ready: false };
|
||||
} else {
|
||||
@ -1775,7 +1774,7 @@ export async function getExchangeWithdrawalInfo(
|
||||
) {
|
||||
logger.warn(
|
||||
`wallet's support for exchange protocol version ${WALLET_EXCHANGE_PROTOCOL_VERSION} might be outdated ` +
|
||||
`(exchange has ${exchangeDetails.protocolVersionRange}), checking for updates`,
|
||||
`(exchange has ${exchangeDetails.protocolVersionRange}), checking for updates`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ export const WALLET_EXCHANGE_PROTOCOL_VERSION = "17:0:0";
|
||||
export const WALLET_MERCHANT_PROTOCOL_VERSION = "2:0:1";
|
||||
|
||||
/**
|
||||
* Protocol version spoken with the merchant.
|
||||
* Protocol version spoken with the bank.
|
||||
*
|
||||
* Uses libtool's current:revision:age versioning.
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user