From 24162c1086c017305253c78280a82bfa9a572b1e Mon Sep 17 00:00:00 2001
From: Sebastian
Date: Thu, 26 May 2022 15:55:14 -0300
Subject: [PATCH] transaction details template
mayor change in the template of the transaction details for every
transaction
more work needs to be done in wallet core for tip and refund to show
more information about the merchant like logo and website
---
packages/taler-util/src/talerTypes.ts | 3 +
packages/taler-util/src/transactionsTypes.ts | 12 +
.../build-fast-with-linaria.mjs | 1 +
.../src/components/Amount.tsx | 2 +-
.../src/components/BalanceTable.tsx | 2 +-
.../src/components/BankDetailsByPaytoType.tsx | 75 +-
.../src/components/Part.tsx | 99 +-
.../src/components/styled/index.tsx | 8 +-
.../taler-wallet-webextension/src/custom.d.ts | 6 +-
.../taler-wallet-webextension/src/stories.tsx | 8 +-
.../src/test-utils.ts | 13 +-
.../src/wallet/Transaction.stories.tsx | 161 ++-
.../src/wallet/Transaction.tsx | 1046 +++++++++++------
.../static-dev/merchant-icon-11.jpeg | Bin 0 -> 60184 bytes
14 files changed, 976 insertions(+), 460 deletions(-)
create mode 100644 packages/taler-wallet-webextension/static-dev/merchant-icon-11.jpeg
diff --git a/packages/taler-util/src/talerTypes.ts b/packages/taler-util/src/talerTypes.ts
index d9213ef5d..7fc3fcba0 100644
--- a/packages/taler-util/src/talerTypes.ts
+++ b/packages/taler-util/src/talerTypes.ts
@@ -362,6 +362,9 @@ export interface MerchantInfo {
name: string;
jurisdiction?: Location;
address?: Location;
+ logo?: string;
+ website?: string;
+ email?: string;
}
export interface Tax {
diff --git a/packages/taler-util/src/transactionsTypes.ts b/packages/taler-util/src/transactionsTypes.ts
index 37c1c7ef1..dcaa56675 100644
--- a/packages/taler-util/src/transactionsTypes.ts
+++ b/packages/taler-util/src/transactionsTypes.ts
@@ -33,6 +33,7 @@ import {
codecForInternationalizedString,
codecForMerchantInfo,
codecForProduct,
+ Location,
} from "./talerTypes.js";
import {
Codec,
@@ -276,6 +277,17 @@ export interface OrderShortInfo {
*/
products: Product[] | undefined;
+ /**
+ * Time indicating when the order should be delivered.
+ * May be overwritten by individual products.
+ */
+ delivery_date?: TalerProtocolTimestamp;
+
+ /**
+ * Delivery location for (all!) products.
+ */
+ delivery_location?: Location;
+
/**
* URL of the fulfillment, given by the merchant
*/
diff --git a/packages/taler-wallet-webextension/build-fast-with-linaria.mjs b/packages/taler-wallet-webextension/build-fast-with-linaria.mjs
index f6de67885..41747a745 100755
--- a/packages/taler-wallet-webextension/build-fast-with-linaria.mjs
+++ b/packages/taler-wallet-webextension/build-fast-with-linaria.mjs
@@ -54,6 +54,7 @@ export const buildConfig = {
loader: {
'.svg': 'text',
'.png': 'dataurl',
+ '.jpeg': 'dataurl',
},
target: [
'es6'
diff --git a/packages/taler-wallet-webextension/src/components/Amount.tsx b/packages/taler-wallet-webextension/src/components/Amount.tsx
index c41f7faf6..b415a30cd 100644
--- a/packages/taler-wallet-webextension/src/components/Amount.tsx
+++ b/packages/taler-wallet-webextension/src/components/Amount.tsx
@@ -6,7 +6,7 @@ export function Amount({ value }: { value: AmountJson | AmountString }): VNode {
const amount = Amounts.stringifyValue(aj, 2);
return (
- {amount} {aj.currency}
+ {amount} {aj.currency}
);
}
diff --git a/packages/taler-wallet-webextension/src/components/BalanceTable.tsx b/packages/taler-wallet-webextension/src/components/BalanceTable.tsx
index e67fb6b4d..a2c91f4a1 100644
--- a/packages/taler-wallet-webextension/src/components/BalanceTable.tsx
+++ b/packages/taler-wallet-webextension/src/components/BalanceTable.tsx
@@ -44,7 +44,7 @@ export function BalanceTable({
width: "100%",
}}
>
- {Amounts.stringifyValue(av)}
+ {Amounts.stringifyValue(av, 2)}
);
diff --git a/packages/taler-wallet-webextension/src/components/BankDetailsByPaytoType.tsx b/packages/taler-wallet-webextension/src/components/BankDetailsByPaytoType.tsx
index 185021bc0..3a2a12c72 100644
--- a/packages/taler-wallet-webextension/src/components/BankDetailsByPaytoType.tsx
+++ b/packages/taler-wallet-webextension/src/components/BankDetailsByPaytoType.tsx
@@ -46,43 +46,47 @@ export function BankDetailsByPaytoType({
if (payto.isKnown && payto.targetType === "bitcoin") {
const min = segwitMinAmount(amount.currency);
return (
-
+
+ Bitcoin transfer details
- Bitcoin exchange need a transaction with 3 output, one output is the
+ The exchange need a transaction with 3 output, one output is the
exchange account and the other two are segwit fake address for
- metadata with an minimum amount. Reserve pub : {subject}
+ metadata with an minimum amount.
+ Reserve}
+ value={subject}
+ />
+
In bitcoincore wallet use 'Add Recipient' button to add
two additional recipient and copy addresses and amounts
-
-
- {payto.targetPath} {Amounts.stringifyValue(amount)} BTC
-
- {payto.segwitAddrs.map((addr, i) => (
-
- {addr} {Amounts.stringifyValue(min)} BTC
-
- ))}
-
-
- In Electrum wallet paste the following three lines in 'Pay
- to' field :
-
-
-
- {payto.targetPath},{Amounts.stringifyValue(amount)}
-
- {payto.segwitAddrs.map((addr, i) => (
-
- {addr} {Amounts.stringifyValue(min)} BTC
-
- ))}
-
+
+
+
+ {payto.targetPath}
+ {Amounts.stringifyValue(amount)} BTC
+
+ {payto.segwitAddrs.map((addr, i) => (
+
+ {addr}
+ {Amounts.stringifyValue(min)} BTC
+
+ ))}
+
+
Make sure the amount show{" "}
{Amounts.stringifyValue(Amounts.sum([amount, min, min]).amount)}{" "}
@@ -93,7 +97,7 @@ export function BankDetailsByPaytoType({
);
}
- const firstPart = !payto.isKnown ? (
+ const accountPart = !payto.isKnown ? (
Account
}
value={payto.targetPath}
@@ -113,10 +117,17 @@ export function BankDetailsByPaytoType({
IBAN} value={payto.iban} />
) : undefined;
return (
-
-
Bank transfer details
+
+
Bank transfer details
- {firstPart}
+ {accountPart}
Exchange}
value={exchangeBaseUrl}
@@ -176,7 +187,7 @@ function Row({
)}
-
+
{name}
{literal ? (
diff --git a/packages/taler-wallet-webextension/src/components/Part.tsx b/packages/taler-wallet-webextension/src/components/Part.tsx
index 21c0f65dc..58165a349 100644
--- a/packages/taler-wallet-webextension/src/components/Part.tsx
+++ b/packages/taler-wallet-webextension/src/components/Part.tsx
@@ -14,33 +14,122 @@
GNU Taler; see the file COPYING. If not, see
*/
import { PaytoUri, stringifyPaytoUri } from "@gnu-taler/taler-util";
+import { styled } from "@linaria/react";
import { Fragment, h, VNode } from "preact";
-import { ExtraLargeText, LargeText, SmallLightText } from "./styled/index.js";
+import { useState } from "preact/hooks";
+import {
+ ExtraLargeText,
+ LargeText,
+ SmallBoldText,
+ SmallLightText,
+} from "./styled/index.js";
export type Kind = "positive" | "negative" | "neutral";
interface Props {
- title: VNode;
+ title: VNode | string;
text: VNode | string;
- kind: Kind;
+ kind?: Kind;
big?: boolean;
+ showSign?: boolean;
}
-export function Part({ text, title, kind, big }: Props): VNode {
+export function Part({
+ text,
+ title,
+ kind = "neutral",
+ big,
+ showSign,
+}: Props): VNode {
const Text = big ? ExtraLargeText : LargeText;
return (
- {title}
+ {title}
+ {!showSign || kind === "neutral"
+ ? undefined
+ : kind === "positive"
+ ? "+"
+ : "-"}
{text}
);
}
+const CollasibleBox = styled.div`
+ border: 1px solid black;
+ border-radius: 0.25em;
+ display: flex;
+ vertical-align: middle;
+ justify-content: space-between;
+ flex-direction: column;
+ /* margin: 0.5em; */
+ padding: 0.5em;
+ /* margin: 1em; */
+ /* width: 100%; */
+ /* color: #721c24; */
+ /* background: #f8d7da; */
+
+ & > div {
+ display: flex;
+ justify-content: space-between;
+ div {
+ margin-top: auto;
+ margin-bottom: auto;
+ }
+ & > button {
+ align-self: center;
+ font-size: 100%;
+ padding: 0;
+ height: 28px;
+ width: 28px;
+ }
+ }
+`;
+import arrowDown from "../svg/chevron-down.svg";
+
+export function PartCollapsible({ text, title, big, showSign }: Props): VNode {
+ const Text = big ? ExtraLargeText : LargeText;
+ const [collapsed, setCollapsed] = useState(true);
+
+ return (
+
+
+
{title}
+
{
+ setCollapsed((v) => !v);
+ }}
+ >
+
+
+
+ {/*
+
+ */}
+ {!collapsed && {text}
}
+
+ );
+}
+
interface PropsPayto {
payto: PaytoUri;
kind: Kind;
diff --git a/packages/taler-wallet-webextension/src/components/styled/index.tsx b/packages/taler-wallet-webextension/src/components/styled/index.tsx
index 7517a1388..a531a15dc 100644
--- a/packages/taler-wallet-webextension/src/components/styled/index.tsx
+++ b/packages/taler-wallet-webextension/src/components/styled/index.tsx
@@ -87,7 +87,7 @@ export const WalletBox = styled.div<{ noPadding?: boolean }>`
justify-content: space-between;
align-items: center;
& > * {
- width: 500px;
+ width: 600px;
}
& > section {
padding: ${({ noPadding }) => (noPadding ? "0px" : "8px")};
@@ -660,6 +660,12 @@ export const WarningText = styled.div`
export const SmallText = styled.div`
font-size: small;
`;
+
+export const SmallBoldText = styled.div`
+ font-size: small;
+ font-weight: bold;
+`;
+
export const LargeText = styled.div`
font-size: large;
`;
diff --git a/packages/taler-wallet-webextension/src/custom.d.ts b/packages/taler-wallet-webextension/src/custom.d.ts
index 521b824c7..711112ad8 100644
--- a/packages/taler-wallet-webextension/src/custom.d.ts
+++ b/packages/taler-wallet-webextension/src/custom.d.ts
@@ -13,7 +13,11 @@
You should have received a copy of the GNU General Public License along with
GNU Taler; see the file COPYING. If not, see
*/
-declare module "*.jpeg" {
+ declare module "*.jpeg" {
+ const content: any;
+ export default content;
+}
+declare module "*.jpg" {
const content: any;
export default content;
}
diff --git a/packages/taler-wallet-webextension/src/stories.tsx b/packages/taler-wallet-webextension/src/stories.tsx
index 9c0f69ec4..fd5d3c590 100644
--- a/packages/taler-wallet-webextension/src/stories.tsx
+++ b/packages/taler-wallet-webextension/src/stories.tsx
@@ -330,9 +330,11 @@ function Application(): VNode {
const hash = location.hash.substring(1);
const found = document.getElementById(hash);
if (found) {
- found.scrollIntoView({
- block: "center",
- });
+ setTimeout(() => {
+ found.scrollIntoView({
+ block: "center",
+ });
+ }, 10);
}
}
}, []);
diff --git a/packages/taler-wallet-webextension/src/test-utils.ts b/packages/taler-wallet-webextension/src/test-utils.ts
index eceda616f..9e219daa6 100644
--- a/packages/taler-wallet-webextension/src/test-utils.ts
+++ b/packages/taler-wallet-webextension/src/test-utils.ts
@@ -26,22 +26,27 @@ options.requestAnimationFrame = (fn: () => void) => {
export function createExample(
Component: FunctionalComponent,
- props: Partial,
+ props: Partial | (() => Partial),
): ComponentChildren {
+ //FIXME: props are evaluated on build time
+ // in some cases we want to evaluated the props on render time so we can get some relative timestamp
+ // check how we can build evaluatedProps in render time
+ const evaluatedProps = typeof props === "function" ? props() : props
const Render = (args: any): VNode => create(Component, args);
- Render.args = props;
+ Render.args = evaluatedProps;
return Render;
}
export function createExampleWithCustomContext(
Component: FunctionalComponent,
- props: Partial,
+ props: Partial | (() => Partial),
ContextProvider: FunctionalComponent,
contextProps: Partial,
): ComponentChildren {
+ const evaluatedProps = typeof props === "function" ? props() : props
const Render = (args: any): VNode => create(Component, args);
const WithContext = (args: any): VNode => create(ContextProvider, { ...contextProps, children: [Render(args)] } as any);
- WithContext.args = props
+ WithContext.args = evaluatedProps
return WithContext
}
diff --git a/packages/taler-wallet-webextension/src/wallet/Transaction.stories.tsx b/packages/taler-wallet-webextension/src/wallet/Transaction.stories.tsx
index f162543ae..493cdd1d7 100644
--- a/packages/taler-wallet-webextension/src/wallet/Transaction.stories.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/Transaction.stories.tsx
@@ -30,6 +30,7 @@ import {
TransactionTip,
TransactionType,
TransactionWithdrawal,
+ WithdrawalDetails,
WithdrawalType,
} from "@gnu-taler/taler-util";
import { DevContextProviderForTesting } from "../context/devContext.js";
@@ -57,6 +58,8 @@ const commonTransaction = {
transactionId: "12",
} as TransactionCommon;
+import merchantIcon from "../../static-dev/merchant-icon-11.jpeg";
+
const exampleData = {
withdraw: {
...commonTransaction,
@@ -65,27 +68,34 @@ const exampleData = {
withdrawalDetails: {
confirmed: false,
reservePub: "A05AJGMFNSK4Q62NXR2FKNDB1J4EXTYQTE7VA4M9GZQ4TR06YBNG",
- exchangePaytoUris: ["payto://x-taler-bank/bank/account"],
+ exchangePaytoUris: ["payto://x-taler-bank/bank.demo.taler.net/Exchange"],
type: WithdrawalType.ManualTransfer,
},
} as TransactionWithdrawal,
payment: {
...commonTransaction,
- amountEffective: "KUDOS:11",
+ amountEffective: "KUDOS:12",
type: TransactionType.Payment,
info: {
contractTermsHash: "ASDZXCASD",
merchant: {
name: "the merchant",
+ logo: merchantIcon,
+ website: "https://www.themerchant.taler",
+ email: "contact@merchant.taler",
},
orderId: "2021.167-03NPY6MCYMVGT",
products: [],
summary: "Essay: Why the Devil's Advocate Doesn't Help Reach the Truth",
fulfillmentMessage: "",
+ // delivery_date: { t_s: 1 },
+ // delivery_location: {
+ // address_lines: [""],
+ // },
},
refundPending: undefined,
- totalRefundEffective: "USD:0",
- totalRefundRaw: "USD:0",
+ totalRefundEffective: "KUDOS:0",
+ totalRefundRaw: "KUDOS:0",
proposalId: "1EMJJH8EP1NX3XF7733NCYS2DBEJW4Q2KA5KEB37MCQJQ8Q5HMC0",
status: PaymentStatus.Accepted,
} as TransactionPayment,
@@ -93,7 +103,7 @@ const exampleData = {
...commonTransaction,
type: TransactionType.Deposit,
depositGroupId: "#groupId",
- targetPaytoUri: "payto://x-taler-bank/bank/account",
+ targetPaytoUri: "payto://x-taler-bank/bank.demo.taler.net/Exchange",
} as TransactionDeposit,
refresh: {
...commonTransaction,
@@ -117,7 +127,7 @@ const exampleData = {
},
orderId: "2021.167-03NPY6MCYMVGT",
products: [],
- summary: "the summary",
+ summary: "Essay: Why the Devil's Advocate Doesn't Help Reach the Truth",
fulfillmentMessage: "",
},
refundPending: undefined,
@@ -143,20 +153,27 @@ export const Withdraw = createExample(TestedComponent, {
transaction: exampleData.withdraw,
});
-export const WithdrawOneMinuteAgo = createExample(TestedComponent, {
+export const WithdrawFiveMinutesAgo = createExample(TestedComponent, () => ({
transaction: {
...exampleData.withdraw,
- timestamp: TalerProtocolTimestamp.fromSeconds(new Date().getTime() - 60),
+ timestamp: TalerProtocolTimestamp.fromSeconds(
+ new Date().getTime() / 1000 - 60 * 5,
+ ),
},
-});
+}));
-export const WithdrawOneMinuteAgoAndPending = createExample(TestedComponent, {
- transaction: {
- ...exampleData.withdraw,
- timestamp: TalerProtocolTimestamp.fromSeconds(new Date().getTime() - 60),
- pending: true,
- },
-});
+export const WithdrawFiveMinutesAgoAndPending = createExample(
+ TestedComponent,
+ () => ({
+ transaction: {
+ ...exampleData.withdraw,
+ timestamp: TalerProtocolTimestamp.fromSeconds(
+ new Date().getTime() / 1000 - 60 * 5,
+ ),
+ pending: true,
+ },
+ }),
+);
export const WithdrawError = createExample(TestedComponent, {
transaction: {
@@ -177,17 +194,17 @@ export const WithdrawErrorInDevMode = createExampleInCustomContext(
{ value: true },
);
-export const WithdrawPendingManual = createExample(TestedComponent, {
+export const WithdrawPendingManual = createExample(TestedComponent, () => ({
transaction: {
...exampleData.withdraw,
withdrawalDetails: {
type: WithdrawalType.ManualTransfer,
exchangePaytoUris: ["payto://iban/asdasdasd"],
reservePub: "A05AJGMFNSK4Q62NXR2FKNDB1J4EXTYQTE7VA4M9GZQ4TR06YBNG",
- },
+ } as WithdrawalDetails,
pending: true,
},
-});
+}));
export const WithdrawPendingTalerBankUnconfirmed = createExample(
TestedComponent,
@@ -231,10 +248,95 @@ export const PaymentError = createExample(TestedComponent, {
},
});
-export const PaymentWithoutFee = createExample(TestedComponent, {
+export const PaymentWithRefund = createExample(TestedComponent, {
+ transaction: {
+ ...exampleData.payment,
+ amountRaw: "KUDOS:12",
+ totalRefundEffective: "KUDOS:1",
+ totalRefundRaw: "KUDOS:1",
+ },
+});
+
+export const PaymentWithDeliveryDate = createExample(TestedComponent, {
+ transaction: {
+ ...exampleData.payment,
+ amountRaw: "KUDOS:12",
+ info: {
+ ...exampleData.payment.info,
+ delivery_date: {
+ t_s: new Date().getTime() / 1000,
+ },
+ },
+ },
+});
+
+export const PaymentWithDeliveryAddr = createExample(TestedComponent, {
+ transaction: {
+ ...exampleData.payment,
+ amountRaw: "KUDOS:12",
+ info: {
+ ...exampleData.payment.info,
+ delivery_location: {
+ country: "Argentina",
+ street: "Elm Street",
+ district: "CABA",
+ post_code: "1101",
+ },
+ },
+ },
+});
+
+export const PaymentWithDeliveryFull = createExample(TestedComponent, {
+ transaction: {
+ ...exampleData.payment,
+ amountRaw: "KUDOS:12",
+ info: {
+ ...exampleData.payment.info,
+ delivery_date: {
+ t_s: new Date().getTime() / 1000,
+ },
+ delivery_location: {
+ country: "Argentina",
+ street: "Elm Street",
+ district: "CABA",
+ post_code: "1101",
+ },
+ },
+ },
+});
+
+export const PaymentWithRefundPending = createExample(TestedComponent, {
+ transaction: {
+ ...exampleData.payment,
+ amountRaw: "KUDOS:12",
+ refundPending: "KUDOS:3",
+ totalRefundEffective: "KUDOS:1",
+ totalRefundRaw: "KUDOS:1",
+ },
+});
+
+export const PaymentWithFeeAndRefund = createExample(TestedComponent, {
transaction: {
...exampleData.payment,
amountRaw: "KUDOS:11",
+ totalRefundEffective: "KUDOS:1",
+ totalRefundRaw: "KUDOS:1",
+ },
+});
+
+export const PaymentWithFeeAndRefundFee = createExample(TestedComponent, {
+ transaction: {
+ ...exampleData.payment,
+ amountRaw: "KUDOS:11",
+ totalRefundEffective: "KUDOS:1",
+ totalRefundRaw: "KUDOS:2",
+ },
+});
+
+export const PaymentWithoutFee = createExample(TestedComponent, {
+ transaction: {
+ ...exampleData.payment,
+ amountRaw: "KUDOS:12",
},
});
@@ -249,7 +351,7 @@ export const PaymentWithProducts = createExample(TestedComponent, {
...exampleData.payment,
info: {
...exampleData.payment.info,
- summary: "this order has 5 products",
+ summary: "summary of 5 products",
products: [
{
description: "t-shirt",
@@ -360,20 +462,3 @@ export const RefundError = createExample(TestedComponent, {
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/wallet/Transaction.tsx b/packages/taler-wallet-webextension/src/wallet/Transaction.tsx
index 3377f98c7..9ccb353a9 100644
--- a/packages/taler-wallet-webextension/src/wallet/Transaction.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/Transaction.tsx
@@ -16,14 +16,24 @@
import {
AbsoluteTime,
+ AmountJson,
Amounts,
+ Location,
NotificationType,
parsePaytoUri,
parsePayUri,
+ TalerProtocolTimestamp,
Transaction,
+ TransactionDeposit,
+ TransactionPayment,
+ TransactionRefresh,
+ TransactionRefund,
+ TransactionTip,
TransactionType,
+ TransactionWithdrawal,
WithdrawalType,
} from "@gnu-taler/taler-util";
+import { styled } from "@linaria/react";
import { differenceInSeconds } from "date-fns";
import { ComponentChildren, Fragment, h, VNode } from "preact";
import { useEffect, useState } from "preact/hooks";
@@ -33,15 +43,17 @@ import { BankDetailsByPaytoType } from "../components/BankDetailsByPaytoType.js"
import { ErrorTalerOperation } from "../components/ErrorTalerOperation.js";
import { Loading } from "../components/Loading.js";
import { LoadingError } from "../components/LoadingError.js";
-import { Part, PartPayto } from "../components/Part.js";
+import { Kind, Part, PartCollapsible, PartPayto } from "../components/Part.js";
import {
Button,
+ ButtonBox,
ButtonDestructive,
ButtonPrimary,
CenteredDialog,
InfoBox,
ListOfProducts,
Overlay,
+ Row,
RowBorderGray,
SmallLightText,
SubTitle,
@@ -119,6 +131,14 @@ export interface WalletTransactionProps {
onBack: () => void;
}
+const PurchaseDetailsTable = styled.table`
+ width: 100%;
+
+ & > tr > td:nth-child(2n) {
+ text-align: right;
+ }
+`;
+
export function TransactionView({
transaction,
onDelete,
@@ -168,9 +188,7 @@ export function TransactionView({
)}
-
+
@@ -189,10 +207,8 @@ export function TransactionView({
}
if (transaction.type === TransactionType.Withdrawal) {
- const fee = Amounts.sub(
- Amounts.parseOrThrow(transaction.amountRaw),
- Amounts.parseOrThrow(transaction.amountEffective),
- ).amount;
+ const total = Amounts.parseOrThrow(transaction.amountEffective);
+ const chosen = Amounts.parseOrThrow(transaction.amountRaw);
return (
{confirmBeforeForget ? (
@@ -219,205 +235,125 @@ export function TransactionView({
) : undefined}
-
- Withdrawal
-
-
- {transaction.pending ? (
- transaction.withdrawalDetails.type ===
- WithdrawalType.ManualTransfer ? (
-
-
-
-
+
+ {transaction.exchangeBaseUrl}
+
+
+ {!transaction.pending ? undefined : transaction.withdrawalDetails
+ .type === WithdrawalType.ManualTransfer ? (
+
+
+
+
+ Make sure to use the correct subject, otherwise the money will
+ not arrive in this wallet.
+
+
+
+ ) : (
+
+ {!transaction.withdrawalDetails.confirmed &&
+ transaction.withdrawalDetails.bankConfirmationUrl ? (
+
+
- Make sure to use the correct subject, otherwise the money
- will not arrive in this wallet.
-
-
-
-
Total withdrawn}
- text={ }
- kind="positive"
- />
- Exchange fee}
- text={ }
- kind="negative"
- />
-
- ) : (
-
- {!transaction.withdrawalDetails.confirmed &&
- transaction.withdrawalDetails.bankConfirmationUrl ? (
-
-
- The bank is waiting for confirmation. Go to the
+ The bank did not yet confirmed the wire transfer. Go to the
+ {` `}
bank site
-
+ {" "}
+ and check there is no pending step.
-
- ) : undefined}
- {transaction.withdrawalDetails.confirmed && (
-
-
- Waiting for the coins to arrive
-
-
- )}
- Total withdrawn}
- text={ }
- kind="positive"
- />
- Chosen amount}
- text={ }
- kind="neutral"
- />
- Exchange fee}
- text={ }
- kind="negative"
- />
-
- )
- ) : (
-
- Total withdrawn}
- text={ }
- kind="positive"
- />
- Chosen amount}
- text={ }
- kind="neutral"
- />
- Exchange fee}
- text={ }
- kind="negative"
- />
+
+
+ ) : undefined}
+ {transaction.withdrawalDetails.confirmed && (
+
+
+ Bank has confirmed the wire transfer. Waiting for the exchange
+ to send the coins
+
+
+ )}
)}
Exchange}
- text={new URL(transaction.exchangeBaseUrl).hostname}
- kind="neutral"
+ title={Details }
+ text={ }
/>
);
}
- const showLargePic = (): void => {
- return;
- };
-
if (transaction.type === TransactionType.Payment) {
- const fee = Amounts.sub(
- Amounts.parseOrThrow(transaction.amountEffective),
- Amounts.parseOrThrow(transaction.amountRaw),
- ).amount;
-
- const refundFee = Amounts.sub(
- Amounts.parseOrThrow(transaction.totalRefundRaw),
- Amounts.parseOrThrow(transaction.totalRefundEffective),
- ).amount;
- const refunded = Amounts.isNonZero(
- Amounts.parseOrThrow(transaction.totalRefundRaw),
- );
const pendingRefund =
transaction.refundPending === undefined
? undefined
: Amounts.parseOrThrow(transaction.refundPending);
+
+ const total = Amounts.sub(
+ Amounts.parseOrThrow(transaction.amountEffective),
+ Amounts.parseOrThrow(transaction.totalRefundEffective),
+ ).amount;
+
return (
-
- Payment
-
-
-
- Total paid}
- text={ }
+
- {Amounts.isNonZero(fee) && (
-
+ >
+ {transaction.info.fulfillmentUrl ? (
+
+ {transaction.info.summary}
+
+ ) : (
+ transaction.info.summary
+ )}
+
+
+ {pendingRefund !== undefined && Amounts.isNonZero(pendingRefund) && (
+
+
+ Merchant created a refund for this order but was not automatically
+ picked up.
+
Purchase amount}
- text={ }
- kind="neutral"
- />
- Purchase Fee}
- text={ }
- kind="negative"
- />
-
- )}
- {refunded && (
-
- Total refunded}
- text={ }
+ title={Offer }
+ text={ }
kind="positive"
/>
- {Amounts.isNonZero(refundFee) && (
-
- Refund amount}
- text={ }
- kind="neutral"
- />
- Refund fee}
- text={ }
- kind="negative"
- />
-
- )}
-
- )}
- {pendingRefund !== undefined && Amounts.isNonZero(pendingRefund) && (
- Refund pending}
- text={ }
- kind="positive"
- />
+
+
)}
Merchant}
@@ -425,268 +361,630 @@ export function TransactionView({
kind="neutral"
/>
Purchase}
- text={
- transaction.info.fulfillmentUrl ? (
-
- {transaction.info.summary}
-
- ) : (
- transaction.info.summary
- )
- }
+ title={Invoice ID }
+ text={transaction.info.orderId}
kind="neutral"
/>
Receipt}
- text={`#${transaction.info.orderId}`}
+ title={Details }
+ text={ }
kind="neutral"
/>
-
-
- {transaction.info.products && transaction.info.products.length > 0 && (
-
- {transaction.info.products.map((p, k) => (
-
-
-
-
-
- {p.quantity && p.quantity > 0 && (
-
- x {p.quantity} {p.unit}
-
- )}
-
{p.description}
-
-
- ))}
-
- )}
-
);
}
if (transaction.type === TransactionType.Deposit) {
- const fee = Amounts.sub(
- Amounts.parseOrThrow(transaction.amountEffective),
- Amounts.parseOrThrow(transaction.amountRaw),
- ).amount;
+ const total = Amounts.parseOrThrow(transaction.amountRaw);
const payto = parsePaytoUri(transaction.targetPaytoUri);
return (
-
- Deposit
-
-
-
+
+ {transaction.targetPaytoUri}
+
+ {payto && }
Total send}
- text={ }
+ title={Details }
+ text={ }
kind="neutral"
/>
- {Amounts.isNonZero(fee) && (
-
- Deposit amount}
- text={ }
- kind="positive"
- />
- Fee}
- text={ }
- kind="negative"
- />
-
- )}
- {payto && }
);
}
if (transaction.type === TransactionType.Refresh) {
- const fee = Amounts.sub(
+ const total = Amounts.sub(
Amounts.parseOrThrow(transaction.amountRaw),
Amounts.parseOrThrow(transaction.amountEffective),
).amount;
+
return (
-
- Refresh
-
-
-
- Total refresh}
- text={ }
+
+ {transaction.exchangeBaseUrl}
+
+ Details}
+ text={ }
/>
- {Amounts.isNonZero(fee) && (
-
- Refresh amount}
- text={ }
- kind="neutral"
- />
- Fee}
- text={ }
- kind="negative"
- />
-
- )}
);
}
if (transaction.type === TransactionType.Tip) {
- const fee = Amounts.sub(
- Amounts.parseOrThrow(transaction.amountRaw),
- Amounts.parseOrThrow(transaction.amountEffective),
- ).amount;
+ const total = Amounts.parseOrThrow(transaction.amountEffective);
+
return (
-
- Tip
-
-
-
- Total tip}
- text={ }
+
+ {transaction.merchantBaseUrl}
+
+ {/* Merchant}
+ text={transaction.info.merchant.name}
+ kind="neutral"
+ />
+ Invoice ID}
+ text={transaction.info.orderId}
+ kind="neutral"
+ /> */}
+ Details}
+ text={ }
/>
- {Amounts.isNonZero(fee) && (
-
- Received amount}
- text={ }
- kind="neutral"
- />
- Fee}
- text={ }
- kind="negative"
- />
-
- )}
);
}
if (transaction.type === TransactionType.Refund) {
- const fee = Amounts.sub(
- Amounts.parseOrThrow(transaction.amountRaw),
- Amounts.parseOrThrow(transaction.amountEffective),
- ).amount;
+ const total = Amounts.parseOrThrow(transaction.amountEffective);
return (
-
- Refund
-
-
-
- Total refund}
- text={ }
+
- {Amounts.isNonZero(fee) && (
-
- Refund amount}
- text={ }
- kind="neutral"
- />
- Fee}
- text={ }
- kind="negative"
- />
-
- )}
+ >
+ {transaction.info.summary}
+
+
Merchant}
text={transaction.info.merchant.name}
kind="neutral"
/>
-
Purchase}
+ title={Original order ID }
text={
- {transaction.info.summary}
+ {transaction.info.orderId}
}
kind="neutral"
/>
Receipt}
- text={`#${transaction.info.orderId}`}
+ title={Purchase summary }
+ text={transaction.info.summary}
kind="neutral"
/>
-
-
- {transaction.info.products && transaction.info.products.length > 0 && (
-
- {transaction.info.products.map((p, k) => (
-
-
-
-
-
- {p.quantity && p.quantity > 0 && (
-
- x {p.quantity} {p.unit}
-
- )}
-
{p.description}
-
-
- ))}
-
- )}
-
+ Details}
+ text={ }
+ />
);
}
return
;
}
+
+function DeliveryDetails({
+ date,
+ location,
+}: {
+ date: TalerProtocolTimestamp | undefined;
+ location: Location | undefined;
+}): VNode {
+ const { i18n } = useTranslationContext();
+ return (
+
+ {location && (
+
+ {location.country && (
+
+
+ Country
+
+ {location.country}
+
+ )}
+ {location.address_lines && (
+
+
+ Address lines
+
+ {location.address_lines}
+
+ )}
+ {location.building_number && (
+
+
+ Building number
+
+ {location.building_number}
+
+ )}
+ {location.building_name && (
+
+
+ Building name
+
+ {location.building_name}
+
+ )}
+ {location.street && (
+
+
+ Street
+
+ {location.street}
+
+ )}
+ {location.post_code && (
+
+
+ Post code
+
+ {location.post_code}
+
+ )}
+ {location.town_location && (
+
+
+ Town location
+
+ {location.town_location}
+
+ )}
+ {location.town && (
+
+
+ Town
+
+ {location.town}
+
+ )}
+ {location.district && (
+
+
+ District
+
+ {location.district}
+
+ )}
+ {location.country_subdivision && (
+
+
+ Country subdivision
+
+ {location.country_subdivision}
+
+ )}
+
+ )}
+
+ {!location || !date ? undefined : (
+
+
+
+
+
+ )}
+ {date && (
+
+
+ Date
+
+
+
+
+
+ )}
+
+ );
+}
+
+function PurchaseDetails({
+ transaction,
+}: {
+ transaction: TransactionPayment;
+}): VNode {
+ const { i18n } = useTranslationContext();
+
+ const partialFee = Amounts.sub(
+ Amounts.parseOrThrow(transaction.amountEffective),
+ Amounts.parseOrThrow(transaction.amountRaw),
+ ).amount;
+
+ const refundRaw = Amounts.parseOrThrow(transaction.totalRefundRaw);
+
+ const refundFee = Amounts.sub(
+ refundRaw,
+ Amounts.parseOrThrow(transaction.totalRefundEffective),
+ ).amount;
+
+ const fee = Amounts.sum([partialFee, refundFee]).amount;
+
+ const hasProducts =
+ transaction.info.products && transaction.info.products.length > 0;
+
+ const hasShipping =
+ transaction.info.delivery_date !== undefined ||
+ transaction.info.delivery_location !== undefined;
+
+ const showLargePic = (): void => {
+ return;
+ };
+
+ const total = Amounts.sub(
+ Amounts.parseOrThrow(transaction.amountEffective),
+ Amounts.parseOrThrow(transaction.totalRefundEffective),
+ ).amount;
+
+ return (
+
+
+ Price
+
+
+
+
+
+ {Amounts.isNonZero(refundRaw) && (
+
+ Refunded
+
+
+
+
+ )}
+ {Amounts.isNonZero(fee) && (
+
+ Transaction fees
+
+
+
+
+ )}
+
+
+
+
+
+
+ Total
+
+
+
+
+ {hasProducts && (
+
+
+ Products}
+ text={
+
+ {transaction.info.products?.map((p, k) => (
+
+
+
+
+
+ {p.quantity && p.quantity > 0 && (
+
+ x {p.quantity} {p.unit}
+
+ )}
+
{p.description}
+
+
+ ))}
+
+ }
+ />
+
+
+ )}
+ {hasShipping && (
+
+
+ Delivery}
+ text={
+
+ }
+ />
+
+
+ )}
+
+ );
+}
+
+function RefundDetails({
+ transaction,
+}: {
+ transaction: TransactionRefund;
+}): VNode {
+ const { i18n } = useTranslationContext();
+
+ const fee = Amounts.sub(
+ Amounts.parseOrThrow(transaction.amountRaw),
+ Amounts.parseOrThrow(transaction.amountEffective),
+ ).amount;
+
+ return (
+
+
+ Amount
+
+
+
+
+
+ {Amounts.isNonZero(fee) && (
+
+ Transaction fees
+
+
+
+
+ )}
+
+
+
+
+
+
+ Total
+
+
+
+
+
+ );
+}
+
+function DepositDetails({
+ transaction,
+}: {
+ transaction: TransactionDeposit;
+}): VNode {
+ const { i18n } = useTranslationContext();
+
+ const fee = Amounts.sub(
+ Amounts.parseOrThrow(transaction.amountRaw),
+ Amounts.parseOrThrow(transaction.amountEffective),
+ ).amount;
+
+ return (
+
+
+ Amount
+
+
+
+
+
+ {Amounts.isNonZero(fee) && (
+
+ Transaction fees
+
+
+
+
+ )}
+
+
+
+
+
+
+ Total transfer
+
+
+
+
+
+ );
+}
+function RefreshDetails({
+ transaction,
+}: {
+ transaction: TransactionRefresh;
+}): VNode {
+ const { i18n } = useTranslationContext();
+
+ const fee = Amounts.sub(
+ Amounts.parseOrThrow(transaction.amountRaw),
+ Amounts.parseOrThrow(transaction.amountEffective),
+ ).amount;
+
+ return (
+
+
+ Amount
+
+
+
+
+
+
+
+
+
+
+ Transaction fees
+
+
+
+
+
+ );
+}
+
+function TipDetails({ transaction }: { transaction: TransactionTip }): VNode {
+ const { i18n } = useTranslationContext();
+
+ const fee = Amounts.sub(
+ Amounts.parseOrThrow(transaction.amountRaw),
+ Amounts.parseOrThrow(transaction.amountEffective),
+ ).amount;
+
+ return (
+
+
+ Amount
+
+
+
+
+
+ {Amounts.isNonZero(fee) && (
+
+ Transaction fees
+
+
+
+
+ )}
+
+
+
+
+
+
+ Total
+
+
+
+
+
+ );
+}
+
+function WithdrawDetails({
+ transaction,
+}: {
+ transaction: TransactionWithdrawal;
+}): VNode {
+ const { i18n } = useTranslationContext();
+
+ const fee = Amounts.sub(
+ Amounts.parseOrThrow(transaction.amountRaw),
+ Amounts.parseOrThrow(transaction.amountEffective),
+ ).amount;
+
+ return (
+
+
+ Withdraw
+
+
+
+
+
+ {Amounts.isNonZero(fee) && (
+
+ Transaction fees
+
+
+
+
+ )}
+
+
+
+
+
+
+ Total
+
+
+
+
+
+ );
+}
+
+function Header({
+ timestamp,
+ total,
+ children,
+ kind,
+ type,
+}: {
+ timestamp: TalerProtocolTimestamp;
+ total: AmountJson;
+ children: ComponentChildren;
+ kind: Kind;
+ type: string;
+}): VNode {
+ return (
+
+
+ {children}
+
+
+
+
+ }
+ kind={kind}
+ showSign
+ />
+
+
+
+ );
+}
diff --git a/packages/taler-wallet-webextension/static-dev/merchant-icon-11.jpeg b/packages/taler-wallet-webextension/static-dev/merchant-icon-11.jpeg
new file mode 100644
index 0000000000000000000000000000000000000000..1777936c86c84bbc5a01f7a35efbb45c4a041489
GIT binary patch
literal 60184
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