summaryrefslogtreecommitdiff
path: root/packages/taler-wallet-webextension/src/popup
diff options
context:
space:
mode:
Diffstat (limited to 'packages/taler-wallet-webextension/src/popup')
-rw-r--r--packages/taler-wallet-webextension/src/popup/History.stories.tsx256
-rw-r--r--packages/taler-wallet-webextension/src/popup/History.tsx34
-rw-r--r--packages/taler-wallet-webextension/src/popup/Transaction.stories.tsx76
-rw-r--r--packages/taler-wallet-webextension/src/popup/Transaction.tsx308
4 files changed, 447 insertions, 227 deletions
diff --git a/packages/taler-wallet-webextension/src/popup/History.stories.tsx b/packages/taler-wallet-webextension/src/popup/History.stories.tsx
new file mode 100644
index 000000000..a73b7ea3f
--- /dev/null
+++ b/packages/taler-wallet-webextension/src/popup/History.stories.tsx
@@ -0,0 +1,256 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 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 <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import {
+ PaymentStatus,
+ TransactionCommon, TransactionDeposit, TransactionPayment,
+ TransactionRefresh, TransactionRefund, TransactionTip, TransactionType,
+ TransactionWithdrawal,
+ WithdrawalType
+} from '@gnu-taler/taler-util';
+import { FunctionalComponent } from 'preact';
+import { HistoryView as TestedComponent } from './History';
+
+export default {
+ title: 'popup/transaction/list',
+ component: TestedComponent,
+ decorators: [
+ (Story: any) => <div>
+ <link key="1" rel="stylesheet" type="text/css" href="/style/pure.css" />
+ <link key="2" rel="stylesheet" type="text/css" href="/style/popup.css" />
+ <link key="3" rel="stylesheet" type="text/css" href="/style/wallet.css" />
+ <div style={{ margin: "1em", width: 400, display: 'flex', padding: '0.5em', height: 'calc(20rem - 34px)', border: 'black solid 1px' }}>
+ <Story />
+ </div>
+ </div>
+ ],
+};
+
+const commonTransaction = {
+ amountRaw: 'USD:10',
+ amountEffective: 'USD:9',
+ pending: false,
+ timestamp: {
+ t_ms: new Date().getTime()
+ },
+ transactionId: '12',
+} as TransactionCommon
+
+const exampleData = {
+ withdraw: {
+ ...commonTransaction,
+ type: TransactionType.Withdrawal,
+ exchangeBaseUrl: 'http://exchange.taler',
+ withdrawalDetails: {
+ confirmed: false,
+ exchangePaytoUris: ['payto://x-taler-bank/bank/account'],
+ type: WithdrawalType.ManualTransfer,
+ }
+ } as TransactionWithdrawal,
+ payment: {
+ ...commonTransaction,
+ amountEffective: 'USD:11',
+ type: TransactionType.Payment,
+ info: {
+ contractTermsHash: 'ASDZXCASD',
+ merchant: {
+ name: 'the merchant',
+ },
+ orderId: '2021.167-03NPY6MCYMVGT',
+ products: [],
+ summary: 'the summary',
+ fulfillmentMessage: '',
+ },
+ proposalId: '1EMJJH8EP1NX3XF7733NCYS2DBEJW4Q2KA5KEB37MCQJQ8Q5HMC0',
+ status: PaymentStatus.Accepted,
+ } as TransactionPayment,
+ deposit: {
+ ...commonTransaction,
+ type: TransactionType.Deposit,
+ depositGroupId: '#groupId',
+ targetPaytoUri: 'payto://x-taler-bank/bank/account',
+ } as TransactionDeposit,
+ refresh: {
+ ...commonTransaction,
+ type: TransactionType.Refresh,
+ exchangeBaseUrl: 'http://exchange.taler',
+ } as TransactionRefresh,
+ tip: {
+ ...commonTransaction,
+ type: TransactionType.Tip,
+ merchantBaseUrl: 'http://merchant.taler',
+ } as TransactionTip,
+ refund: {
+ ...commonTransaction,
+ type: TransactionType.Refund,
+ refundedTransactionId: 'payment:1EMJJH8EP1NX3XF7733NCYS2DBEJW4Q2KA5KEB37MCQJQ8Q5HMC0',
+ info: {
+ contractTermsHash: 'ASDZXCASD',
+ merchant: {
+ name: 'the merchant',
+ },
+ orderId: '2021.167-03NPY6MCYMVGT',
+ products: [],
+ summary: 'the summary',
+ fulfillmentMessage: '',
+ },
+ } as TransactionRefund,
+}
+
+function createExample<Props>(Component: FunctionalComponent<Props>, props: Partial<Props>) {
+ const r = (args: any) => <Component {...args} />
+ r.args = props
+ return r
+}
+
+export const Empty = createExample(TestedComponent, {
+ list: []
+});
+
+
+export const One = createExample(TestedComponent, {
+ list: [exampleData.withdraw]
+});
+
+export const Several = createExample(TestedComponent, {
+ list: [
+ exampleData.withdraw,
+ exampleData.payment,
+ exampleData.withdraw,
+ exampleData.payment,
+ exampleData.refresh,
+ exampleData.refund,
+ exampleData.tip,
+ exampleData.deposit,
+ ]
+});
+
+// export const WithdrawPending = createExample(TestedComponent, {
+// transaction: { ...exampleData.withdraw, pending: true },
+// });
+
+
+// export const Payment = createExample(TestedComponent, {
+// transaction: exampleData.payment
+// });
+
+// export const PaymentWithoutFee = createExample(TestedComponent, {
+// transaction: {
+// ...exampleData.payment,
+// amountRaw: 'USD:11',
+
+// }
+// });
+
+// export const PaymentPending = createExample(TestedComponent, {
+// transaction: { ...exampleData.payment, pending: true },
+// });
+
+// export const PaymentWithProducts = createExample(TestedComponent, {
+// transaction: {
+// ...exampleData.payment,
+// info: {
+// ...exampleData.payment.info,
+// summary: 'this order has 5 products',
+// products: [{
+// description: 't-shirt',
+// unit: 'shirts',
+// quantity: 1,
+// }, {
+// description: 't-shirt',
+// unit: 'shirts',
+// quantity: 1,
+// }, {
+// description: 'e-book',
+// }, {
+// description: 'beer',
+// unit: 'pint',
+// quantity: 15,
+// }, {
+// description: 'beer',
+// unit: 'pint',
+// quantity: 15,
+// }]
+// }
+// } as TransactionPayment,
+// });
+
+// export const PaymentWithLongSummary = createExample(TestedComponent, {
+// transaction: {
+// ...exampleData.payment,
+// info: {
+// ...exampleData.payment.info,
+// summary: 'this is a very long summary that will occupy severals lines, this is a very long summary that will occupy severals lines, this is a very long summary that will occupy severals lines, this is a very long summary that will occupy severals lines, ',
+// products: [{
+// description: 'an xl sized t-shirt with some drawings on it, color pink',
+// unit: 'shirts',
+// quantity: 1,
+// }, {
+// description: 'beer',
+// unit: 'pint',
+// quantity: 15,
+// }]
+// }
+// } as TransactionPayment,
+// });
+
+
+// export const Deposit = createExample(TestedComponent, {
+// transaction: exampleData.deposit
+// });
+
+// export const DepositPending = createExample(TestedComponent, {
+// transaction: { ...exampleData.deposit, pending: true }
+// });
+
+// export const Refresh = createExample(TestedComponent, {
+// transaction: exampleData.refresh
+// });
+
+// export const Tip = createExample(TestedComponent, {
+// transaction: exampleData.tip
+// });
+
+// export const TipPending = createExample(TestedComponent, {
+// transaction: { ...exampleData.tip, pending: true }
+// });
+
+// export const Refund = createExample(TestedComponent, {
+// transaction: exampleData.refund
+// });
+
+// export const RefundPending = createExample(TestedComponent, {
+// transaction: { ...exampleData.refund, pending: true }
+// });
+
+// export const RefundWithProducts = createExample(TestedComponent, {
+// transaction: {
+// ...exampleData.refund,
+// info: {
+// ...exampleData.refund.info,
+// products: [{
+// description: 't-shirt',
+// }, {
+// description: 'beer',
+// }]
+// }
+// } as TransactionRefund,
+// });
diff --git a/packages/taler-wallet-webextension/src/popup/History.tsx b/packages/taler-wallet-webextension/src/popup/History.tsx
index ffcec5e41..1a70f00ff 100644
--- a/packages/taler-wallet-webextension/src/popup/History.tsx
+++ b/packages/taler-wallet-webextension/src/popup/History.tsx
@@ -38,17 +38,23 @@ export function HistoryPage(props: any): JSX.Element {
return <div>Loading ...</div>;
}
- const txs = [...transactions.transactions].reverse();
+ return <HistoryView list={[...transactions.transactions].reverse()} />;
+}
- return (
- <div>
- {txs.map((tx, i) => (
- <TransactionItem key={i} tx={tx} />
- ))}
- </div>
- );
+export function HistoryView({ list }: { list: Transaction[] }) {
+ return <div style={{ height: 'calc(20rem - 34px )', overflow: 'auto', width: '100%' }}>
+ {list.map((tx, i) => (
+ <TransactionItem key={i} tx={tx} />
+ ))}
+ </div>
}
+import imageBank from '../../static/img/ri-bank-line.svg';
+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';
+
function TransactionItem(props: { tx: Transaction }): JSX.Element {
const tx = props.tx;
switch (tx.type) {
@@ -61,7 +67,7 @@ function TransactionItem(props: { tx: Transaction }): JSX.Element {
title="Withdrawal"
subtitle={`via ${tx.exchangeBaseUrl}`}
timestamp={tx.timestamp}
- iconPath="/static/img/ri-bank-line.svg"
+ iconPath={imageBank}
pending={tx.pending}
></TransactionLayout>
);
@@ -74,7 +80,7 @@ function TransactionItem(props: { tx: Transaction }): JSX.Element {
title="Payment"
subtitle={tx.info.summary}
timestamp={tx.timestamp}
- iconPath="/static/img/ri-shopping-cart-line.svg"
+ iconPath={imageShoppingCart}
pending={tx.pending}
></TransactionLayout>
);
@@ -87,7 +93,7 @@ function TransactionItem(props: { tx: Transaction }): JSX.Element {
title="Refund"
subtitle={tx.info.summary}
timestamp={tx.timestamp}
- iconPath="/static/img/ri-refund-2-line.svg"
+ iconPath={imageRefund}
pending={tx.pending}
></TransactionLayout>
);
@@ -100,7 +106,7 @@ function TransactionItem(props: { tx: Transaction }): JSX.Element {
title="Tip"
subtitle={`from ${new URL(tx.merchantBaseUrl).hostname}`}
timestamp={tx.timestamp}
- iconPath="/static/img/ri-hand-heart-line.svg"
+ iconPath={imageHandHeart}
pending={tx.pending}
></TransactionLayout>
);
@@ -113,7 +119,7 @@ function TransactionItem(props: { tx: Transaction }): JSX.Element {
title="Refresh"
subtitle={`via exchange ${tx.exchangeBaseUrl}`}
timestamp={tx.timestamp}
- iconPath="/static/img/ri-refresh-line.svg"
+ iconPath={imageRefresh}
pending={tx.pending}
></TransactionLayout>
);
@@ -126,7 +132,7 @@ function TransactionItem(props: { tx: Transaction }): JSX.Element {
title="Refresh"
subtitle={`to ${tx.targetPaytoUri}`}
timestamp={tx.timestamp}
- iconPath="/static/img/ri-refresh-line.svg"
+ iconPath={imageRefresh}
pending={tx.pending}
></TransactionLayout>
);
diff --git a/packages/taler-wallet-webextension/src/popup/Transaction.stories.tsx b/packages/taler-wallet-webextension/src/popup/Transaction.stories.tsx
index 3df2687fd..bf090cad7 100644
--- a/packages/taler-wallet-webextension/src/popup/Transaction.stories.tsx
+++ b/packages/taler-wallet-webextension/src/popup/Transaction.stories.tsx
@@ -37,7 +37,7 @@ export default {
<link key="1" rel="stylesheet" type="text/css" href="/style/pure.css" />
<link key="2" rel="stylesheet" type="text/css" href="/style/popup.css" />
<link key="3" rel="stylesheet" type="text/css" href="/style/wallet.css" />
- <div style={{ margin: "1em", width: 400 }}>
+ <div style={{ margin: "1em", width: 400, display: 'flex', padding: '0.5em', height: 'calc(20rem - 34px)', border: 'black solid 1px' }}>
<Story />
</div>
</div>
@@ -74,7 +74,7 @@ const exampleData = {
merchant: {
name: 'the merchant',
},
- orderId: '#12345',
+ orderId: '2021.167-03NPY6MCYMVGT',
products: [],
summary: 'the summary',
fulfillmentMessage: '',
@@ -107,7 +107,7 @@ const exampleData = {
merchant: {
name: 'the merchant',
},
- orderId: '#12345',
+ orderId: '2021.167-03NPY6MCYMVGT',
products: [],
summary: 'the summary',
fulfillmentMessage: '',
@@ -121,69 +121,111 @@ function createExample<Props>(Component: FunctionalComponent<Props>, props: Part
return r
}
-export const NotYetLoaded = createExample(TestedComponent,{});
+export const NotYetLoaded = createExample(TestedComponent, {});
-export const Withdraw = createExample(TestedComponent,{
+export const Withdraw = createExample(TestedComponent, {
transaction: exampleData.withdraw
});
-export const WithdrawPending = createExample(TestedComponent,{
+export const WithdrawPending = createExample(TestedComponent, {
transaction: { ...exampleData.withdraw, pending: true },
});
-export const Payment = createExample(TestedComponent,{
+export const Payment = createExample(TestedComponent, {
transaction: exampleData.payment
});
-export const PaymentPending = createExample(TestedComponent,{
+export const PaymentWithoutFee = createExample(TestedComponent, {
+ transaction: {
+ ...exampleData.payment,
+ amountRaw: 'USD:11',
+
+ }
+});
+
+export const PaymentPending = createExample(TestedComponent, {
transaction: { ...exampleData.payment, pending: true },
});
-export const PaymentWithProducts = createExample(TestedComponent,{
+export const PaymentWithProducts = createExample(TestedComponent, {
transaction: {
...exampleData.payment,
info: {
...exampleData.payment.info,
+ summary: 'this order has 5 products',
products: [{
description: 't-shirt',
+ unit: 'shirts',
+ quantity: 1,
+ }, {
+ description: 't-shirt',
+ unit: 'shirts',
+ quantity: 1,
+ }, {
+ description: 'e-book',
+ }, {
+ description: 'beer',
+ unit: 'pint',
+ quantity: 15,
+ }, {
+ description: 'beer',
+ unit: 'pint',
+ quantity: 15,
+ }]
+ }
+ } as TransactionPayment,
+});
+
+export const PaymentWithLongSummary = createExample(TestedComponent, {
+ transaction: {
+ ...exampleData.payment,
+ info: {
+ ...exampleData.payment.info,
+ summary: 'this is a very long summary that will occupy severals lines, this is a very long summary that will occupy severals lines, this is a very long summary that will occupy severals lines, this is a very long summary that will occupy severals lines, ',
+ products: [{
+ description: 'an xl sized t-shirt with some drawings on it, color pink',
+ unit: 'shirts',
+ quantity: 1,
}, {
description: 'beer',
+ unit: 'pint',
+ quantity: 15,
}]
}
} as TransactionPayment,
});
-export const Deposit = createExample(TestedComponent,{
+export const Deposit = createExample(TestedComponent, {
transaction: exampleData.deposit
});
-export const DepositPending = createExample(TestedComponent,{
+export const DepositPending = createExample(TestedComponent, {
transaction: { ...exampleData.deposit, pending: true }
});
-export const Refresh = createExample(TestedComponent,{
+export const Refresh = createExample(TestedComponent, {
transaction: exampleData.refresh
});
-export const Tip = createExample(TestedComponent,{
+export const Tip = createExample(TestedComponent, {
transaction: exampleData.tip
});
-export const TipPending = createExample(TestedComponent,{
+export const TipPending = createExample(TestedComponent, {
transaction: { ...exampleData.tip, pending: true }
});
-export const Refund = createExample(TestedComponent,{
+export const Refund = createExample(TestedComponent, {
transaction: exampleData.refund
});
-export const RefundPending = createExample(TestedComponent,{
+export const RefundPending = createExample(TestedComponent, {
transaction: { ...exampleData.refund, pending: true }
});
-export const RefundWithProducts = createExample(TestedComponent,{
+export const RefundWithProducts = createExample(TestedComponent, {
transaction: {
...exampleData.refund,
info: {
diff --git a/packages/taler-wallet-webextension/src/popup/Transaction.tsx b/packages/taler-wallet-webextension/src/popup/Transaction.tsx
index b1179228e..6939a08c3 100644
--- a/packages/taler-wallet-webextension/src/popup/Transaction.tsx
+++ b/packages/taler-wallet-webextension/src/popup/Transaction.tsx
@@ -14,14 +14,14 @@
TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
*/
-import { Amounts, i18n, Transaction, TransactionType } from "@gnu-taler/taler-util";
+import { AmountJson, Amounts, i18n, Transaction, TransactionType } from "@gnu-taler/taler-util";
import { format } from "date-fns";
-import { JSX } from "preact";
+import { Fragment, JSX } 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"
export function TransactionPage({ tid }: { tid: string; }): JSX.Element {
const [transaction, setTransaction] = useState<
@@ -59,11 +59,10 @@ export function TransactionView({ transaction, onDelete, onBack }: WalletTransac
}
function Footer() {
- return <footer style={{ marginTop: 'auto', display: 'flex' }}>
+ return <footer style={{ marginTop: 'auto', display: 'flex', flexShrink: 0 }}>
<button onClick={onBack}><i18n.Translate>back</i18n.Translate></button>
<div style={{ width: '100%', flexDirection: 'row', justifyContent: 'flex-end', display: 'flex' }}>
- <button onClick={onDelete}><i18n.Translate>remove</i18n.Translate></button>
-
+ <button class="pure-button button-destructive" onClick={onDelete}><i18n.Translate>forget</i18n.Translate></button>
</div>
</footer>
@@ -74,91 +73,66 @@ export function TransactionView({ transaction, onDelete, onBack }: WalletTransac
return <span style={{ fontWeight: 'normal', fontSize: 16, color: 'gray' }}>(pending...)</span>
}
+ const Fee = ({ value }: { value: AmountJson }) => Amounts.isNonZero(value) ?
+ <span style="font-size: 16px;font-weight: normal;color: gray;">(fee {Amounts.stringify(value)})</span> : null
+
if (transaction.type === TransactionType.Withdrawal) {
+ const fee = Amounts.sub(
+ Amounts.parseOrThrow(transaction.amountRaw),
+ Amounts.parseOrThrow(transaction.amountEffective),
+ ).amount
return (
- <div style={{ display: 'flex', flexDirection: 'column', flex: 1, minHeight: '20rem' }} >
- <section>
- <h1>Withdrawal <Pending /></h1>
- <p>
+ <div style={{ display: 'flex', flexDirection: 'column', width: '100%' }} >
+ <section style={{ color: transaction.pending ? 'gray' : '', flex: '1 0 auto', height: 'calc(20rem - 34px - 45px)', overflow: 'auto' }}>
+ <span style="flat: left; font-size:small; color:gray">{transaction.timestamp.t_ms === "never" ? "never" : format(transaction.timestamp.t_ms, 'dd/MM/yyyy HH:mm:ss')}</span>
+ <span style="float: right; font-size:small; color:gray">
From <b>{transaction.exchangeBaseUrl}</b>
- </p>
- <table class={transaction.pending ? "detailsTable pending" : "detailsTable"}>
- <tr>
- <td>Amount subtracted</td>
- <td>{transaction.amountRaw}</td>
- </tr>
- <tr>
- <td>Amount received</td>
- <td>{transaction.amountEffective}</td>
- </tr>
- <tr>
- <td>Exchange fee</td>
- <td>{Amounts.stringify(
- Amounts.sub(
- Amounts.parseOrThrow(transaction.amountRaw),
- Amounts.parseOrThrow(transaction.amountEffective),
- ).amount
- )}</td>
- </tr>
- <tr>
- <td>When</td>
- <td>{transaction.timestamp.t_ms === "never" ? "never" : format(transaction.timestamp.t_ms, 'dd/MM/yyyy HH:mm:ss')}</td>
- </tr>
- </table>
+ </span>
+ <h3>Withdraw <Pending /></h3>
+ <h1>{transaction.amountEffective} <Fee value={fee} /></h1>
</section>
<Footer />
</div>
);
}
+ const showLargePic = () => {
+
+ }
+
if (transaction.type === TransactionType.Payment) {
+ const fee = Amounts.sub(
+ Amounts.parseOrThrow(transaction.amountEffective),
+ Amounts.parseOrThrow(transaction.amountRaw),
+ ).amount
+
return (
- <div style={{ display: 'flex', flexDirection: 'column', flex: 1, minHeight: '20rem' }} >
- <section>
- <h1>Payment ({transaction.proposalId.substring(0, 10)}...) <Pending /></h1>
- <p>
+ <div style={{ display: 'flex', flexDirection: 'column', width: '100%' }} >
+ <section style={{ color: transaction.pending ? 'gray' : '', flex: '1 0 auto', height: 'calc(20rem - 34px - 45px)', overflow: 'auto' }}>
+ <span style="flat: left; font-size:small; color:gray">{transaction.timestamp.t_ms === "never" ? "never" : format(transaction.timestamp.t_ms, 'dd/MM/yyyy HH:mm:ss')}</span>
+ <span style="float: right; font-size:small; color:gray">
To <b>{transaction.info.merchant.name}</b>
+ </span>
+ <h3>Payment <Pending /></h3>
+ <h1>{transaction.amountEffective} <Fee value={fee} /></h1>
+ <span style="font-size:small; color:gray">#{transaction.info.orderId}</span>
+ <p>
+ {transaction.info.summary}
</p>
- <table class={transaction.pending ? "detailsTable pending" : "detailsTable"}>
- <tr>
- <td>Order id</td>
- <td>{transaction.info.orderId}</td>
- </tr>
- <tr>
- <td>Summary</td>
- <td>{transaction.info.summary}</td>
- </tr>
- {transaction.info.products && transaction.info.products.length > 0 &&
- <tr>
- <td>Products</td>
- <td><ol style={{ margin: 0, textAlign: 'left' }}>
- {transaction.info.products.map(p =>
- <li>{p.description}</li>
- )}</ol></td>
- </tr>
+ <div>
+ {transaction.info.products && transaction.info.products.length > 0 && <div>
+ {transaction.info.products.map(p => <div style="display: flex; flex-direction: row; border: 1px solid gray; border-radius: 0.5em; margin: 0.5em 0px; justify-content: left; padding: 0.5em;">
+ <a href="#" onClick={showLargePic}>
+ <img class="pure-img" style="display:inline-block" src={p.image ? p.image : emptyImg} width="32" height="32" />
+ </a>
+ <div style="display: block; margin-left: 1em;">
+ {p.quantity && p.quantity > 0 && <div style="font-size: small; color: gray;">x {p.quantity} {p.unit}</div>}
+ <div style={{ textOverflow: 'ellipsis', overflow: 'hidden', width: 'calc(20rem - 32px - 32px - 8px - 1em)', whiteSpace: 'nowrap' }}>{p.description}</div>
+ </div>
+ </div>)}
+ </div>
}
- <tr>
- <td>Order amount</td>
- <td>{transaction.amountRaw}</td>
- </tr>
- <tr>
- <td>Order amount and fees</td>
- <td>{transaction.amountEffective}</td>
- </tr>
- <tr>
- <td>Exchange fee</td>
- <td>{Amounts.stringify(
- Amounts.sub(
- Amounts.parseOrThrow(transaction.amountEffective),
- Amounts.parseOrThrow(transaction.amountRaw),
- ).amount
- )}</td>
- </tr>
- <tr>
- <td>When</td>
- <td>{transaction.timestamp.t_ms === "never" ? "never" : format(transaction.timestamp.t_ms, 'dd/MM/yyyy HH:mm:ss')}</td>
- </tr>
- </table>
+ </div>
</section>
<Footer />
</div>
@@ -166,36 +140,19 @@ export function TransactionView({ transaction, onDelete, onBack }: WalletTransac
}
if (transaction.type === TransactionType.Deposit) {
+ const fee = Amounts.sub(
+ Amounts.parseOrThrow(transaction.amountRaw),
+ Amounts.parseOrThrow(transaction.amountEffective),
+ ).amount
return (
- <div style={{ display: 'flex', flexDirection: 'column', flex: 1, minHeight: '20rem' }} >
- <section>
- <h1>Deposit ({transaction.depositGroupId}) <Pending /></h1>
- <p>
+ <div style={{ display: 'flex', flexDirection: 'column', width: '100%' }} >
+ <section style={{ color: transaction.pending ? 'gray' : '', flex: '1 0 auto', height: 'calc(20rem - 34px - 45px)', overflow: 'auto' }}>
+ <span style="flat: left; font-size:small; color:gray">{transaction.timestamp.t_ms === "never" ? "never" : format(transaction.timestamp.t_ms, 'dd/MM/yyyy HH:mm:ss')}</span>
+ <span style="float: right; font-size:small; color:gray">
To <b>{transaction.targetPaytoUri}</b>
- </p>
- <table class={transaction.pending ? "detailsTable pending" : "detailsTable"}>
- <tr>
- <td>Amount deposit</td>
- <td>{transaction.amountRaw}</td>
- </tr>
- <tr>
- <td>Amount deposit and fees</td>
- <td>{transaction.amountEffective}</td>
- </tr>
- <tr>
- <td>Exchange fee</td>
- <td>{Amounts.stringify(
- Amounts.sub(
- Amounts.parseOrThrow(transaction.amountEffective),
- Amounts.parseOrThrow(transaction.amountRaw),
- ).amount
- )}</td>
- </tr>
- <tr>
- <td>When</td>
- <td>{transaction.timestamp.t_ms === "never" ? "never" : format(transaction.timestamp.t_ms, 'dd/MM/yyyy HH:mm:ss')}</td>
- </tr>
- </table>
+ </span>
+ <h3>Deposit <Pending /></h3>
+ <h1>{transaction.amountEffective} <Fee value={fee} /></h1>
</section>
<Footer />
</div>
@@ -203,27 +160,19 @@ export function TransactionView({ transaction, onDelete, onBack }: WalletTransac
}
if (transaction.type === TransactionType.Refresh) {
+ const fee = Amounts.sub(
+ Amounts.parseOrThrow(transaction.amountRaw),
+ Amounts.parseOrThrow(transaction.amountEffective),
+ ).amount
return (
- <div style={{ display: 'flex', flexDirection: 'column', flex: 1, minHeight: '20rem' }} >
- <section>
- <h1>Refresh <Pending /></h1>
- <p>
+ <div style={{ display: 'flex', flexDirection: 'column', width: '100%' }} >
+ <section style={{ color: transaction.pending ? 'gray' : '', flex: '1 0 auto', height: 'calc(20rem - 34px - 45px)', overflow: 'auto' }}>
+ <span style="flat: left; font-size:small; color:gray">{transaction.timestamp.t_ms === "never" ? "never" : format(transaction.timestamp.t_ms, 'dd/MM/yyyy HH:mm:ss')}</span>
+ <span style="float: right; font-size:small; color:gray">
From <b>{transaction.exchangeBaseUrl}</b>
- </p>
- <table class={transaction.pending ? "detailsTable pending" : "detailsTable"}>
- <tr>
- <td>Amount refreshed</td>
- <td>{transaction.amountRaw}</td>
- </tr>
- <tr>
- <td>Fees</td>
- <td>{transaction.amountEffective}</td>
- </tr>
- <tr>
- <td>When</td>
- <td>{transaction.timestamp.t_ms === "never" ? "never" : format(transaction.timestamp.t_ms, 'dd/MM/yyyy HH:mm:ss')}</td>
- </tr>
- </table>
+ </span>
+ <h3>Refresh <Pending /></h3>
+ <h1>{transaction.amountEffective} <Fee value={fee} /></h1>
</section>
<Footer />
</div>
@@ -231,91 +180,58 @@ export function TransactionView({ transaction, onDelete, onBack }: WalletTransac
}
if (transaction.type === TransactionType.Tip) {
+ const fee = Amounts.sub(
+ Amounts.parseOrThrow(transaction.amountRaw),
+ Amounts.parseOrThrow(transaction.amountEffective),
+ ).amount
return (
- <div style={{ display: 'flex', flexDirection: 'column', flex: 1, minHeight: '20rem' }} >
- <section>
- <h1>Tip <Pending /></h1>
- <p>
+ <div style={{ display: 'flex', flexDirection: 'column', width: '100%' }} >
+ <section style={{ color: transaction.pending ? 'gray' : '', flex: '1 0 auto', height: 'calc(20rem - 34px - 45px)', overflow: 'auto' }}>
+ <span style="flat: left; font-size:small; color:gray">{transaction.timestamp.t_ms === "never" ? "never" : format(transaction.timestamp.t_ms, 'dd/MM/yyyy HH:mm:ss')}</span>
+ <span style="float: right; font-size:small; color:gray">
From <b>{transaction.merchantBaseUrl}</b>
- </p>
- <table class={transaction.pending ? "detailsTable pending" : "detailsTable"}>
- <tr>
- <td>Amount deduce</td>
- <td>{transaction.amountRaw}</td>
- </tr>
- <tr>
- <td>Amount received</td>
- <td>{transaction.amountEffective}</td>
- </tr>
- <tr>
- <td>Exchange fee</td>
- <td>{Amounts.stringify(
- Amounts.sub(
- Amounts.parseOrThrow(transaction.amountRaw),
- Amounts.parseOrThrow(transaction.amountEffective),
- ).amount
- )}</td>
- </tr>
- <tr>
- <td>When</td>
- <td>{transaction.timestamp.t_ms === "never" ? "never" : format(transaction.timestamp.t_ms, 'dd/MM/yyyy HH:mm:ss')}</td>
- </tr>
- </table>
+ </span>
+ <h3>Tip <Pending /></h3>
+ <h1>{transaction.amountEffective} <Fee value={fee} /></h1>
</section>
<Footer />
</div>
);
}
- const TRANSACTION_FROM_REFUND = /[a-z]*:([\w]{10}).*/
if (transaction.type === TransactionType.Refund) {
+ const fee = Amounts.sub(
+ Amounts.parseOrThrow(transaction.amountRaw),
+ Amounts.parseOrThrow(transaction.amountEffective),
+ ).amount
return (
- <div style={{ display: 'flex', flexDirection: 'column', flex: 1, minHeight: '20rem' }} >
- <section>
- <h1>Refund ({TRANSACTION_FROM_REFUND.exec(transaction.refundedTransactionId)![1]}...) <Pending /></h1>
- <p>
+ <div style={{ display: 'flex', flexDirection: 'column', width: '100%' }} >
+ <section style={{ color: transaction.pending ? 'gray' : '', flex: '1 0 auto', height: 'calc(20rem - 34px - 45px)', overflow: 'auto' }}>
+ <span style="flat: left; font-size:small; color:gray">{transaction.timestamp.t_ms === "never" ? "never" : format(transaction.timestamp.t_ms, 'dd/MM/yyyy HH:mm:ss')}</span>
+ <span style="float: right; font-size:small; color:gray">
From <b>{transaction.info.merchant.name}</b>
+ </span>
+ <h3>Refund <Pending /></h3>
+ <h1>{transaction.amountEffective} <Fee value={fee} /></h1>
+ <span style="font-size:small; color:gray">#{transaction.info.orderId}</span>
+ <p>
+ {transaction.info.summary}
</p>
- <table class={transaction.pending ? "detailsTable pending" : "detailsTable"}>
- <tr>
- <td>Order id</td>
- <td>{transaction.info.orderId}</td>
- </tr>
- <tr>
- <td>Summary</td>
- <td>{transaction.info.summary}</td>
- </tr>
- {transaction.info.products && transaction.info.products.length > 0 &&
- <tr>
- <td>Products</td>
- <td><ol>
- {transaction.info.products.map(p =>
- <li>{p.description}</li>
- )}</ol></td>
- </tr>
+ <div>
+ {transaction.info.products && transaction.info.products.length > 0 && <div>
+ {transaction.info.products.map(p => <div style="display: flex; flex-direction: row; border: 1px solid gray; border-radius: 0.5em; margin: 0.5em 0px; justify-content: left; padding: 0.5em;">
+ <a href="#" onClick={showLargePic}>
+ <img class="pure-img" style="display:inline-block" src={p.image ? p.image : emptyImg} width="32" height="32" />
+ </a>
+ <div style="display: block; margin-left: 1em;">
+ {p.quantity && p.quantity > 0 && <div style="font-size: small; color: gray;">x {p.quantity} {p.unit}</div>}
+ <div style={{ textOverflow: 'ellipsis', overflow: 'hidden', width: 'calc(20rem - 32px - 32px - 8px - 1em)', whiteSpace: 'nowrap' }}>{p.description}</div>
+ </div>
+ </div>)}
+ </div>
}
- <tr>
- <td>Amount deduce</td>
- <td>{transaction.amountRaw}</td>
- </tr>
- <tr>
- <td>Amount received</td>
- <td>{transaction.amountEffective}</td>
- </tr>
- <tr>
- <td>Exchange fee</td>
- <td>{Amounts.stringify(
- Amounts.sub(
- Amounts.parseOrThrow(transaction.amountRaw),
- Amounts.parseOrThrow(transaction.amountEffective),
- ).amount
- )}</td>
- </tr>
- <tr>
- <td>When</td>
- <td>{transaction.timestamp.t_ms === "never" ? "never" : format(transaction.timestamp.t_ms, 'dd/MM/yyyy HH:mm:ss')}</td>
- </tr>
- </table>
+ </div>
+
</section>
<Footer />
</div>