diff --git a/packages/taler-wallet-webextension/src/components/styled/index.tsx b/packages/taler-wallet-webextension/src/components/styled/index.tsx index 434e3350a..7d8118392 100644 --- a/packages/taler-wallet-webextension/src/components/styled/index.tsx +++ b/packages/taler-wallet-webextension/src/components/styled/index.tsx @@ -4,7 +4,7 @@ import type * as Linaria from '@linaria/core'; import { styled } from '@linaria/react'; -export const PaymentStatus = styled.span<{color:string}>` +export const PaymentStatus = styled.span<{ color: string }>` padding: 5px; border-radius: 5px; color: white; @@ -136,20 +136,53 @@ export const Centered = styled.div` ` export const Row = styled.div` display: flex; - border: 1px solid gray; - border-radius: 0.5em; margin: 0.5em 0; justify-content: space-between; padding: 0.5em; ` +export const Column = styled.div` + display: flex; + flex-direction: column; + margin: 0em 1em; + justify-content: space-between; +` + +export const RowBorderGray = styled(Row)` + border: 1px solid gray; + border-radius: 0.5em; +` + +export const HistoryRow = styled(RowBorderGray)` + & > ${Column}:last-of-type { + margin-left: auto; + align-self: center; + } +` + +export const ListOfProducts = styled.div` + & > div > a > img { + max-width: 100%; + display: inline-block; + + width: 32px; + height: 32px; + } + & > div > div { + margin-right: auto; + margin-left: 1em; + } +` + export const LightText = styled.div` color: gray; ` export const SmallText = styled.div` font-size: small; - margin-top: 0.5em; +` +export const ExtraLargeText = styled.div` + font-size: x-large; ` export const SmallTextLight = styled(SmallText)` diff --git a/packages/taler-wallet-webextension/src/popup/BackupPage.tsx b/packages/taler-wallet-webextension/src/popup/BackupPage.tsx index c2067ad21..9428922d5 100644 --- a/packages/taler-wallet-webextension/src/popup/BackupPage.tsx +++ b/packages/taler-wallet-webextension/src/popup/BackupPage.tsx @@ -21,7 +21,7 @@ import { differenceInMonths, formatDuration, intervalToDuration } from "date-fns import { FunctionalComponent, Fragment, JSX, VNode, AnyComponent } from "preact"; import { BoldLight, ButtonPrimary, ButtonSuccess, Centered, - CenteredText, CenteredTextBold, PopupBox, Row, + CenteredText, CenteredTextBold, PopupBox, RowBorderGray, SmallText, SmallTextLight } from "../components/styled"; import { useBackupStatus } from "../hooks/useBackupStatus"; @@ -94,12 +94,12 @@ function BackupLayout(props: TransactionLayoutProps): JSX.Element { return ( - +
{props.title} - {dateStr && Last synced: {dateStr}} - {!dateStr && Not synced} + {dateStr && Last synced: {dateStr}} + {!dateStr && Not synced}
{props.status?.type === 'paid' ? @@ -107,7 +107,7 @@ function BackupLayout(props: TransactionLayoutProps): JSX.Element {
{props.status.type}
}
-
+ ); } diff --git a/packages/taler-wallet-webextension/src/popup/History.tsx b/packages/taler-wallet-webextension/src/popup/History.tsx index e76e656c1..57fc10c26 100644 --- a/packages/taler-wallet-webextension/src/popup/History.tsx +++ b/packages/taler-wallet-webextension/src/popup/History.tsx @@ -42,11 +42,13 @@ export function HistoryPage(props: any): JSX.Element { } export function HistoryView({ list }: { list: Transaction[] }) { - return
- {list.map((tx, i) => ( - - ))} -
+ return +
+ {list.map((tx, i) => ( + + ))} +
+
} import imageBank from '../../static/img/ri-bank-line.svg'; @@ -54,6 +56,7 @@ import imageShoppingCart from '../../static/img/ri-shopping-cart-line.svg'; import imageRefund from '../../static/img/ri-refund-2-line.svg'; import imageHandHeart from '../../static/img/ri-hand-heart-line.svg'; import imageRefresh from '../../static/img/ri-refresh-line.svg'; +import { Column, ExtraLargeText, HistoryRow, PopupBox, Row, RowBorderGray, SmallTextLight } from "../components/styled"; function TransactionItem(props: { tx: Transaction }): JSX.Element { const tx = props.tx; @@ -146,37 +149,25 @@ function TransactionLayout(props: TransactionLayoutProps): JSX.Element { timeStyle: "short", } as any); return ( -
+ -
-
{dateStr}
-
+ + {dateStr} + {props.title} {props.pending ? ( (Pending) ) : null} -
+
{props.subtitle}
-
+ -
+ ); } @@ -210,24 +201,14 @@ function TransactionAmount(props: TransactionAmountProps): JSX.Element { case "unknown": sign = ""; } - const style: JSX.AllCSSProperties = { - marginLeft: "auto", - display: "flex", - flexDirection: "column", - alignItems: "center", - alignSelf: "center" - }; - if (props.pending) { - style.color = "gray"; - } return ( -
-
+ + {sign} {amount} -
+
{currency}
-
+ ); } diff --git a/packages/taler-wallet-webextension/src/popup/Transaction.stories.tsx b/packages/taler-wallet-webextension/src/popup/Transaction.stories.tsx index 00108aac6..3c0bed6c7 100644 --- a/packages/taler-wallet-webextension/src/popup/Transaction.stories.tsx +++ b/packages/taler-wallet-webextension/src/popup/Transaction.stories.tsx @@ -123,8 +123,6 @@ function createExample(Component: FunctionalComponent, props: Part return r } -export const NotYetLoaded = createExample(TestedComponent, {}); - export const Withdraw = createExample(TestedComponent, { transaction: exampleData.withdraw }); diff --git a/packages/taler-wallet-webextension/src/popup/Transaction.tsx b/packages/taler-wallet-webextension/src/popup/Transaction.tsx index c5274da58..fd7389c04 100644 --- a/packages/taler-wallet-webextension/src/popup/Transaction.tsx +++ b/packages/taler-wallet-webextension/src/popup/Transaction.tsx @@ -16,12 +16,14 @@ import { AmountJson, Amounts, i18n, Transaction, TransactionType } from "@gnu-taler/taler-util"; import { format } from "date-fns"; -import { Fragment, JSX } from "preact"; +import { Fragment, JSX, VNode } from "preact"; import { route } from 'preact-router'; import { useEffect, useState } from "preact/hooks"; import * as wxApi from "../wxApi"; import { Pages } from "./popup"; import emptyImg from "../../static/img/empty.png" +import { Button, ButtonDestructive, ButtonPrimary, ListOfProducts, PopupBox, Row, RowBorderGray, SmallTextLight } from "../components/styled"; +import { ErrorMessage } from "../components/ErrorMessage"; export function TransactionPage({ tid }: { tid: string; }): JSX.Element { const [transaction, setTransaction] = useState< @@ -41,6 +43,9 @@ export function TransactionPage({ tid }: { tid: string; }): JSX.Element { fetchData(); }, []); + if (!transaction) { + return
Loading ...
; + } return wxApi.deleteTransaction(tid).then(_ => history.go(-1))} @@ -49,65 +54,63 @@ export function TransactionPage({ tid }: { tid: string; }): JSX.Element { } export interface WalletTransactionProps { - transaction?: Transaction, + transaction: Transaction, onDelete: () => void, onRetry: () => void, onBack: () => void, } + export function TransactionView({ transaction, onDelete, onRetry, onBack }: WalletTransactionProps) { - if (!transaction) { - return
Loading ...
; - } - - function Footer() { - return
- -
- {transaction?.error ? : null } - -
- -
- } function Status() { - if (transaction?.error) { + if (transaction.error) { return (failed) } - if (!transaction?.pending) return null - return (pending...) + if (transaction.pending) { + return (pending...) + } + return null } - function Error() { - if (!transaction?.error) return null - return
-

{transaction.error.hint}

-
+ function Fee({ value }: { value: AmountJson }) { + if (Amounts.isZero(value)) return null + return (fee {Amounts.stringify(value)}) } - const Fee = ({ value }: { value: AmountJson }) => Amounts.isNonZero(value) ? - (fee {Amounts.stringify(value)}) : null + function TransactionTemplate({ upperRight, children }: { upperRight: VNode, children: VNode[] }) { + return +
+ + {transaction.timestamp.t_ms === "never" ? "never" : format(transaction.timestamp.t_ms, 'dd/MM/yyyy HH:mm:ss')} + + + {upperRight} + +
+
+ + {children} +
+
+ +
+ {transaction?.error ? retry : null} + delete +
+
+
+ } if (transaction.type === TransactionType.Withdrawal) { const fee = Amounts.sub( Amounts.parseOrThrow(transaction.amountRaw), Amounts.parseOrThrow(transaction.amountEffective), ).amount - return ( -
-
- {transaction.timestamp.t_ms === "never" ? "never" : format(transaction.timestamp.t_ms, 'dd/MM/yyyy HH:mm:ss')} - - From {transaction.exchangeBaseUrl} - - -

Withdraw

-

{transaction.amountEffective}

-
-
-
- ); + return From {transaction.exchangeBaseUrl}}> +

Withdraw

+

{transaction.amountEffective}

+
} const showLargePic = () => { @@ -120,38 +123,29 @@ export function TransactionView({ transaction, onDelete, onRetry, onBack }: Wall Amounts.parseOrThrow(transaction.amountRaw), ).amount - return ( -
-
- {transaction.timestamp.t_ms === "never" ? "never" : format(transaction.timestamp.t_ms, 'dd/MM/yyyy HH:mm:ss')} - - To {transaction.info.merchant.name} - - -

Payment

-

{transaction.amountEffective}

- #{transaction.info.orderId} -

- {transaction.info.summary} -

-
- {transaction.info.products && transaction.info.products.length > 0 &&
- {transaction.info.products.map(p =>
- - - -
- {p.quantity && p.quantity > 0 &&
x {p.quantity} {p.unit}
} -
{p.description}
-
-
)} -
- } -
-
-