diff --git a/packages/taler-util/src/amounts.ts b/packages/taler-util/src/amounts.ts index e472de503..f0434be0e 100644 --- a/packages/taler-util/src/amounts.ts +++ b/packages/taler-util/src/amounts.ts @@ -402,6 +402,12 @@ export class Amounts { */ static stringify(a: AmountLike): string { a = Amounts.jsonifyAmount(a); + const s = this.stringifyValue(a) + + return `${a.currency}:${s}`; + } + + static stringifyValue(a: AmountJson): string { const av = a.value + Math.floor(a.fraction / amountFractionalBase); const af = a.fraction % amountFractionalBase; let s = av.toString(); @@ -417,7 +423,6 @@ export class Amounts { n = (n * 10) % amountFractionalBase; } } - - return `${a.currency}:${s}`; + return s } } diff --git a/packages/taler-wallet-webextension/.storybook/preview.js b/packages/taler-wallet-webextension/.storybook/preview.js index 920e6b1ca..488663469 100644 --- a/packages/taler-wallet-webextension/.storybook/preview.js +++ b/packages/taler-wallet-webextension/.storybook/preview.js @@ -158,8 +158,6 @@ export const decorators = [ - - } diff --git a/packages/taler-wallet-webextension/src/components/styled/index.tsx b/packages/taler-wallet-webextension/src/components/styled/index.tsx index 66595d84c..8f795ce83 100644 --- a/packages/taler-wallet-webextension/src/components/styled/index.tsx +++ b/packages/taler-wallet-webextension/src/components/styled/index.tsx @@ -85,6 +85,7 @@ export const WalletBox = styled.div<{ noPadding?: boolean }>` flex-direction: row; justify-content: space-between; display: flex; + background-color: #f7f7f7; & button { margin-right: 8px; margin-left: 8px; @@ -199,6 +200,33 @@ export const Button = styled.button` } `; +export const FontIcon = styled.div` + font-family: monospace; + font-size: x-large; + text-align: center; + font-weight: bold; + /* vertical-align: text-top; */ +` +export const ButtonBox = styled(Button)` + padding: .5em; + width: 2em; + height: 2em; + + & > ${FontIcon} { + width: 1em; + height: 1em; + display: inline; + line-height: 0px; + } + background-color: transparent; + + border: 1px solid; + border-radius: 4px; + border-color: black; + color: black; +` + + const ButtonVariant = styled(Button)` color: white; border-radius: 4px; @@ -208,18 +236,35 @@ const ButtonVariant = styled(Button)` export const ButtonPrimary = styled(ButtonVariant)` background-color: rgb(66, 184, 221); ` +export const ButtonBoxPrimary = styled(ButtonBox)` + color: rgb(66, 184, 221); + border-color: rgb(66, 184, 221); +` export const ButtonSuccess = styled(ButtonVariant)` background-color: rgb(28, 184, 65); ` +export const ButtonBoxSuccess = styled(ButtonBox)` + color: rgb(28, 184, 65); + border-color: rgb(28, 184, 65); +` export const ButtonWarning = styled(ButtonVariant)` background-color: rgb(223, 117, 20); ` +export const ButtonBoxWarning = styled(ButtonBox)` + color: rgb(223, 117, 20); + border-color: rgb(223, 117, 20); +` export const ButtonDestructive = styled(ButtonVariant)` background-color: rgb(202, 60, 60); ` +export const ButtonBoxDestructive = styled(ButtonBox)` + color: rgb(202, 60, 60); + border-color: rgb(202, 60, 60); +` + export const BoldLight = styled.div` color: gray; @@ -336,6 +381,7 @@ export const CenteredTextBold = styled(CenteredText)` font-weight: bold; color: ${((props: any): any => String(props.color) as any) as any}; ` + export const Input = styled.div<{ invalid?: boolean }>` & label { display: block; @@ -359,7 +405,7 @@ export const ErrorBox = styled.div` /* margin: 0.5em; */ padding-left: 1em; padding-right: 1em; - width: 100%; + /* width: 100%; */ color: #721c24; background: #f8d7da; diff --git a/packages/taler-wallet-webextension/src/popup/ProviderDetailPage.tsx b/packages/taler-wallet-webextension/src/popup/ProviderDetailPage.tsx index bfc32a8f3..83d94ac0f 100644 --- a/packages/taler-wallet-webextension/src/popup/ProviderDetailPage.tsx +++ b/packages/taler-wallet-webextension/src/popup/ProviderDetailPage.tsx @@ -58,9 +58,7 @@ export function ProviderView({ info, onDelete, onSync, onBack, onExtend }: ViewP const isPaid = info.paymentStatus.type === ProviderPaymentType.Paid || info.paymentStatus.type === ProviderPaymentType.TermsChanged return ( - {info.backupProblem || info.lastError ? - - : undefined } + {info.name} {info.syncProviderBaseUrl} {isPaid ? 'Paid' : 'Unpaid'} diff --git a/packages/taler-wallet-webextension/src/wallet/ProviderDetailPage.tsx b/packages/taler-wallet-webextension/src/wallet/ProviderDetailPage.tsx index fc361f625..871e30b71 100644 --- a/packages/taler-wallet-webextension/src/wallet/ProviderDetailPage.tsx +++ b/packages/taler-wallet-webextension/src/wallet/ProviderDetailPage.tsx @@ -58,9 +58,7 @@ export function ProviderView({ info, onDelete, onSync, onBack, onExtend }: ViewP const isPaid = info.paymentStatus.type === ProviderPaymentType.Paid || info.paymentStatus.type === ProviderPaymentType.TermsChanged return ( - {info.backupProblem || info.lastError ? - - : undefined } + {info.name} {info.syncProviderBaseUrl} {isPaid ? 'Paid' : 'Unpaid'} diff --git a/packages/taler-wallet-webextension/src/wallet/Transaction.stories.tsx b/packages/taler-wallet-webextension/src/wallet/Transaction.stories.tsx index 0f7ea457d..535509cef 100644 --- a/packages/taler-wallet-webextension/src/wallet/Transaction.stories.tsx +++ b/packages/taler-wallet-webextension/src/wallet/Transaction.stories.tsx @@ -40,8 +40,8 @@ export default { }; const commonTransaction = { - amountRaw: 'USD:10', - amountEffective: 'USD:9', + amountRaw: 'KUDOS:11', + amountEffective: 'KUDOS:9.2', pending: false, timestamp: { t_ms: new Date().getTime() @@ -62,7 +62,7 @@ const exampleData = { } as TransactionWithdrawal, payment: { ...commonTransaction, - amountEffective: 'USD:11', + amountEffective: 'KUDOS:11', type: TransactionType.Payment, info: { contractTermsHash: 'ASDZXCASD', @@ -147,7 +147,7 @@ export const PaymentError = createExample(TestedComponent, { export const PaymentWithoutFee = createExample(TestedComponent, { transaction: { ...exampleData.payment, - amountRaw: 'USD:11', + amountRaw: 'KUDOS:11', } }); diff --git a/packages/taler-wallet-webextension/src/wallet/Transaction.tsx b/packages/taler-wallet-webextension/src/wallet/Transaction.tsx index d00abc16a..ad00b3d1b 100644 --- a/packages/taler-wallet-webextension/src/wallet/Transaction.tsx +++ b/packages/taler-wallet-webextension/src/wallet/Transaction.tsx @@ -14,7 +14,7 @@ TALER; see the file COPYING. If not, see */ -import { AmountJson, Amounts, i18n, Transaction, TransactionType } from "@gnu-taler/taler-util"; +import { AmountJson, AmountLike, Amounts, i18n, Transaction, TransactionType } from "@gnu-taler/taler-util"; import { format } from "date-fns"; import { Fragment, JSX, VNode, h } from "preact"; import { route } from 'preact-router'; @@ -22,7 +22,7 @@ import { useEffect, useState } from "preact/hooks"; import * as wxApi from "../wxApi"; import { Pages } from "../NavigationBar"; import emptyImg from "../../static/img/empty.png" -import { Button, ButtonDestructive, ButtonPrimary, ListOfProducts, PopupBox, Row, RowBorderGray, SmallTextLight, WalletBox } from "../components/styled"; +import { Button, ButtonBox, ButtonBoxDestructive, ButtonDestructive, ButtonPrimary, ExtraLargeText, FontIcon, LargeText, ListOfProducts, PopupBox, Row, RowBorderGray, SmallTextLight, WalletBox } from "../components/styled"; import { ErrorMessage } from "../components/ErrorMessage"; export function TransactionPage({ tid }: { tid: string; }): JSX.Element { @@ -73,43 +73,54 @@ export function TransactionView({ transaction, onDelete, onRetry, onBack }: Wall return null } - function Fee({ value }: { value: AmountJson }) { - if (Amounts.isZero(value)) return null - return (fee {Amounts.stringify(value)}) - } - - function TransactionTemplate({ upperRight, children }: { upperRight: VNode, children: VNode[] }) { + function TransactionTemplate({ children }: { children: VNode[] }) { return - - - {transaction.timestamp.t_ms === "never" ? "never" : format(transaction.timestamp.t_ms, 'dd/MM/yyyy HH:mm:ss')} - - - {upperRight} - - - {children} + + {children} + } + type Kind = 'positive' | 'negative' | 'neutral'; + function Part({ text, title, kind, big }: { title: string, text: AmountLike, kind: Kind, big?: boolean }) { + const Text = big ? ExtraLargeText : LargeText; + return + {title} + + {text} + + + } + + function amountToString(text: AmountLike) { + const aj = Amounts.jsonifyAmount(text) + const amount = Amounts.stringifyValue(aj) + return `${amount} ${aj.currency}` + } + if (transaction.type === TransactionType.Withdrawal) { const fee = Amounts.sub( Amounts.parseOrThrow(transaction.amountRaw), Amounts.parseOrThrow(transaction.amountEffective), ).amount - return From {transaction.exchangeBaseUrl}}> - Withdraw - {transaction.amountEffective} + return + Withdrawal + {transaction.timestamp.t_ms === 'never' ? 'never': format(transaction.timestamp.t_ms, 'dd MMMM yyyy, HH:mm')} + + + + + } @@ -123,13 +134,17 @@ export function TransactionView({ transaction, onDelete, onRetry, onBack }: Wall Amounts.parseOrThrow(transaction.amountRaw), ).amount - return To {transaction.info.merchant.name}}> - Payment - {transaction.amountEffective} - #{transaction.info.orderId} - - {transaction.info.summary} - + return + Payment + {transaction.timestamp.t_ms === 'never' ? 'never': format(transaction.timestamp.t_ms, 'dd MMMM yyyy, HH:mm')} + + + + + + + + {transaction.info.products && transaction.info.products.length > 0 && @@ -153,9 +168,13 @@ export function TransactionView({ transaction, onDelete, onRetry, onBack }: Wall Amounts.parseOrThrow(transaction.amountRaw), Amounts.parseOrThrow(transaction.amountEffective), ).amount - return To {transaction.targetPaytoUri}}> - Deposit - {transaction.amountEffective} + return + Deposit + {transaction.timestamp.t_ms === 'never' ? 'never': format(transaction.timestamp.t_ms, 'dd MMMM yyyy, HH:mm')} + + + + } @@ -164,9 +183,13 @@ export function TransactionView({ transaction, onDelete, onRetry, onBack }: Wall Amounts.parseOrThrow(transaction.amountRaw), Amounts.parseOrThrow(transaction.amountEffective), ).amount - return From {transaction.exchangeBaseUrl}}> - Refresh - {transaction.amountEffective} + return + Refresh + {transaction.timestamp.t_ms === 'never' ? 'never': format(transaction.timestamp.t_ms, 'dd MMMM yyyy, HH:mm')} + + + + } @@ -175,9 +198,13 @@ export function TransactionView({ transaction, onDelete, onRetry, onBack }: Wall Amounts.parseOrThrow(transaction.amountRaw), Amounts.parseOrThrow(transaction.amountEffective), ).amount - return From {transaction.merchantBaseUrl}}> - Tip - {transaction.amountEffective} + return + Tip + {transaction.timestamp.t_ms === 'never' ? 'never': format(transaction.timestamp.t_ms, 'dd MMMM yyyy, HH:mm')} + + + + } @@ -186,11 +213,17 @@ export function TransactionView({ transaction, onDelete, onRetry, onBack }: Wall Amounts.parseOrThrow(transaction.amountRaw), Amounts.parseOrThrow(transaction.amountEffective), ).amount - return From {transaction.info.merchant.name}}> - Refund - {transaction.amountEffective} + return + Refund + {transaction.timestamp.t_ms === 'never' ? 'never': format(transaction.timestamp.t_ms, 'dd MMMM yyyy, HH:mm')} + + + + + + + - #{transaction.info.orderId} {transaction.info.summary}
- {transaction.info.summary} -
{transaction.info.summary}