summaryrefslogtreecommitdiff
path: root/packages/taler-wallet-webextension
diff options
context:
space:
mode:
authorFlorian Dold <florian@dold.me>2020-11-18 17:33:02 +0100
committerFlorian Dold <florian@dold.me>2020-11-18 17:33:02 +0100
commit9cd1062f1bd608b3f5b6910983b339401a227452 (patch)
tree2d3769985545e5f31f2cd54bcef211afa8007edd /packages/taler-wallet-webextension
parentd6409f185d332f6ade298f143cdb7803391f4b0b (diff)
downloadwallet-core-9cd1062f1bd608b3f5b6910983b339401a227452.tar.gz
wallet-core-9cd1062f1bd608b3f5b6910983b339401a227452.tar.bz2
wallet-core-9cd1062f1bd608b3f5b6910983b339401a227452.zip
towards a nicer transaction history
Diffstat (limited to 'packages/taler-wallet-webextension')
-rw-r--r--packages/taler-wallet-webextension/src/pages/popup.tsx167
-rw-r--r--packages/taler-wallet-webextension/static/img/COPYRIGHT15
-rw-r--r--packages/taler-wallet-webextension/static/img/ri-bank-line.svg1
-rw-r--r--packages/taler-wallet-webextension/static/img/ri-file-unknown-line.svg1
-rw-r--r--packages/taler-wallet-webextension/static/img/ri-hand-heart-line.svg1
-rw-r--r--packages/taler-wallet-webextension/static/img/ri-refresh-line.svg1
-rw-r--r--packages/taler-wallet-webextension/static/img/ri-refund-2-line.svg1
-rw-r--r--packages/taler-wallet-webextension/static/img/ri-shopping-cart-line.svg1
8 files changed, 176 insertions, 12 deletions
diff --git a/packages/taler-wallet-webextension/src/pages/popup.tsx b/packages/taler-wallet-webextension/src/pages/popup.tsx
index d7cdd548e..8d8d5a85d 100644
--- a/packages/taler-wallet-webextension/src/pages/popup.tsx
+++ b/packages/taler-wallet-webextension/src/pages/popup.tsx
@@ -36,6 +36,8 @@ import {
TransactionsResponse,
Transaction,
TransactionType,
+ AmountString,
+ Timestamp,
} from "taler-wallet-core";
import { abbrev, renderAmount, PageLink } from "../renderHtml";
@@ -301,19 +303,161 @@ class WalletBalanceView extends React.Component<any, any> {
}
}
-function Icon({ l }: { l: string }): JSX.Element {
- return <div className={"icon"}>{l}</div>;
+interface TransactionAmountProps {
+ debitCreditIndicator: "debit" | "credit" | "unknown";
+ amount: AmountString | "unknown";
+ pending: boolean;
}
-function formatAndCapitalize(text: string): string {
- text = text.replace("-", " ");
- text = text.replace(/^./, text[0].toUpperCase());
- return text;
+function TransactionAmount(props: TransactionAmountProps): JSX.Element {
+ const [currency, amount] = props.amount.split(":");
+ let sign: string;
+ switch (props.debitCreditIndicator) {
+ case "credit":
+ sign = "+";
+ break;
+ case "debit":
+ sign = "-";
+ break;
+ case "unknown":
+ sign = "";
+ }
+ const style: React.CSSProperties = {
+ marginLeft: "auto",
+ display: "flex",
+ flexDirection: "column",
+ alignItems: "center",
+ alignSelf: "center"
+ };
+ if (props.pending) {
+ style.color = "gray";
+ }
+ return (
+ <div style={{ ...style }}>
+ <div style={{ fontSize: "x-large" }}>
+ {sign}
+ {amount}
+ </div>
+ <div>{currency}</div>
+ </div>
+ );
+}
+
+interface TransactionLayoutProps {
+ debitCreditIndicator: "debit" | "credit" | "unknown";
+ amount: AmountString | "unknown";
+ timestamp: Timestamp;
+ title: string;
+ subtitle: string;
+ iconPath: string;
+ pending: boolean;
+}
+
+function TransactionLayout(props: TransactionLayoutProps): JSX.Element {
+ const date = new Date(props.timestamp.t_ms);
+ const dateStr = date.toLocaleString([], {
+ dateStyle: "medium",
+ timeStyle: "short",
+ } as any);
+ return (
+ <div
+ style={{
+ display: "flex",
+ flexDirection: "row",
+ border: "1px solid gray",
+ borderRadius: "0.5em",
+ margin: "0.5em 0",
+ justifyContent: "space-between",
+ padding: "0.5em",
+ }}
+ >
+ <img src={props.iconPath} />
+ <div
+ style={{ display: "flex", flexDirection: "column", marginLeft: "1em" }}
+ >
+ <div style={{ fontSize: "small", color: "gray" }}>{dateStr}</div>
+ <div style={{ fontVariant: "small-caps", fontSize: "x-large" }}>
+ <span>{props.title}</span>
+ {props.pending ? (
+ <span style={{ color: "darkblue" }}> (Pending)</span>
+ ) : null}
+ </div>
+
+ <div>{props.subtitle}</div>
+ </div>
+ <TransactionAmount
+ pending={props.pending}
+ amount={props.amount}
+ debitCreditIndicator={props.debitCreditIndicator}
+ />
+ </div>
+ );
}
function TransactionItem(props: { tx: Transaction }): JSX.Element {
const tx = props.tx;
- return <pre>{JSON.stringify(tx)}</pre>
+ switch (tx.type) {
+ case TransactionType.Withdrawal:
+ return (
+ <TransactionLayout
+ amount={tx.amountEffective}
+ debitCreditIndicator={"credit"}
+ title="Withdrawal"
+ subtitle={`via ${tx.exchangeBaseUrl}`}
+ timestamp={tx.timestamp}
+ iconPath="/static/img/ri-bank-line.svg"
+ pending={tx.pending}
+ ></TransactionLayout>
+ );
+ case TransactionType.Payment:
+ return (
+ <TransactionLayout
+ amount={tx.amountEffective}
+ debitCreditIndicator={"debit"}
+ title="Payment"
+ subtitle={tx.info.summary}
+ timestamp={tx.timestamp}
+ iconPath="/static/img/ri-shopping-cart-line.svg"
+ pending={tx.pending}
+ ></TransactionLayout>
+ );
+ case TransactionType.Refund:
+ return (
+ <TransactionLayout
+ amount={tx.amountEffective}
+ debitCreditIndicator={"credit"}
+ title="Refund"
+ subtitle={tx.info.summary}
+ timestamp={tx.timestamp}
+ iconPath="/static/img/ri-refund-2-line.svg"
+ pending={tx.pending}
+ ></TransactionLayout>
+ );
+ case TransactionType.Tip:
+ return (
+ <TransactionLayout
+ amount={tx.amountEffective}
+ debitCreditIndicator={"credit"}
+ title="Tip"
+ subtitle={`from ${new URL(tx.merchantBaseUrl).hostname}`}
+ timestamp={tx.timestamp}
+ iconPath="/static/img/ri-hand-heart-line.svg"
+ pending={tx.pending}
+ ></TransactionLayout>
+ );
+ case TransactionType.Refresh:
+ return (
+ <TransactionLayout
+ amount={tx.amountEffective}
+ debitCreditIndicator={"credit"}
+ title="Refresh"
+ subtitle={`via exchange ${tx.exchangeBaseUrl}`}
+ timestamp={tx.timestamp}
+ iconPath="/static/img/ri-refresh-line.svg"
+ pending={tx.pending}
+ ></TransactionLayout>
+ );
+ }
}
function WalletHistory(props: any): JSX.Element {
@@ -334,9 +478,11 @@ function WalletHistory(props: any): JSX.Element {
return <div>Loading ...</div>;
}
+ const txs = [...transactions.transactions].reverse();
+
return (
<div>
- {transactions.transactions.map((tx) => (
+ {txs.map((tx) => (
<TransactionItem tx={tx} />
))}
</div>
@@ -379,10 +525,7 @@ function WalletDebug(props: any): JSX.Element {
return (
<div>
<p>Debug tools:</p>
- <button onClick={openExtensionPage("/popup.html")}>wallet tab</button>
- <button onClick={openExtensionPage("/benchmark.html")}>benchmark</button>
- <button onClick={openExtensionPage("/show-db.html")}>show db</button>
- <button onClick={openExtensionPage("/tree.html")}>show tree</button>
+ <button onClick={openExtensionPage("/static/popup.html")}>wallet tab</button>
<br />
<button onClick={confirmReset}>reset</button>
<button onClick={reload}>reload chrome extension</button>
diff --git a/packages/taler-wallet-webextension/static/img/COPYRIGHT b/packages/taler-wallet-webextension/static/img/COPYRIGHT
new file mode 100644
index 000000000..d1a2bf1de
--- /dev/null
+++ b/packages/taler-wallet-webextension/static/img/COPYRIGHT
@@ -0,0 +1,15 @@
+# Icon Copyright Info
+
+## Remix Icons
+
+https://github.com/Remix-Design/RemixIcon
+
+Remix Icon is licensed under the Apache License Version 2.0. Feel free to use
+these icons in your products and distribute them. We would be very grateful if
+you mention "Remix Icon" in your product info, but it's not required. The only
+thing we ask is that these icons are not for sale.
+
+
+### Used Icons
+
+* ri-*.svg
diff --git a/packages/taler-wallet-webextension/static/img/ri-bank-line.svg b/packages/taler-wallet-webextension/static/img/ri-bank-line.svg
new file mode 100644
index 000000000..8d987df79
--- /dev/null
+++ b/packages/taler-wallet-webextension/static/img/ri-bank-line.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path fill="none" d="M0 0h24v24H0z"/><path d="M2 20h20v2H2v-2zm2-8h2v7H4v-7zm5 0h2v7H9v-7zm4 0h2v7h-2v-7zm5 0h2v7h-2v-7zM2 7l10-5 10 5v4H2V7zm2 1.236V9h16v-.764l-8-4-8 4zM12 8a1 1 0 1 1 0-2 1 1 0 0 1 0 2z"/></svg>
diff --git a/packages/taler-wallet-webextension/static/img/ri-file-unknown-line.svg b/packages/taler-wallet-webextension/static/img/ri-file-unknown-line.svg
new file mode 100644
index 000000000..5203d49f5
--- /dev/null
+++ b/packages/taler-wallet-webextension/static/img/ri-file-unknown-line.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path fill="none" d="M0 0h24v24H0z"/><path d="M11 15h2v2h-2v-2zm2-1.645V14h-2v-1.5a1 1 0 0 1 1-1 1.5 1.5 0 1 0-1.471-1.794l-1.962-.393A3.501 3.501 0 1 1 13 13.355zM15 4H5v16h14V8h-4V4zM3 2.992C3 2.444 3.447 2 3.999 2H16l5 5v13.993A1 1 0 0 1 20.007 22H3.993A1 1 0 0 1 3 21.008V2.992z"/></svg>
diff --git a/packages/taler-wallet-webextension/static/img/ri-hand-heart-line.svg b/packages/taler-wallet-webextension/static/img/ri-hand-heart-line.svg
new file mode 100644
index 000000000..a9c195eac
--- /dev/null
+++ b/packages/taler-wallet-webextension/static/img/ri-hand-heart-line.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path fill="none" d="M0 0h24v24H0z"/><path d="M5 9a1 1 0 0 1 1 1 6.97 6.97 0 0 1 4.33 1.5h2.17c1.332 0 2.53.579 3.353 1.499L19 13a5 5 0 0 1 4.516 2.851C21.151 18.972 17.322 21 13 21c-2.79 0-5.15-.603-7.06-1.658A.998.998 0 0 1 5 20H2a1 1 0 0 1-1-1v-9a1 1 0 0 1 1-1h3zm1.001 3L6 17.021l.045.033C7.84 18.314 10.178 19 13 19c3.004 0 5.799-1.156 7.835-3.13l.133-.133-.12-.1a2.994 2.994 0 0 0-1.643-.63L19 15l-2.112-.001c.073.322.112.657.112 1.001v1H8v-2l6.79-.001-.034-.078a2.501 2.501 0 0 0-2.092-1.416L12.5 13.5H9.57A4.985 4.985 0 0 0 6.002 12zM4 11H3v7h1v-7zm9.646-7.425L14 3.93l.354-.354a2.5 2.5 0 1 1 3.535 3.536L14 11l-3.89-3.89a2.5 2.5 0 1 1 3.536-3.535zm-2.12 1.415a.5.5 0 0 0-.06.637l.058.069L14 8.17l2.476-2.474a.5.5 0 0 0 .058-.638l-.058-.07a.5.5 0 0 0-.638-.057l-.07.058-1.769 1.768-1.767-1.77-.068-.056a.5.5 0 0 0-.638.058z"/></svg>
diff --git a/packages/taler-wallet-webextension/static/img/ri-refresh-line.svg b/packages/taler-wallet-webextension/static/img/ri-refresh-line.svg
new file mode 100644
index 000000000..6efa8554b
--- /dev/null
+++ b/packages/taler-wallet-webextension/static/img/ri-refresh-line.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path fill="none" d="M0 0h24v24H0z"/><path d="M5.463 4.433A9.961 9.961 0 0 1 12 2c5.523 0 10 4.477 10 10 0 2.136-.67 4.116-1.81 5.74L17 12h3A8 8 0 0 0 6.46 6.228l-.997-1.795zm13.074 15.134A9.961 9.961 0 0 1 12 22C6.477 22 2 17.523 2 12c0-2.136.67-4.116 1.81-5.74L7 12H4a8 8 0 0 0 13.54 5.772l.997 1.795z"/></svg>
diff --git a/packages/taler-wallet-webextension/static/img/ri-refund-2-line.svg b/packages/taler-wallet-webextension/static/img/ri-refund-2-line.svg
new file mode 100644
index 000000000..5805daf09
--- /dev/null
+++ b/packages/taler-wallet-webextension/static/img/ri-refund-2-line.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path fill="none" d="M0 0h24v24H0z"/><path d="M5.671 4.257c3.928-3.219 9.733-2.995 13.4.672 3.905 3.905 3.905 10.237 0 14.142-3.905 3.905-10.237 3.905-14.142 0A9.993 9.993 0 0 1 2.25 9.767l.077-.313 1.934.51a8 8 0 1 0 3.053-4.45l-.221.166 1.017 1.017-4.596 1.06 1.06-4.596 1.096 1.096zM13 6v2h2.5v2H10a.5.5 0 0 0-.09.992L10 11h4a2.5 2.5 0 1 1 0 5h-1v2h-2v-2H8.5v-2H14a.5.5 0 0 0 .09-.992L14 13h-4a2.5 2.5 0 1 1 0-5h1V6h2z"/></svg>
diff --git a/packages/taler-wallet-webextension/static/img/ri-shopping-cart-line.svg b/packages/taler-wallet-webextension/static/img/ri-shopping-cart-line.svg
new file mode 100644
index 000000000..50dabf446
--- /dev/null
+++ b/packages/taler-wallet-webextension/static/img/ri-shopping-cart-line.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path fill="none" d="M0 0h24v24H0z"/><path d="M4 16V4H2V2h3a1 1 0 0 1 1 1v12h12.438l2-8H8V5h13.72a1 1 0 0 1 .97 1.243l-2.5 10a1 1 0 0 1-.97.757H5a1 1 0 0 1-1-1zm2 7a2 2 0 1 1 0-4 2 2 0 0 1 0 4zm12 0a2 2 0 1 1 0-4 2 2 0 0 1 0 4z"/></svg>