/* 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 { Fragment, h, VNode } from "preact"; import { LoadingError } from "../../components/LoadingError.js"; import { LogoHeader } from "../../components/LogoHeader.js"; import { Input, LinkPrimary, SubTitle, SvgIcon, WalletAction, } from "../../components/styled/index.js"; import { useTranslationContext } from "../../context/translation.js"; import { FeeDescription, FeeDescriptionPair, State } from "./index.js"; import { styled } from "@linaria/react"; import arrowDown from "../../svg/chevron-down.svg"; import { Amount } from "../../components/Amount.js"; import { Time } from "../../components/Time.js"; import { AbsoluteTime, AmountJson, Amounts } from "@gnu-taler/taler-util"; import { Button } from "../../mui/Button.js"; import { SelectList } from "../../components/SelectList.js"; import { useState } from "preact/hooks"; const ButtonGroup = styled.div` & > button { margin-left: 8px; margin-right: 8px; } `; const FeeDescriptionTable = styled.table` & { margin-bottom: 20px; width: 100%; border-collapse: collapse; } td { padding: 8px; } td.fee { text-align: center; } th.fee { text-align: center; } td.value { text-align: right; width: 1%; white-space: nowrap; } td.icon { width: 24px; } td.icon > div { width: 24px; height: 24px; margin: 0px; } td.expiration { text-align: center; } tr[data-main="true"] { background-color: #add8e662; } tr[data-main="true"] > td.value, tr[data-main="true"] > td.expiration, tr[data-main="true"] > td.fee { border-bottom: lightgray solid 1px; } tr[data-hidden="true"] { display: none; } tbody > tr.value[data-hasMore="true"], tbody > tr.value[data-hasMore="true"] > td { cursor: pointer; } th { position: sticky; top: 0; background-color: white; } `; const Container = styled.div` display: flex; flex-direction: column; & > * { margin-bottom: 20px; } `; export function LoadingUriView({ error }: State.LoadingUriError): VNode { const { i18n } = useTranslationContext(); return ( Could not load tip status} error={error} /> ); } export function NoExchangesView(state: State.NoExchanges): VNode { const { i18n } = useTranslationContext(); return
no exchanges
; } export function ComparingView({ exchanges, selected, nextFeeUpdate, onReset, onSelect, pairTimeline, }: State.Comparing): VNode { const { i18n } = useTranslationContext(); return (

Service fee description

Select {selected.currency} exchange } list={exchanges.list} name="lang" value={exchanges.value} onChange={exchanges.onChange} />

Auditors
{selected.auditors.length === 0 ? (
Doesn't have auditors
) : ( selected.auditors.map((a) => {
{a.auditor_url}
; }) )}
currency {selected.currency}
next fee update {

Operations

Deposits

  Denomination Fee Until

Withdrawals

  Denomination Fee Until

Refunds

  Denomination Fee Until {" "}

Refresh

  Denomination Fee Until {" "}
Wallet operations Fee
history(i) 0.1
kyc (i) 0.1
account (i) 0.1
purse (i) 0.1
wire SEPA (i) 0.1
closing SEPA(i) 0.1
wad SEPA (i) 0.1
Privacy policy Terms of service
); } export function ReadyView({ exchanges, selected, nextFeeUpdate, onClose, timeline, }: State.Ready): VNode { const { i18n } = useTranslationContext(); return (

Service fee description

Select {selected.currency} exchange } list={exchanges.list} name="lang" value={exchanges.value} onChange={exchanges.onChange} />

Auditors
{selected.auditors.length === 0 ? (
Doesn't have auditors
) : ( selected.auditors.map((a) => {
{a.auditor_url}
; }) )}
currency {selected.currency}
next fee update {

Operations

Deposits

  Denomination Fee Until

Withdrawals

  Denomination Fee Until

Refunds

  Denomination Fee Until {" "}

Refresh

  Denomination Fee Until {" "}
Wallet operations Fee
history(i) 0.1
kyc (i) 0.1
account (i) 0.1
purse (i) 0.1
wire SEPA (i) 0.1
closing SEPA(i) 0.1
wad SEPA (i) 0.1
Privacy policy Terms of service
); } function FeeDescriptionRowsGroup({ infos, }: { infos: FeeDescription[]; }): VNode { const [expanded, setExpand] = useState(false); const hasMoreInfo = infos.length > 1; return ( {infos.map((info, idx) => { const main = idx === 0; return ( setExpand((p) => !p)} > {hasMoreInfo && main ? ( ) : undefined} {main ? : ""} {info.fee ? ( {} ) : undefined} ); } function FeePairRowsGroup({ infos }: { infos: FeeDescriptionPair[] }): VNode { const [expanded, setExpand] = useState(false); const hasMoreInfo = infos.length > 1; return ( {infos.map((info, idx) => { const main = idx === 0; return ( setExpand((p) => !p)} > {hasMoreInfo && main ? ( ) : undefined} {main ? : ""} {info.left ? ( {} ) : ( --- )} {info.right ? ( {} ) : ( --- )} ); } /** * Group by value and then render using FeePairRowsGroup * @param param0 * @returns */ function RenderFeePairByValue({ list }: { list: FeeDescriptionPair[] }): VNode { return ( { list.reduce( (prev, info, idx) => { const next = idx >= list.length - 1 ? undefined : list[idx + 1]; const nextIsMoreInfo = next !== undefined && Amounts.cmp(next.value, info.value) === 0; prev.rows.push(info); if (nextIsMoreInfo) { return prev; } prev.rows = []; prev.views.push(); return prev; }, { rows: [], views: [] } as { rows: FeeDescriptionPair[]; views: h.JSX.Element[]; }, ).views } ); } /** * * Group by value and then render using FeeDescriptionRowsGroup * @param param0 * @returns */ function RenderFeeDescriptionByValue({ first, }: { first: FeeDescription[]; }): VNode { return ( { first.reduce( (prev, info, idx) => { const next = idx >= first.length - 1 ? undefined : first[idx + 1]; const nextIsMoreInfo = next !== undefined && Amounts.cmp(next.value, info.value) === 0; prev.rows.push(info); if (nextIsMoreInfo) { return prev; } prev.rows = []; prev.views.push(); return prev; }, { rows: [], views: [] } as { rows: FeeDescription[]; views: h.JSX.Element[]; }, ).views } ); }