diff options
Diffstat (limited to 'packages/taler-wallet-webextension/src/wallet')
15 files changed, 546 insertions, 1111 deletions
diff --git a/packages/taler-wallet-webextension/src/wallet/History.stories.tsx b/packages/taler-wallet-webextension/src/wallet/History.stories.tsx new file mode 100644 index 000000000..f50fd3b68 --- /dev/null +++ b/packages/taler-wallet-webextension/src/wallet/History.stories.tsx @@ -0,0 +1,294 @@ +/* + 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: 'wallet/history/list', + component: TestedComponent, +}; + +let count = 0 +const commonTransaction = () => ({ + amountRaw: 'USD:10', + amountEffective: 'USD:9', + pending: false, + timestamp: { + t_ms: new Date().getTime() - (count++ * 1000*60*60*7) + }, + 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: [], + balances: [{ + available: 'TESTKUDOS:10', + pendingIncoming: 'TESTKUDOS:0', + pendingOutgoing: 'TESTKUDOS:0', + hasPendingTransactions: false, + requiresUserInput: false, + }] +}); + + +export const One = createExample(TestedComponent, { + list: [exampleData.withdraw], + balances: [{ + available: 'USD:10', + pendingIncoming: 'USD:0', + pendingOutgoing: 'USD:0', + hasPendingTransactions: false, + requiresUserInput: false, + }] +}); + +export const Several = createExample(TestedComponent, { + list: [ + exampleData.withdraw, + exampleData.payment, + exampleData.withdraw, + exampleData.payment, + exampleData.refresh, + exampleData.refund, + exampleData.tip, + exampleData.deposit, + ], + balances: [{ + available: 'TESTKUDOS:10', + pendingIncoming: 'TESTKUDOS:0', + pendingOutgoing: 'TESTKUDOS:0', + hasPendingTransactions: false, + requiresUserInput: false, + }] +}); + +export const SeveralWithTwoCurrencies = createExample(TestedComponent, { + list: [ + exampleData.withdraw, + exampleData.payment, + exampleData.withdraw, + exampleData.payment, + exampleData.refresh, + exampleData.refund, + exampleData.tip, + exampleData.deposit, + ], + balances: [{ + available: 'TESTKUDOS:10', + pendingIncoming: 'TESTKUDOS:0', + pendingOutgoing: 'TESTKUDOS:0', + hasPendingTransactions: false, + requiresUserInput: false, + },{ + available: 'USD:10', + pendingIncoming: 'USD:0', + pendingOutgoing: 'USD:0', + hasPendingTransactions: false, + requiresUserInput: false, + }] +}); + +// 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/wallet/History.tsx b/packages/taler-wallet-webextension/src/wallet/History.tsx new file mode 100644 index 000000000..6ef5047ae --- /dev/null +++ b/packages/taler-wallet-webextension/src/wallet/History.tsx @@ -0,0 +1,248 @@ +/* + This file is part of TALER + (C) 2016 GNUnet e.V. + + 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. + + 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 + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ + +import { AmountString, Balance, Timestamp, Transaction, TransactionsResponse, TransactionType } from "@gnu-taler/taler-util"; +import { format } from "date-fns"; +import { Fragment, JSX } from "preact"; +import { useEffect, useState } from "preact/hooks"; +import imageBank from '../../static/img/ri-bank-line.svg'; +import imageHandHeart from '../../static/img/ri-hand-heart-line.svg'; +import imageRefresh from '../../static/img/ri-refresh-line.svg'; +import imageRefund from '../../static/img/ri-refund-2-line.svg'; +import imageShoppingCart from '../../static/img/ri-shopping-cart-line.svg'; +import { Column, ExtraLargeText, HistoryRow, WalletBox, DateSeparator, SmallTextLight } from "../components/styled"; +import { useBalances } from "../hooks/useBalances"; +import * as wxApi from "../wxApi"; +import { Pages } from "../NavigationBar"; + + +export function HistoryPage(props: any): JSX.Element { + const [transactions, setTransactions] = useState< + TransactionsResponse | undefined + >(undefined); + const balance = useBalances() + const balanceWithoutError = balance?.error ? [] : (balance?.response.balances || []) + + useEffect(() => { + const fetchData = async (): Promise<void> => { + const res = await wxApi.getTransactions(); + setTransactions(res); + }; + fetchData(); + }, []); + + if (!transactions) { + return <div>Loading ...</div>; + } + + return <HistoryView balances={balanceWithoutError} list={[...transactions.transactions].reverse()} />; +} + +function amountToString(c: AmountString) { + const idx = c.indexOf(':') + return `${c.substring(idx + 1)} ${c.substring(0, idx)}` +} + + + +export function HistoryView({ list, balances }: { list: Transaction[], balances: Balance[] }) { + const byDate = list.reduce(function (rv, x) { + const theDate = x.timestamp.t_ms === "never" ? "never" : format(x.timestamp.t_ms, 'dd MMMM yyyy'); + (rv[theDate] = rv[theDate] || []).push(x); + return rv; + }, {} as { [x: string]: Transaction[] }); + + return <WalletBox noPadding> + {balances.length > 0 && <header> + {balances.length === 1 && <div class="title"> + Balance: <span>{amountToString(balances[0].available)}</span> + </div>} + {balances.length > 1 && <div class="title"> + Balance: <ul style={{ margin: 0 }}> + {balances.map(b => <li>{b.available}</li>)} + </ul> + </div>} + </header>} + <section> + {Object.keys(byDate).map(d => { + return <Fragment> + <DateSeparator>{d}</DateSeparator> + {byDate[d].map((tx, i) => ( + <TransactionItem key={i} tx={tx} /> + ))} + </Fragment> + })} + </section> + </WalletBox> +} + +function TransactionItem(props: { tx: Transaction }): JSX.Element { + const tx = props.tx; + switch (tx.type) { + case TransactionType.Withdrawal: + return ( + <TransactionLayout + id={tx.transactionId} + amount={tx.amountEffective} + debitCreditIndicator={"credit"} + title="Withdrawal" + subtitle={`via ${tx.exchangeBaseUrl}`} + timestamp={tx.timestamp} + iconPath={imageBank} + pending={tx.pending} + ></TransactionLayout> + ); + case TransactionType.Payment: + return ( + <TransactionLayout + id={tx.transactionId} + amount={tx.amountEffective} + debitCreditIndicator={"debit"} + title="Payment" + subtitle={tx.info.summary} + timestamp={tx.timestamp} + iconPath={imageShoppingCart} + pending={tx.pending} + ></TransactionLayout> + ); + case TransactionType.Refund: + return ( + <TransactionLayout + id={tx.transactionId} + amount={tx.amountEffective} + debitCreditIndicator={"credit"} + title="Refund" + subtitle={tx.info.summary} + timestamp={tx.timestamp} + iconPath={imageRefund} + pending={tx.pending} + ></TransactionLayout> + ); + case TransactionType.Tip: + return ( + <TransactionLayout + id={tx.transactionId} + amount={tx.amountEffective} + debitCreditIndicator={"credit"} + title="Tip" + subtitle={`from ${new URL(tx.merchantBaseUrl).hostname}`} + timestamp={tx.timestamp} + iconPath={imageHandHeart} + pending={tx.pending} + ></TransactionLayout> + ); + case TransactionType.Refresh: + return ( + <TransactionLayout + id={tx.transactionId} + amount={tx.amountEffective} + debitCreditIndicator={"credit"} + title="Refresh" + subtitle={`via exchange ${tx.exchangeBaseUrl}`} + timestamp={tx.timestamp} + iconPath={imageRefresh} + pending={tx.pending} + ></TransactionLayout> + ); + case TransactionType.Deposit: + return ( + <TransactionLayout + id={tx.transactionId} + amount={tx.amountEffective} + debitCreditIndicator={"debit"} + title="Refresh" + subtitle={`to ${tx.targetPaytoUri}`} + timestamp={tx.timestamp} + iconPath={imageRefresh} + pending={tx.pending} + ></TransactionLayout> + ); + } +} + +function TransactionLayout(props: TransactionLayoutProps): JSX.Element { + const date = new Date(props.timestamp.t_ms); + const dateStr = format(date, 'HH:mm:ss') + return ( + // <a href={Pages.transaction.replace(':tid', props.id)}> + <HistoryRow href={Pages.transaction.replace(':tid', props.id)}> + <img src={props.iconPath} /> + <Column> + <ExtraLargeText> + <span>{props.title}</span> + {props.pending ? ( + <span style={{ color: "darkblue" }}> (Pending)</span> + ) : null} + </ExtraLargeText> + <SmallTextLight>{dateStr}</SmallTextLight> + </Column> + <TransactionAmount + pending={props.pending} + amount={props.amount} + debitCreditIndicator={props.debitCreditIndicator} + /> + </HistoryRow> + // </a> + ); +} + +interface TransactionLayoutProps { + debitCreditIndicator: "debit" | "credit" | "unknown"; + amount: AmountString | "unknown"; + timestamp: Timestamp; + title: string; + id: string; + subtitle: string; + iconPath: string; + pending: boolean; +} + +interface TransactionAmountProps { + debitCreditIndicator: "debit" | "credit" | "unknown"; + amount: AmountString | "unknown"; + pending: boolean; +} + +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 = ""; + } + return ( + <Column style={{ + color: + props.pending ? "gray" : + (sign === '+' ? 'darkgreen' : + (sign === '-' ? 'darkred' : + undefined)) + }}> + <ExtraLargeText> + {sign} + {amount} + </ExtraLargeText> + <div>{currency}</div> + </Column> + ); +} + diff --git a/packages/taler-wallet-webextension/src/wallet/Pay.stories.tsx b/packages/taler-wallet-webextension/src/wallet/Pay.stories.tsx deleted file mode 100644 index 0297d6264..000000000 --- a/packages/taler-wallet-webextension/src/wallet/Pay.stories.tsx +++ /dev/null @@ -1,103 +0,0 @@ -/* - 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 { ContractTerms, PreparePayResultType } from '@gnu-taler/taler-util'; -import { FunctionalComponent, h } from 'preact'; -import { PaymentRequestView as TestedComponent } from './Pay'; - - -export default { - title: 'wallet/pay', - component: TestedComponent, - argTypes: { - }, -}; - -function createExample<Props>(Component: FunctionalComponent<Props>, props: Partial<Props>) { - const r = (args: any) => <Component {...args} /> - r.args = props - return r -} - -export const InsufficientBalance = createExample(TestedComponent, { - payStatus: { - status: PreparePayResultType.InsufficientBalance, - proposalId: "proposal1234", - contractTerms: { - merchant: { - name: 'someone' - }, - amount: 'USD:10', - } as Partial<ContractTerms> as any, - amountRaw: 'USD:10', - } -}); - -export const PaymentPossible = createExample(TestedComponent, { - payStatus: { - status: PreparePayResultType.PaymentPossible, - amountEffective: 'USD:10', - amountRaw: 'USD:10', - contractTerms: { - merchant: { - name: 'someone' - }, - amount: 'USD:10', - } as Partial<ContractTerms> as any, - contractTermsHash: '123456', - proposalId: 'proposal1234' - } -}); - -export const AlreadyConfirmedWithFullfilment = createExample(TestedComponent, { - payStatus: { - status: PreparePayResultType.AlreadyConfirmed, - amountEffective: 'USD:10', - amountRaw: 'USD:10', - contractTerms: { - merchant: { - name: 'someone' - }, - fulfillment_message: 'congratulations! you are looking at the fulfillment message! ', - amount: 'USD:10', - } as Partial<ContractTerms> as any, - contractTermsHash: '123456', - proposalId: 'proposal1234', - paid: false, - } -}); - -export const AlreadyConfirmedWithoutFullfilment = createExample(TestedComponent, { - payStatus: { - status: PreparePayResultType.AlreadyConfirmed, - amountEffective: 'USD:10', - amountRaw: 'USD:10', - contractTerms: { - merchant: { - name: 'someone' - }, - amount: 'USD:10', - } as Partial<ContractTerms> as any, - contractTermsHash: '123456', - proposalId: 'proposal1234', - paid: false, - } -}); diff --git a/packages/taler-wallet-webextension/src/wallet/Pay.tsx b/packages/taler-wallet-webextension/src/wallet/Pay.tsx deleted file mode 100644 index a5849bb28..000000000 --- a/packages/taler-wallet-webextension/src/wallet/Pay.tsx +++ /dev/null @@ -1,253 +0,0 @@ -/* - This file is part of TALER - (C) 2015 GNUnet e.V. - - 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. - - 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 - TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> - */ - -/** - * Page shown to the user to confirm entering - * a contract. - */ - -/** - * Imports. - */ -// import * as i18n from "../i18n"; - -import { renderAmount, ProgressButton } from "../renderHtml"; -import * as wxApi from "../wxApi"; - -import { useState, useEffect } from "preact/hooks"; - -import { ConfirmPayResultDone, getJsonI18n, i18n } from "@gnu-taler/taler-util"; -import { - PreparePayResult, - ConfirmPayResult, - AmountJson, - PreparePayResultType, - Amounts, - ContractTerms, - ConfirmPayResultType, -} from "@gnu-taler/taler-util"; -import { JSX, VNode } from "preact"; - -interface Props { - talerPayUri?: string -} - -export function AlreadyPaid({ payStatus }: { payStatus: PreparePayResult }) { - const fulfillmentUrl = payStatus.contractTerms.fulfillment_url; - let message; - if (fulfillmentUrl) { - message = ( - <span> - You have already paid for this article. Click{" "} - <a href={fulfillmentUrl} target="_bank" rel="external">here</a> to view it again. - </span> - ); - } else { - message = <span> - You have already paid for this article:{" "} - <em> - {payStatus.contractTerms.fulfillment_message ?? "no message given"} - </em> - </span>; - } - return <section class="main"> - <h1>GNU Taler Wallet</h1> - <article class="fade"> - {message} - </article> - </section> -} - -const doPayment = async (payStatus: PreparePayResult): Promise<ConfirmPayResultDone> => { - if (payStatus.status !== "payment-possible") { - throw Error(`invalid state: ${payStatus.status}`); - } - const proposalId = payStatus.proposalId; - const res = await wxApi.confirmPay(proposalId, undefined); - if (res.type !== ConfirmPayResultType.Done) { - throw Error("payment pending"); - } - const fu = res.contractTerms.fulfillment_url; - if (fu) { - document.location.href = fu; - } - return res; -}; - - - -export function PayPage({ talerPayUri }: Props): JSX.Element { - const [payStatus, setPayStatus] = useState<PreparePayResult | undefined>(undefined); - const [payResult, setPayResult] = useState<ConfirmPayResult | undefined>(undefined); - const [payErrMsg, setPayErrMsg] = useState<string | undefined>(""); - - useEffect(() => { - if (!talerPayUri) return; - const doFetch = async (): Promise<void> => { - const p = await wxApi.preparePay(talerPayUri); - setPayStatus(p); - }; - doFetch(); - }, [talerPayUri]); - - if (!talerPayUri) { - return <span>missing pay uri</span> - } - - if (!payStatus) { - return <span>Loading payment information ...</span>; - } - - if (payResult && payResult.type === ConfirmPayResultType.Done) { - if (payResult.contractTerms.fulfillment_message) { - const obj = { - fulfillment_message: payResult.contractTerms.fulfillment_message, - fulfillment_message_i18n: - payResult.contractTerms.fulfillment_message_i18n, - }; - const msg = getJsonI18n(obj, "fulfillment_message"); - return ( - <div> - <p>Payment succeeded.</p> - <p>{msg}</p> - </div> - ); - } else { - return <span>Redirecting ...</span>; - } - } - - const onClick = async () => { - try { - const res = await doPayment(payStatus) - setPayResult(res); - } catch (e) { - console.error(e); - setPayErrMsg(e.message); - } - - } - - return <PaymentRequestView payStatus={payStatus} onClick={onClick} payErrMsg={payErrMsg} />; -} - -export interface PaymentRequestViewProps { - payStatus: PreparePayResult; - onClick: () => void; - payErrMsg?: string; - -} -export function PaymentRequestView({ payStatus, onClick, payErrMsg }: PaymentRequestViewProps) { - let totalFees: AmountJson | undefined = undefined; - let insufficientBalance = false; - const [loading, setLoading] = useState(false); - const contractTerms: ContractTerms = payStatus.contractTerms; - - if ( - payStatus.status === PreparePayResultType.AlreadyConfirmed - ) { - return <AlreadyPaid payStatus={payStatus} /> - } - - if (!contractTerms) { - return ( - <span> - Error: did not get contract terms from merchant or wallet backend. - </span> - ); - } - - if (payStatus.status == PreparePayResultType.InsufficientBalance) { - insufficientBalance = true; - } - - if (payStatus.status === PreparePayResultType.PaymentPossible) { - const amountRaw = Amounts.parseOrThrow(payStatus.amountRaw); - const amountEffective: AmountJson = Amounts.parseOrThrow( - payStatus.amountEffective, - ); - totalFees = Amounts.sub(amountEffective, amountRaw).amount; - } - - let merchantName: VNode; - if (contractTerms.merchant && contractTerms.merchant.name) { - merchantName = <strong>{contractTerms.merchant.name}</strong>; - } else { - merchantName = <strong>(pub: {contractTerms.merchant_pub})</strong>; - } - - const amount = ( - <strong>{renderAmount(Amounts.parseOrThrow(contractTerms.amount))}</strong> - ); - - return <section class="main"> - <h1>GNU Taler Wallet</h1> - <article class="fade"> - <div> - <p> - <i18n.Translate> - The merchant <span>{merchantName}</span> offers you to purchase: - </i18n.Translate> - <div style={{ textAlign: "center" }}> - <strong>{contractTerms.summary}</strong> - </div> - {totalFees ? ( - <i18n.Translate> - The total price is <span>{amount} </span> - (plus <span>{renderAmount(totalFees)}</span> fees). - </i18n.Translate> - ) : ( - <i18n.Translate> - The total price is <span>{amount}</span>. - </i18n.Translate> - )} - </p> - - {insufficientBalance ? ( - <div> - <p style={{ color: "red", fontWeight: "bold" }}> - Unable to pay: Your balance is insufficient. - </p> - </div> - ) : null} - - {payErrMsg ? ( - <div> - <p>Payment failed: {payErrMsg}</p> - <button - class="pure-button button-success" - onClick={onClick} - > - {i18n.str`Retry`} - </button> - </div> - ) : ( - <div> - <ProgressButton - isLoading={loading} - disabled={insufficientBalance} - onClick={onClick} - > - {i18n.str`Confirm payment`} - </ProgressButton> - </div> - )} - </div> - </article> - </section> - - -}
\ No newline at end of file diff --git a/packages/taler-wallet-webextension/src/wallet/Refund.stories.tsx b/packages/taler-wallet-webextension/src/wallet/Refund.stories.tsx deleted file mode 100644 index 044141f0c..000000000 --- a/packages/taler-wallet-webextension/src/wallet/Refund.stories.tsx +++ /dev/null @@ -1,83 +0,0 @@ -/* - 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 { ContractTerms, OrderShortInfo, PreparePayResultType } from '@gnu-taler/taler-util'; -import { FunctionalComponent, h } from 'preact'; -import { View as TestedComponent } from './Refund'; - - -export default { - title: 'wallet/refund', - component: TestedComponent, - argTypes: { - }, -}; - -function createExample<Props>(Component: FunctionalComponent<Props>, props: Partial<Props>) { - const r = (args: any) => <Component {...args} /> - r.args = props - return r -} - -export const Complete = createExample(TestedComponent, { - applyResult: { - amountEffectivePaid: 'USD:10', - amountRefundGone: 'USD:0', - amountRefundGranted: 'USD:2', - contractTermsHash: 'QWEASDZXC', - info: { - summary: 'tasty cold beer', - contractTermsHash: 'QWEASDZXC', - } as Partial<OrderShortInfo> as any, - pendingAtExchange: false, - proposalId: "proposal123", - } -}); - -export const Partial = createExample(TestedComponent, { - applyResult: { - amountEffectivePaid: 'USD:10', - amountRefundGone: 'USD:1', - amountRefundGranted: 'USD:2', - contractTermsHash: 'QWEASDZXC', - info: { - summary: 'tasty cold beer', - contractTermsHash: 'QWEASDZXC', - } as Partial<OrderShortInfo> as any, - pendingAtExchange: false, - proposalId: "proposal123", - } -}); - -export const InProgress = createExample(TestedComponent, { - applyResult: { - amountEffectivePaid: 'USD:10', - amountRefundGone: 'USD:1', - amountRefundGranted: 'USD:2', - contractTermsHash: 'QWEASDZXC', - info: { - summary: 'tasty cold beer', - contractTermsHash: 'QWEASDZXC', - } as Partial<OrderShortInfo> as any, - pendingAtExchange: true, - proposalId: "proposal123", - } -}); diff --git a/packages/taler-wallet-webextension/src/wallet/Refund.tsx b/packages/taler-wallet-webextension/src/wallet/Refund.tsx deleted file mode 100644 index bb26d933b..000000000 --- a/packages/taler-wallet-webextension/src/wallet/Refund.tsx +++ /dev/null @@ -1,95 +0,0 @@ -/* - This file is part of TALER - (C) 2015-2016 GNUnet e.V. - - 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. - - 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 - TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> - */ - -/** - * Page that shows refund status for purchases. - * - * @author Florian Dold - */ - -import * as wxApi from "../wxApi"; -import { AmountView } from "../renderHtml"; -import { - ApplyRefundResponse, - Amounts, -} from "@gnu-taler/taler-util"; -import { useEffect, useState } from "preact/hooks"; -import { JSX } from "preact/jsx-runtime"; - -interface Props { - talerRefundUri?: string -} -export interface ViewProps { - applyResult: ApplyRefundResponse; -} -export function View({ applyResult }: ViewProps) { - return <section class="main"> - <h1>GNU Taler Wallet</h1> - <article class="fade"> - <h2>Refund Status</h2> - <p> - The product <em>{applyResult.info.summary}</em> has received a total - effective refund of{" "} - <AmountView amount={applyResult.amountRefundGranted} />. - </p> - {applyResult.pendingAtExchange ? ( - <p>Refund processing is still in progress.</p> - ) : null} - {!Amounts.isZero(applyResult.amountRefundGone) ? ( - <p> - The refund amount of{" "} - <AmountView amount={applyResult.amountRefundGone} />{" "} - could not be applied. - </p> - ) : null} - </article> - </section> -} -export function RefundPage({ talerRefundUri }: Props): JSX.Element { - const [applyResult, setApplyResult] = useState<ApplyRefundResponse | undefined>(undefined); - const [errMsg, setErrMsg] = useState<string | undefined>(undefined); - - useEffect(() => { - if (!talerRefundUri) return; - const doFetch = async (): Promise<void> => { - try { - const result = await wxApi.applyRefund(talerRefundUri); - setApplyResult(result); - } catch (e) { - console.error(e); - setErrMsg(e.message); - console.log("err message", e.message); - } - }; - doFetch(); - }, [talerRefundUri]); - - console.log("rendering"); - - if (!talerRefundUri) { - return <span>missing taler refund uri</span>; - } - - if (errMsg) { - return <span>Error: {errMsg}</span>; - } - - if (!applyResult) { - return <span>Updating refund status</span>; - } - - return <View applyResult={applyResult} />; -} diff --git a/packages/taler-wallet-webextension/src/wallet/Tip.stories.tsx b/packages/taler-wallet-webextension/src/wallet/Tip.stories.tsx deleted file mode 100644 index ffd976144..000000000 --- a/packages/taler-wallet-webextension/src/wallet/Tip.stories.tsx +++ /dev/null @@ -1,66 +0,0 @@ -/* - 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 { ContractTerms, PreparePayResultType } from '@gnu-taler/taler-util'; -import { FunctionalComponent, h } from 'preact'; -import { View as TestedComponent } from './Tip'; - - -export default { - title: 'wallet/tip', - component: TestedComponent, - argTypes: { - }, -}; - -function createExample<Props>(Component: FunctionalComponent<Props>, props: Partial<Props>) { - const r = (args: any) => <Component {...args} /> - r.args = props - return r -} - -export const Accepted = createExample(TestedComponent, { - prepareTipResult: { - accepted: true, - merchantBaseUrl: '', - exchangeBaseUrl: '', - expirationTimestamp : { - t_ms: 0 - }, - tipAmountEffective: 'USD:10', - tipAmountRaw: 'USD:5', - walletTipId: 'id' - } -}); - -export const NotYetAccepted = createExample(TestedComponent, { - prepareTipResult: { - accepted: false, - merchantBaseUrl: 'http://merchant.url/', - exchangeBaseUrl: 'http://exchange.url/', - expirationTimestamp : { - t_ms: 0 - }, - tipAmountEffective: 'USD:10', - tipAmountRaw: 'USD:5', - walletTipId: 'id' - } -}); diff --git a/packages/taler-wallet-webextension/src/wallet/Tip.tsx b/packages/taler-wallet-webextension/src/wallet/Tip.tsx deleted file mode 100644 index 69886668b..000000000 --- a/packages/taler-wallet-webextension/src/wallet/Tip.tsx +++ /dev/null @@ -1,110 +0,0 @@ -/* - This file is part of TALER - (C) 2017 GNUnet e.V. - - 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. - - 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 - TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> - */ - -/** - * Page shown to the user to accept or ignore a tip from a merchant. - * - * @author Florian Dold <dold@taler.net> - */ - -import { useEffect, useState } from "preact/hooks"; -import { PrepareTipResult } from "@gnu-taler/taler-util"; -import { AmountView } from "../renderHtml"; -import * as wxApi from "../wxApi"; -import { JSX } from "preact/jsx-runtime"; - -interface Props { - talerTipUri?: string -} -export interface ViewProps { - prepareTipResult: PrepareTipResult; - onAccept: () => void; - onIgnore: () => void; - -} -export function View({ prepareTipResult, onAccept, onIgnore }: ViewProps) { - return <section class="main"> - <h1>GNU Taler Wallet</h1> - <article class="fade"> - {prepareTipResult.accepted ? ( - <span> - Tip from <code>{prepareTipResult.merchantBaseUrl}</code> accepted. Check - your transactions list for more details. - </span> - ) : ( - <div> - <p> - The merchant <code>{prepareTipResult.merchantBaseUrl}</code> is - offering you a tip of{" "} - <strong> - <AmountView amount={prepareTipResult.tipAmountEffective} /> - </strong>{" "} - via the exchange <code>{prepareTipResult.exchangeBaseUrl}</code> - </p> - <button onClick={onAccept}>Accept tip</button> - <button onClick={onIgnore}>Ignore</button> - </div> - )} - </article> - </section> - -} - -export function TipPage({ talerTipUri }: Props): JSX.Element { - const [updateCounter, setUpdateCounter] = useState<number>(0); - const [prepareTipResult, setPrepareTipResult] = useState< - PrepareTipResult | undefined - >(undefined); - - const [tipIgnored, setTipIgnored] = useState(false); - - useEffect(() => { - if (!talerTipUri) return; - const doFetch = async (): Promise<void> => { - const p = await wxApi.prepareTip({ talerTipUri }); - setPrepareTipResult(p); - }; - doFetch(); - }, [talerTipUri, updateCounter]); - - const doAccept = async () => { - if (!prepareTipResult) { - return; - } - await wxApi.acceptTip({ walletTipId: prepareTipResult?.walletTipId }); - setUpdateCounter(updateCounter + 1); - }; - - const doIgnore = () => { - setTipIgnored(true); - }; - - if (!talerTipUri) { - return <span>missing tip uri</span>; - } - - if (tipIgnored) { - return <span>You've ignored the tip.</span>; - } - - if (!prepareTipResult) { - return <span>Loading ...</span>; - } - - return <View prepareTipResult={prepareTipResult} - onAccept={doAccept} onIgnore={doIgnore} - /> -} diff --git a/packages/taler-wallet-webextension/src/wallet/Welcome.stories.tsx b/packages/taler-wallet-webextension/src/wallet/Welcome.stories.tsx index 4fa87a137..6579450b3 100644 --- a/packages/taler-wallet-webextension/src/wallet/Welcome.stories.tsx +++ b/packages/taler-wallet-webextension/src/wallet/Welcome.stories.tsx @@ -19,7 +19,7 @@ * @author Sebastian Javier Marchano (sebasjm) */ -import { FunctionalComponent, h } from 'preact'; +import { createExample } from '../test-utils'; import { View as TestedComponent } from './Welcome'; @@ -28,12 +28,6 @@ export default { component: TestedComponent, }; -function createExample<Props>(Component: FunctionalComponent<Props>, props: Partial<Props>) { - const r = (args: any) => <Component {...args} /> - r.args = props - return r -} - export const Normal = createExample(TestedComponent, { permissionsEnabled: true, diagnostics: { diff --git a/packages/taler-wallet-webextension/src/wallet/Welcome.tsx b/packages/taler-wallet-webextension/src/wallet/Welcome.tsx index 4c33e1c72..0738e14b6 100644 --- a/packages/taler-wallet-webextension/src/wallet/Welcome.tsx +++ b/packages/taler-wallet-webextension/src/wallet/Welcome.tsx @@ -24,7 +24,7 @@ import { JSX } from "preact/jsx-runtime"; import { Checkbox } from "../components/Checkbox"; import { useExtendedPermissions } from "../hooks/useExtendedPermissions"; import { Diagnostics } from "../components/Diagnostics"; -import { WalletPage } from "../components/styled"; +import { WalletBox } from "../components/styled"; import { useDiagnostics } from "../hooks/useDiagnostics"; import { WalletDiagnostics } from "@gnu-taler/taler-util"; @@ -44,12 +44,7 @@ export interface ViewProps { timedOut: boolean, } export function View({ permissionsEnabled, togglePermissions, diagnostics, timedOut }: ViewProps): JSX.Element { - return (<WalletPage> - <div style="border-bottom: 3px dashed #aa3939; margin-bottom: 2em;"> - <h1 style="font-family: monospace; font-size: 250%;"> - <span style="color: #aa3939;">❰</span>Taler Wallet<span style="color: #aa3939;">❱</span> - </h1> - </div> + return (<WalletBox> <h1>Browser Extension Installed!</h1> <div> <p>Thank you for installing the wallet.</p> @@ -68,6 +63,6 @@ export function View({ permissionsEnabled, togglePermissions, diagnostics, timed Learn how to top up your wallet balance » </a> </div> - </WalletPage> + </WalletBox> ); } diff --git a/packages/taler-wallet-webextension/src/wallet/Withdraw.stories.tsx b/packages/taler-wallet-webextension/src/wallet/Withdraw.stories.tsx deleted file mode 100644 index fef36b820..000000000 --- a/packages/taler-wallet-webextension/src/wallet/Withdraw.stories.tsx +++ /dev/null @@ -1,50 +0,0 @@ -/* - 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 { h } from 'preact'; -import { View, ViewProps } from './Withdraw'; - - -export default { - title: 'wallet/withdraw', - component: View, - argTypes: { - }, -}; - -export const WithoutDetails = (a: any) => <View {...a} />; -WithoutDetails.args = { -} as ViewProps - -export const CompleteWithExchange = (a: any) => <View {...a} />; -CompleteWithExchange.args = { - details: { - amount: 'USD:2', - }, - selectedExchange: 'Some exchange' -} as ViewProps - -export const CompleteWithoutExchange = (a: any) => <View {...a} />; -CompleteWithoutExchange.args = { - details: { - amount: 'USD:2', - }, -} as ViewProps diff --git a/packages/taler-wallet-webextension/src/wallet/Withdraw.tsx b/packages/taler-wallet-webextension/src/wallet/Withdraw.tsx deleted file mode 100644 index 442ee7dae..000000000 --- a/packages/taler-wallet-webextension/src/wallet/Withdraw.tsx +++ /dev/null @@ -1,178 +0,0 @@ -/* - This file is part of TALER - (C) 2015-2016 GNUnet e.V. - - 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. - - 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 - TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> - */ - -/** - * Page shown to the user to confirm creation - * of a reserve, usually requested by the bank. - * - * @author Florian Dold - */ - -import { i18n } from '@gnu-taler/taler-util' -import { renderAmount } from "../renderHtml"; - -import { useState, useEffect } from "preact/hooks"; -import { - acceptWithdrawal, - onUpdateNotification, - getWithdrawalDetailsForUri, -} from "../wxApi"; -import { WithdrawUriInfoResponse } from "@gnu-taler/taler-util"; -import { JSX } from "preact/jsx-runtime"; -import { WalletPage } from '../components/styled'; - -interface Props { - talerWithdrawUri?: string; -} - -export interface ViewProps { - talerWithdrawUri?: string; - details: WithdrawUriInfoResponse; - selectedExchange?: string; - accept: () => Promise<void>; - setCancelled: (b: boolean) => void; - setSelecting: (b: boolean) => void; -}; - -export function View({ details, selectedExchange, accept, setCancelled, setSelecting }: ViewProps) { - - return ( - <WalletPage> - <div style="border-bottom: 3px dashed #aa3939; margin-bottom: 2em;"> - <h1 style="font-family: monospace; font-size: 250%;"> - <span style="color: #aa3939;">❰</span>Taler Wallet<span style="color: #aa3939;">❱</span> - </h1> - </div> - <div class="fade"> - <div> - <h1><i18n.Translate>Digital Cash Withdrawal</i18n.Translate></h1> - <p><i18n.Translate> - You are about to withdraw{" "} - <strong>{renderAmount(details.amount)}</strong> from your bank account - into your wallet. - </i18n.Translate></p> - {selectedExchange ? ( - <p><i18n.Translate> - The exchange <strong>{selectedExchange}</strong> will be used as the - Taler payment service provider. - </i18n.Translate></p> - ) : null} - - <div> - <button - class="pure-button button-success" - disabled={!selectedExchange} - onClick={() => accept()} - > - {i18n.str`Accept fees and withdraw`} - </button> - <p> - <span - role="button" - tabIndex={0} - style={{ textDecoration: "underline", cursor: "pointer" }} - onClick={() => setSelecting(true)} - > - {i18n.str`Chose different exchange provider`} - </span> - <br /> - <span - role="button" - tabIndex={0} - style={{ textDecoration: "underline", cursor: "pointer" }} - onClick={() => setCancelled(true)} - > - {i18n.str`Cancel withdraw operation`} - </span> - </p> - </div> - </div> - </div> - </WalletPage> - ) -} - -export function WithdrawPage({ talerWithdrawUri, ...rest }: Props): JSX.Element { - const [details, setDetails] = useState<WithdrawUriInfoResponse | undefined>(undefined); - const [selectedExchange, setSelectedExchange] = useState< - string | undefined - >(undefined); - const [cancelled, setCancelled] = useState(false); - const [selecting, setSelecting] = useState(false); - const [errMsg, setErrMsg] = useState<string | undefined>(""); - const [updateCounter, setUpdateCounter] = useState(1); - const [state, setState] = useState(1) - - // setTimeout(() => { - // console.log('tick...') - // setState(s => s + 1) - // }, 1000); - - useEffect(() => { - return onUpdateNotification(() => { - console.log('updating...') - setUpdateCounter(updateCounter + 1); - }); - }, []); - - useEffect(() => { - console.log('on effect yes', talerWithdrawUri) - if (!talerWithdrawUri) return - const fetchData = async (): Promise<void> => { - console.log('que pasa') - try { - const res = await getWithdrawalDetailsForUri({ talerWithdrawUri }); - console.log('res', res) - setDetails(res); - if (res.defaultExchangeBaseUrl) { - setSelectedExchange(res.defaultExchangeBaseUrl); - } - } catch (e) { - console.error(e) - } - }; - fetchData(); - }, [selectedExchange, errMsg, selecting, talerWithdrawUri, updateCounter, state]); - - if (!talerWithdrawUri) { - return <span><i18n.Translate>missing withdraw uri</i18n.Translate></span>; - } - - const accept = async (): Promise<void> => { - if (!selectedExchange) { - throw Error("can't accept, no exchange selected"); - } - console.log("accepting exchange", selectedExchange); - const res = await acceptWithdrawal(talerWithdrawUri, selectedExchange); - console.log("accept withdrawal response", res); - if (res.confirmTransferUrl) { - document.location.href = res.confirmTransferUrl; - } - }; - - if (!details) { - return <span><i18n.Translate>Loading...</i18n.Translate></span>; - } - if (cancelled) { - return <span><i18n.Translate>Withdraw operation has been cancelled.</i18n.Translate></span>; - } - - return <View accept={accept} - setCancelled={setCancelled} setSelecting={setSelecting} - details={details} selectedExchange={selectedExchange} - /> -} - diff --git a/packages/taler-wallet-webextension/src/wallet/payback.tsx b/packages/taler-wallet-webextension/src/wallet/payback.tsx deleted file mode 100644 index 4233b1f96..000000000 --- a/packages/taler-wallet-webextension/src/wallet/payback.tsx +++ /dev/null @@ -1,31 +0,0 @@ -/* - This file is part of TALER - (C) 2017 Inria - - 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. - - 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 - TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> - */ - -import { JSX } from "preact/jsx-runtime"; - -/** - * View and edit auditors. - * - * @author Florian Dold - */ - -/** - * Imports. - */ - -export function makePaybackPage(): JSX.Element { - return <div>not implemented</div>; -} diff --git a/packages/taler-wallet-webextension/src/wallet/reset-required.tsx b/packages/taler-wallet-webextension/src/wallet/reset-required.tsx deleted file mode 100644 index 87751561c..000000000 --- a/packages/taler-wallet-webextension/src/wallet/reset-required.tsx +++ /dev/null @@ -1,97 +0,0 @@ -/* - This file is part of TALER - (C) 2017 GNUnet e.V. - - 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. - - 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 - TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> - */ - -/** - * Page to inform the user when a database reset is required. - * - * @author Florian Dold - */ - -import { Component, JSX } from "preact"; -import * as wxApi from "../wxApi"; - -interface State { - /** - * Did the user check the confirmation check box? - */ - checked: boolean; - - /** - * Do we actually need to reset the db? - */ - resetRequired: boolean; -} - -class ResetNotification extends Component<any, State> { - constructor(props: any) { - super(props); - this.state = { checked: false, resetRequired: true }; - setInterval(() => this.update(), 500); - } - async update(): Promise<void> { - const res = await wxApi.checkUpgrade(); - this.setState({ resetRequired: res.dbResetRequired }); - } - render(): JSX.Element { - if (this.state.resetRequired) { - return ( - <div> - <h1>Manual Reset Required</h1> - <p> - The wallet's database in your browser is incompatible with the{" "} - currently installed wallet. Please reset manually. - </p> - <p> - Once the database format has stabilized, we will provide automatic - upgrades. - </p> - <input - id="check" - type="checkbox" - checked={this.state.checked} - onChange={() => { - this.setState(prev => ({ checked: prev.checked })) - }} - />{" "} - <label htmlFor="check"> - I understand that I will lose all my data - </label> - <br /> - <button - class="pure-button" - disabled={!this.state.checked} - onClick={() => wxApi.resetDb()} - > - Reset - </button> - </div> - ); - } - return ( - <div> - <h1>Everything is fine!</h1>A reset is not required anymore, you can - close this page. - </div> - ); - } -} - -/** - * @deprecated to be removed - */ -export function createResetRequiredPage(): JSX.Element { - return <ResetNotification />; -} diff --git a/packages/taler-wallet-webextension/src/wallet/return-coins.tsx b/packages/taler-wallet-webextension/src/wallet/return-coins.tsx deleted file mode 100644 index 2273d1454..000000000 --- a/packages/taler-wallet-webextension/src/wallet/return-coins.tsx +++ /dev/null @@ -1,30 +0,0 @@ -/* - This file is part of TALER - (C) 2017 Inria - - 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. - - 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 - TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> - */ - -import { JSX } from "preact/jsx-runtime"; - -/** - * Return coins to own bank account. - * - * @author Florian Dold - */ - -/** - * Imports. - */ -export function createReturnCoinsPage(): JSX.Element { - return <span>Not implemented yet.</span>; -} |