/*
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 { ExchangeListItem } from "@gnu-taler/taler-util";
import { useState } from "preact/hooks";
import { useAlertContext } from "../context/alert.js";
import { ButtonHandler } from "../mui/handlers.js";
type State = State.Ready | State.NoExchangeFound | State.Selecting;
export namespace State {
export interface NoExchangeFound {
status: "no-exchange-found";
error: undefined;
currency: string;
defaultExchange: string | undefined;
}
export interface Ready {
status: "ready";
doSelect: ButtonHandler;
selected: ExchangeListItem;
}
export interface Selecting {
status: "selecting-exchange";
error: undefined;
onSelection: (url: string) => Promise;
onCancel: () => Promise;
list: ExchangeListItem[];
currency: string;
initialValue: string;
}
}
interface Props {
currency: string;
//there is a preference for the default at the initial state
defaultExchange?: string;
//list of exchanges
list: ExchangeListItem[];
}
export function useSelectedExchange({
currency,
defaultExchange,
list,
}: Props): State {
const [isSelecting, setIsSelecting] = useState(false);
const [selectedExchange, setSelectedExchange] = useState(
undefined,
);
const { pushAlertOnError } = useAlertContext();
if (!list.length) {
return {
status: "no-exchange-found",
error: undefined,
currency,
defaultExchange,
};
}
const exchangesWithThisCurrency = list.filter((e) => e.currency === currency);
if (!exchangesWithThisCurrency.length) {
// there should be at least one exchange for this currency
return {
status: "no-exchange-found",
error: undefined,
currency,
defaultExchange,
};
}
if (isSelecting) {
const currentExchange =
selectedExchange ??
defaultExchange ??
exchangesWithThisCurrency[0].exchangeBaseUrl;
return {
status: "selecting-exchange",
error: undefined,
list: exchangesWithThisCurrency,
currency,
initialValue: currentExchange,
onSelection: async (exchangeBaseUrl: string) => {
setIsSelecting(false);
setSelectedExchange(exchangeBaseUrl);
},
onCancel: async () => {
setIsSelecting(false);
},
};
}
{
const found = !selectedExchange
? undefined
: list.find((e) => e.exchangeBaseUrl === selectedExchange);
if (found)
return {
status: "ready",
doSelect: {
onClick: pushAlertOnError(async () => setIsSelecting(true)),
},
selected: found,
};
}
{
const found = !defaultExchange
? undefined
: list.find((e) => e.exchangeBaseUrl === defaultExchange);
if (found)
return {
status: "ready",
doSelect: {
onClick: pushAlertOnError(async () => setIsSelecting(true)),
},
selected: found,
};
}
return {
status: "ready",
doSelect: {
onClick: pushAlertOnError(async () => setIsSelecting(true)),
},
selected: exchangesWithThisCurrency[0],
};
}