adding tos information in settings and return to manual withdraw when adding an exchange
This commit is contained in:
parent
f07436aa49
commit
0bfd4523b3
@ -613,6 +613,14 @@ export const LightText = styled.div`
|
|||||||
color: gray;
|
color: gray;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
export const SuccessText = styled.div`
|
||||||
|
color: #388e3c;
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const DestructiveText = styled.div`
|
||||||
|
color: rgb(202, 60, 60);
|
||||||
|
`;
|
||||||
|
|
||||||
export const WarningText = styled.div`
|
export const WarningText = styled.div`
|
||||||
color: rgb(223, 117, 20);
|
color: rgb(223, 117, 20);
|
||||||
`;
|
`;
|
||||||
|
@ -8,6 +8,7 @@ import {
|
|||||||
LinkSuccess,
|
LinkSuccess,
|
||||||
TermsOfService,
|
TermsOfService,
|
||||||
WarningBox,
|
WarningBox,
|
||||||
|
WarningText,
|
||||||
} from "../components/styled";
|
} from "../components/styled";
|
||||||
import { TermsState } from "../utils";
|
import { TermsState } from "../utils";
|
||||||
|
|
||||||
@ -28,10 +29,27 @@ export function TermsOfServiceSection({
|
|||||||
if (!reviewing) {
|
if (!reviewing) {
|
||||||
if (!reviewed) {
|
if (!reviewed) {
|
||||||
if (!onReview) {
|
if (!onReview) {
|
||||||
return <section>Terms of service status: {terms.status}</section>;
|
return (
|
||||||
|
<Fragment>
|
||||||
|
{terms.status === "notfound" && (
|
||||||
|
<section>
|
||||||
|
<WarningText>
|
||||||
|
{i18n.str`Exchange doesn't have terms of service`}
|
||||||
|
</WarningText>
|
||||||
|
</section>
|
||||||
|
)}
|
||||||
|
</Fragment>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
|
{terms.status === "notfound" && (
|
||||||
|
<section>
|
||||||
|
<WarningText>
|
||||||
|
{i18n.str`Exchange doesn't have terms of service`}
|
||||||
|
</WarningText>
|
||||||
|
</section>
|
||||||
|
)}
|
||||||
{terms.status === "new" && (
|
{terms.status === "new" && (
|
||||||
<section>
|
<section>
|
||||||
<ButtonSuccess upperCased onClick={() => onReview(true)}>
|
<ButtonSuccess upperCased onClick={() => onReview(true)}>
|
||||||
@ -64,7 +82,6 @@ export function TermsOfServiceSection({
|
|||||||
enabled={reviewed}
|
enabled={reviewed}
|
||||||
label={i18n.str`I accept the exchange terms of service`}
|
label={i18n.str`I accept the exchange terms of service`}
|
||||||
onToggle={() => {
|
onToggle={() => {
|
||||||
console.log("asdasd", reviewed);
|
|
||||||
onAccept(!reviewed);
|
onAccept(!reviewed);
|
||||||
if (onReview) onReview(false);
|
if (onReview) onReview(false);
|
||||||
}}
|
}}
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
* @author Sebastian Javier Marchano (sebasjm)
|
* @author Sebastian Javier Marchano (sebasjm)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { amountFractionalBase } from "@gnu-taler/taler-util";
|
import { amountFractionalBase, ExchangeListItem } from "@gnu-taler/taler-util";
|
||||||
import { createExample } from "../test-utils";
|
import { createExample } from "../test-utils";
|
||||||
import { termsHtml, termsPdf, termsPlain, termsXml } from "./termsExample";
|
import { termsHtml, termsPdf, termsPlain, termsXml } from "./termsExample";
|
||||||
import { View as TestedComponent } from "./Withdraw";
|
import { View as TestedComponent } from "./Withdraw";
|
||||||
@ -32,24 +32,38 @@ export default {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const exchangeList: ExchangeListItem[] = [
|
||||||
|
{
|
||||||
|
currency: "USD",
|
||||||
|
exchangeBaseUrl: "exchange.demo.taler.net",
|
||||||
|
tos: {
|
||||||
|
currentVersion: "1",
|
||||||
|
acceptedVersion: "1",
|
||||||
|
content: "terms of service content",
|
||||||
|
contentType: "text/plain",
|
||||||
|
},
|
||||||
|
paytoUris: ["asd"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
currency: "USD",
|
||||||
|
exchangeBaseUrl: "exchange.test.taler.net",
|
||||||
|
tos: {
|
||||||
|
currentVersion: "1",
|
||||||
|
acceptedVersion: "1",
|
||||||
|
content: "terms of service content",
|
||||||
|
contentType: "text/plain",
|
||||||
|
},
|
||||||
|
paytoUris: ["asd"],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
export const NewTerms = createExample(TestedComponent, {
|
export const NewTerms = createExample(TestedComponent, {
|
||||||
knownExchanges: [
|
knownExchanges: exchangeList,
|
||||||
{
|
|
||||||
currency: "USD",
|
|
||||||
exchangeBaseUrl: "exchange.demo.taler.net",
|
|
||||||
paytoUris: ["asd"],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
currency: "USD",
|
|
||||||
exchangeBaseUrl: "exchange.test.taler.net",
|
|
||||||
paytoUris: ["asd"],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
exchangeBaseUrl: "exchange.demo.taler.net",
|
exchangeBaseUrl: "exchange.demo.taler.net",
|
||||||
withdrawalFee: {
|
withdrawalFee: {
|
||||||
currency: "USD",
|
currency: "USD",
|
||||||
fraction: 0,
|
fraction: 0,
|
||||||
value: 0,
|
value: 1,
|
||||||
},
|
},
|
||||||
amount: {
|
amount: {
|
||||||
currency: "USD",
|
currency: "USD",
|
||||||
@ -71,18 +85,7 @@ export const NewTerms = createExample(TestedComponent, {
|
|||||||
});
|
});
|
||||||
|
|
||||||
export const TermsReviewingPLAIN = createExample(TestedComponent, {
|
export const TermsReviewingPLAIN = createExample(TestedComponent, {
|
||||||
knownExchanges: [
|
knownExchanges: exchangeList,
|
||||||
{
|
|
||||||
currency: "USD",
|
|
||||||
exchangeBaseUrl: "exchange.demo.taler.net",
|
|
||||||
paytoUris: ["asd"],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
currency: "USD",
|
|
||||||
exchangeBaseUrl: "exchange.test.taler.net",
|
|
||||||
paytoUris: ["asd"],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
exchangeBaseUrl: "exchange.demo.taler.net",
|
exchangeBaseUrl: "exchange.demo.taler.net",
|
||||||
withdrawalFee: {
|
withdrawalFee: {
|
||||||
currency: "USD",
|
currency: "USD",
|
||||||
@ -110,18 +113,7 @@ export const TermsReviewingPLAIN = createExample(TestedComponent, {
|
|||||||
});
|
});
|
||||||
|
|
||||||
export const TermsReviewingHTML = createExample(TestedComponent, {
|
export const TermsReviewingHTML = createExample(TestedComponent, {
|
||||||
knownExchanges: [
|
knownExchanges: exchangeList,
|
||||||
{
|
|
||||||
currency: "USD",
|
|
||||||
exchangeBaseUrl: "exchange.demo.taler.net",
|
|
||||||
paytoUris: ["asd"],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
currency: "USD",
|
|
||||||
exchangeBaseUrl: "exchange.test.taler.net",
|
|
||||||
paytoUris: ["asd"],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
exchangeBaseUrl: "exchange.demo.taler.net",
|
exchangeBaseUrl: "exchange.demo.taler.net",
|
||||||
withdrawalFee: {
|
withdrawalFee: {
|
||||||
currency: "USD",
|
currency: "USD",
|
||||||
@ -151,18 +143,7 @@ export const TermsReviewingHTML = createExample(TestedComponent, {
|
|||||||
});
|
});
|
||||||
|
|
||||||
export const TermsReviewingPDF = createExample(TestedComponent, {
|
export const TermsReviewingPDF = createExample(TestedComponent, {
|
||||||
knownExchanges: [
|
knownExchanges: exchangeList,
|
||||||
{
|
|
||||||
currency: "USD",
|
|
||||||
exchangeBaseUrl: "exchange.demo.taler.net",
|
|
||||||
paytoUris: ["asd"],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
currency: "USD",
|
|
||||||
exchangeBaseUrl: "exchange.test.taler.net",
|
|
||||||
paytoUris: ["asd"],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
exchangeBaseUrl: "exchange.demo.taler.net",
|
exchangeBaseUrl: "exchange.demo.taler.net",
|
||||||
withdrawalFee: {
|
withdrawalFee: {
|
||||||
currency: "USD",
|
currency: "USD",
|
||||||
@ -192,18 +173,7 @@ export const TermsReviewingPDF = createExample(TestedComponent, {
|
|||||||
});
|
});
|
||||||
|
|
||||||
export const TermsReviewingXML = createExample(TestedComponent, {
|
export const TermsReviewingXML = createExample(TestedComponent, {
|
||||||
knownExchanges: [
|
knownExchanges: exchangeList,
|
||||||
{
|
|
||||||
currency: "USD",
|
|
||||||
exchangeBaseUrl: "exchange.demo.taler.net",
|
|
||||||
paytoUris: ["asd"],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
currency: "USD",
|
|
||||||
exchangeBaseUrl: "exchange.test.taler.net",
|
|
||||||
paytoUris: ["asd"],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
exchangeBaseUrl: "exchange.demo.taler.net",
|
exchangeBaseUrl: "exchange.demo.taler.net",
|
||||||
withdrawalFee: {
|
withdrawalFee: {
|
||||||
currency: "USD",
|
currency: "USD",
|
||||||
@ -231,18 +201,7 @@ export const TermsReviewingXML = createExample(TestedComponent, {
|
|||||||
});
|
});
|
||||||
|
|
||||||
export const NewTermsAccepted = createExample(TestedComponent, {
|
export const NewTermsAccepted = createExample(TestedComponent, {
|
||||||
knownExchanges: [
|
knownExchanges: exchangeList,
|
||||||
{
|
|
||||||
currency: "USD",
|
|
||||||
exchangeBaseUrl: "exchange.demo.taler.net",
|
|
||||||
paytoUris: ["asd"],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
currency: "USD",
|
|
||||||
exchangeBaseUrl: "exchange.test.taler.net",
|
|
||||||
paytoUris: ["asd"],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
exchangeBaseUrl: "exchange.demo.taler.net",
|
exchangeBaseUrl: "exchange.demo.taler.net",
|
||||||
withdrawalFee: {
|
withdrawalFee: {
|
||||||
currency: "USD",
|
currency: "USD",
|
||||||
@ -269,18 +228,7 @@ export const NewTermsAccepted = createExample(TestedComponent, {
|
|||||||
});
|
});
|
||||||
|
|
||||||
export const TermsShowAgainXML = createExample(TestedComponent, {
|
export const TermsShowAgainXML = createExample(TestedComponent, {
|
||||||
knownExchanges: [
|
knownExchanges: exchangeList,
|
||||||
{
|
|
||||||
currency: "USD",
|
|
||||||
exchangeBaseUrl: "exchange.demo.taler.net",
|
|
||||||
paytoUris: ["asd"],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
currency: "USD",
|
|
||||||
exchangeBaseUrl: "exchange.test.taler.net",
|
|
||||||
paytoUris: ["asd"],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
exchangeBaseUrl: "exchange.demo.taler.net",
|
exchangeBaseUrl: "exchange.demo.taler.net",
|
||||||
withdrawalFee: {
|
withdrawalFee: {
|
||||||
currency: "USD",
|
currency: "USD",
|
||||||
@ -309,18 +257,7 @@ export const TermsShowAgainXML = createExample(TestedComponent, {
|
|||||||
});
|
});
|
||||||
|
|
||||||
export const TermsChanged = createExample(TestedComponent, {
|
export const TermsChanged = createExample(TestedComponent, {
|
||||||
knownExchanges: [
|
knownExchanges: exchangeList,
|
||||||
{
|
|
||||||
currency: "USD",
|
|
||||||
exchangeBaseUrl: "exchange.demo.taler.net",
|
|
||||||
paytoUris: ["asd"],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
currency: "USD",
|
|
||||||
exchangeBaseUrl: "exchange.test.taler.net",
|
|
||||||
paytoUris: ["asd"],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
exchangeBaseUrl: "exchange.demo.taler.net",
|
exchangeBaseUrl: "exchange.demo.taler.net",
|
||||||
withdrawalFee: {
|
withdrawalFee: {
|
||||||
currency: "USD",
|
currency: "USD",
|
||||||
@ -347,18 +284,7 @@ export const TermsChanged = createExample(TestedComponent, {
|
|||||||
});
|
});
|
||||||
|
|
||||||
export const TermsNotFound = createExample(TestedComponent, {
|
export const TermsNotFound = createExample(TestedComponent, {
|
||||||
knownExchanges: [
|
knownExchanges: exchangeList,
|
||||||
{
|
|
||||||
currency: "USD",
|
|
||||||
exchangeBaseUrl: "exchange.demo.taler.net",
|
|
||||||
paytoUris: ["asd"],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
currency: "USD",
|
|
||||||
exchangeBaseUrl: "exchange.test.taler.net",
|
|
||||||
paytoUris: ["asd"],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
exchangeBaseUrl: "exchange.demo.taler.net",
|
exchangeBaseUrl: "exchange.demo.taler.net",
|
||||||
withdrawalFee: {
|
withdrawalFee: {
|
||||||
currency: "USD",
|
currency: "USD",
|
||||||
@ -382,18 +308,7 @@ export const TermsNotFound = createExample(TestedComponent, {
|
|||||||
});
|
});
|
||||||
|
|
||||||
export const TermsAlreadyAccepted = createExample(TestedComponent, {
|
export const TermsAlreadyAccepted = createExample(TestedComponent, {
|
||||||
knownExchanges: [
|
knownExchanges: exchangeList,
|
||||||
{
|
|
||||||
currency: "USD",
|
|
||||||
exchangeBaseUrl: "exchange.demo.taler.net",
|
|
||||||
paytoUris: ["asd"],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
currency: "USD",
|
|
||||||
exchangeBaseUrl: "exchange.test.taler.net",
|
|
||||||
paytoUris: ["asd"],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
exchangeBaseUrl: "exchange.demo.taler.net",
|
exchangeBaseUrl: "exchange.demo.taler.net",
|
||||||
withdrawalFee: {
|
withdrawalFee: {
|
||||||
currency: "USD",
|
currency: "USD",
|
||||||
@ -417,18 +332,7 @@ export const TermsAlreadyAccepted = createExample(TestedComponent, {
|
|||||||
});
|
});
|
||||||
|
|
||||||
export const WithoutFee = createExample(TestedComponent, {
|
export const WithoutFee = createExample(TestedComponent, {
|
||||||
knownExchanges: [
|
knownExchanges: exchangeList,
|
||||||
{
|
|
||||||
currency: "USD",
|
|
||||||
exchangeBaseUrl: "exchange.demo.taler.net",
|
|
||||||
paytoUris: ["asd"],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
currency: "USD",
|
|
||||||
exchangeBaseUrl: "exchange.test.taler.net",
|
|
||||||
paytoUris: ["asd"],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
exchangeBaseUrl: "exchange.demo.taler.net",
|
exchangeBaseUrl: "exchange.demo.taler.net",
|
||||||
withdrawalFee: {
|
withdrawalFee: {
|
||||||
currency: "USD",
|
currency: "USD",
|
||||||
|
@ -38,7 +38,6 @@ import {
|
|||||||
ButtonWarning,
|
ButtonWarning,
|
||||||
LinkSuccess,
|
LinkSuccess,
|
||||||
WalletAction,
|
WalletAction,
|
||||||
WarningText,
|
|
||||||
} from "../components/styled";
|
} from "../components/styled";
|
||||||
import { useAsyncAsHook } from "../hooks/useAsyncAsHook";
|
import { useAsyncAsHook } from "../hooks/useAsyncAsHook";
|
||||||
import { amountToString, buildTermsOfServiceState, TermsState } from "../utils";
|
import { amountToString, buildTermsOfServiceState, TermsState } from "../utils";
|
||||||
@ -98,17 +97,19 @@ export function View({
|
|||||||
text={amountToString(Amounts.sub(amount, withdrawalFee).amount)}
|
text={amountToString(Amounts.sub(amount, withdrawalFee).amount)}
|
||||||
kind="positive"
|
kind="positive"
|
||||||
/>
|
/>
|
||||||
<Part
|
|
||||||
title="Chosen amount"
|
|
||||||
text={amountToString(amount)}
|
|
||||||
kind="neutral"
|
|
||||||
/>
|
|
||||||
{Amounts.isNonZero(withdrawalFee) && (
|
{Amounts.isNonZero(withdrawalFee) && (
|
||||||
<Part
|
<Fragment>
|
||||||
title="Exchange fee"
|
<Part
|
||||||
text={amountToString(withdrawalFee)}
|
title="Chosen amount"
|
||||||
kind="negative"
|
text={amountToString(amount)}
|
||||||
/>
|
kind="neutral"
|
||||||
|
/>
|
||||||
|
<Part
|
||||||
|
title="Exchange fee"
|
||||||
|
text={amountToString(withdrawalFee)}
|
||||||
|
kind="negative"
|
||||||
|
/>
|
||||||
|
</Fragment>
|
||||||
)}
|
)}
|
||||||
{exchangeBaseUrl && (
|
{exchangeBaseUrl && (
|
||||||
<Part title="Exchange" text={exchangeBaseUrl} kind="neutral" big />
|
<Part title="Exchange" text={exchangeBaseUrl} kind="neutral" big />
|
||||||
@ -140,13 +141,6 @@ export function View({
|
|||||||
)}
|
)}
|
||||||
</section>
|
</section>
|
||||||
)}
|
)}
|
||||||
{terms.status === "notfound" && (
|
|
||||||
<section>
|
|
||||||
<WarningText>
|
|
||||||
{i18n.str`Exchange doesn't have terms of service`}
|
|
||||||
</WarningText>
|
|
||||||
</section>
|
|
||||||
)}
|
|
||||||
<TermsOfServiceSection
|
<TermsOfServiceSection
|
||||||
reviewed={reviewed}
|
reviewed={reviewed}
|
||||||
reviewing={reviewing}
|
reviewing={reviewing}
|
||||||
|
@ -17,19 +17,15 @@
|
|||||||
import { i18n } from "@gnu-taler/taler-util";
|
import { i18n } from "@gnu-taler/taler-util";
|
||||||
import { Fragment, h, VNode } from "preact";
|
import { Fragment, h, VNode } from "preact";
|
||||||
import { Checkbox } from "../components/Checkbox";
|
import { Checkbox } from "../components/Checkbox";
|
||||||
import { useDevContext } from "../context/devContext";
|
|
||||||
import { useExtendedPermissions } from "../hooks/useExtendedPermissions";
|
import { useExtendedPermissions } from "../hooks/useExtendedPermissions";
|
||||||
|
|
||||||
export function SettingsPage(): VNode {
|
export function SettingsPage(): VNode {
|
||||||
const [permissionsEnabled, togglePermissions] = useExtendedPermissions();
|
const [permissionsEnabled, togglePermissions] = useExtendedPermissions();
|
||||||
const { devMode, toggleDevMode } = useDevContext();
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SettingsView
|
<SettingsView
|
||||||
permissionsEnabled={permissionsEnabled}
|
permissionsEnabled={permissionsEnabled}
|
||||||
togglePermissions={togglePermissions}
|
togglePermissions={togglePermissions}
|
||||||
developerMode={devMode}
|
|
||||||
toggleDeveloperMode={toggleDevMode}
|
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -37,15 +33,11 @@ export function SettingsPage(): VNode {
|
|||||||
export interface ViewProps {
|
export interface ViewProps {
|
||||||
permissionsEnabled: boolean;
|
permissionsEnabled: boolean;
|
||||||
togglePermissions: () => void;
|
togglePermissions: () => void;
|
||||||
developerMode: boolean;
|
|
||||||
toggleDeveloperMode: () => void;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function SettingsView({
|
export function SettingsView({
|
||||||
permissionsEnabled,
|
permissionsEnabled,
|
||||||
togglePermissions,
|
togglePermissions,
|
||||||
developerMode,
|
|
||||||
toggleDeveloperMode,
|
|
||||||
}: ViewProps): VNode {
|
}: ViewProps): VNode {
|
||||||
return (
|
return (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
@ -60,14 +52,6 @@ export function SettingsView({
|
|||||||
enabled={permissionsEnabled}
|
enabled={permissionsEnabled}
|
||||||
onToggle={togglePermissions}
|
onToggle={togglePermissions}
|
||||||
/>
|
/>
|
||||||
<h2>Config</h2>
|
|
||||||
<Checkbox
|
|
||||||
label="Developer mode"
|
|
||||||
name="devMode"
|
|
||||||
description="(More options and information useful for debugging)"
|
|
||||||
enabled={developerMode}
|
|
||||||
onToggle={toggleDeveloperMode}
|
|
||||||
/>
|
|
||||||
</section>
|
</section>
|
||||||
<footer style={{ justifyContent: "space-around" }}>
|
<footer style={{ justifyContent: "space-around" }}>
|
||||||
<a
|
<a
|
||||||
|
@ -60,15 +60,19 @@ export function buildTermsOfServiceState(tos: GetExchangeTosResult): TermsState
|
|||||||
tos.content,
|
tos.content,
|
||||||
);
|
);
|
||||||
|
|
||||||
const status: TermsStatus = !content
|
const status: TermsStatus = buildTermsOfServiceStatus(tos.content, tos.acceptedEtag, tos.currentEtag);
|
||||||
? "notfound"
|
|
||||||
: !tos.acceptedEtag
|
|
||||||
? "new"
|
|
||||||
: tos.acceptedEtag !== tos.currentEtag
|
|
||||||
? "changed"
|
|
||||||
: "accepted";
|
|
||||||
|
|
||||||
return { content, status, version: tos.currentEtag }
|
return { content, status, version: tos.currentEtag }
|
||||||
|
|
||||||
|
}
|
||||||
|
export function buildTermsOfServiceStatus(content: string | undefined, acceptedVersion: string | undefined, currentVersion: string | undefined): TermsStatus {
|
||||||
|
return !content
|
||||||
|
? "notfound"
|
||||||
|
: !acceptedVersion
|
||||||
|
? "new"
|
||||||
|
: acceptedVersion !== currentVersion
|
||||||
|
? "changed"
|
||||||
|
: "accepted";
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseTermsOfServiceContent(
|
function parseTermsOfServiceContent(
|
||||||
|
@ -21,7 +21,6 @@
|
|||||||
|
|
||||||
import { AmountJson, Amounts, i18n } from "@gnu-taler/taler-util";
|
import { AmountJson, Amounts, i18n } from "@gnu-taler/taler-util";
|
||||||
import { Fragment, h, VNode } from "preact";
|
import { Fragment, h, VNode } from "preact";
|
||||||
import { route } from "preact-router";
|
|
||||||
import { useState } from "preact/hooks";
|
import { useState } from "preact/hooks";
|
||||||
import { ErrorMessage } from "../components/ErrorMessage";
|
import { ErrorMessage } from "../components/ErrorMessage";
|
||||||
import { SelectList } from "../components/SelectList";
|
import { SelectList } from "../components/SelectList";
|
||||||
@ -35,13 +34,13 @@ import {
|
|||||||
LightText,
|
LightText,
|
||||||
LinkPrimary,
|
LinkPrimary,
|
||||||
} from "../components/styled";
|
} from "../components/styled";
|
||||||
import { Pages } from "../NavigationBar";
|
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
error: string | undefined;
|
error: string | undefined;
|
||||||
initialAmount?: string;
|
initialAmount?: string;
|
||||||
exchangeList: Record<string, string>;
|
exchangeList: Record<string, string>;
|
||||||
onCreate: (exchangeBaseUrl: string, amount: AmountJson) => Promise<void>;
|
onCreate: (exchangeBaseUrl: string, amount: AmountJson) => Promise<void>;
|
||||||
|
onAddExchange: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function CreateManualWithdraw({
|
export function CreateManualWithdraw({
|
||||||
@ -49,6 +48,7 @@ export function CreateManualWithdraw({
|
|||||||
exchangeList,
|
exchangeList,
|
||||||
error,
|
error,
|
||||||
onCreate,
|
onCreate,
|
||||||
|
onAddExchange,
|
||||||
}: Props): VNode {
|
}: Props): VNode {
|
||||||
const exchangeSelectList = Object.keys(exchangeList);
|
const exchangeSelectList = Object.keys(exchangeList);
|
||||||
const currencySelectList = Object.values(exchangeList);
|
const currencySelectList = Object.values(exchangeList);
|
||||||
@ -90,7 +90,7 @@ export function CreateManualWithdraw({
|
|||||||
return (
|
return (
|
||||||
<Centered style={{ marginTop: 100 }}>
|
<Centered style={{ marginTop: 100 }}>
|
||||||
<BoldLight>No exchange configured</BoldLight>
|
<BoldLight>No exchange configured</BoldLight>
|
||||||
<ButtonSuccess onClick={() => route(Pages.exchange_add)}>
|
<ButtonSuccess onClick={onAddExchange}>
|
||||||
<i18n.Translate>Add exchange</i18n.Translate>
|
<i18n.Translate>Add exchange</i18n.Translate>
|
||||||
</ButtonSuccess>
|
</ButtonSuccess>
|
||||||
</Centered>
|
</Centered>
|
||||||
@ -130,10 +130,7 @@ export function CreateManualWithdraw({
|
|||||||
/>
|
/>
|
||||||
</Input>
|
</Input>
|
||||||
<div style={{ display: "flex", justifyContent: "space-between" }}>
|
<div style={{ display: "flex", justifyContent: "space-between" }}>
|
||||||
<LinkPrimary
|
<LinkPrimary onClick={onAddExchange} style={{ marginLeft: "auto" }}>
|
||||||
onClick={() => route(Pages.exchange_add)}
|
|
||||||
style={{ marginLeft: "auto" }}
|
|
||||||
>
|
|
||||||
<i18n.Translate>Add exchange</i18n.Translate>
|
<i18n.Translate>Add exchange</i18n.Translate>
|
||||||
</LinkPrimary>
|
</LinkPrimary>
|
||||||
</div>
|
</div>
|
||||||
|
@ -5,7 +5,6 @@ import {
|
|||||||
Button,
|
Button,
|
||||||
ButtonSuccess,
|
ButtonSuccess,
|
||||||
ButtonWarning,
|
ButtonWarning,
|
||||||
WarningBox,
|
|
||||||
} from "../components/styled/index";
|
} from "../components/styled/index";
|
||||||
import { TermsOfServiceSection } from "../cta/TermsOfServiceSection";
|
import { TermsOfServiceSection } from "../cta/TermsOfServiceSection";
|
||||||
import { useAsyncAsHook } from "../hooks/useAsyncAsHook";
|
import { useAsyncAsHook } from "../hooks/useAsyncAsHook";
|
||||||
@ -97,14 +96,6 @@ export function View({
|
|||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
{terms && terms.status === "notfound" && (
|
|
||||||
<section>
|
|
||||||
<WarningBox>
|
|
||||||
{i18n.str`Exchange doesn't have terms of service`}
|
|
||||||
</WarningBox>
|
|
||||||
</section>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{terms && (
|
{terms && (
|
||||||
<TermsOfServiceSection
|
<TermsOfServiceSection
|
||||||
reviewed={reviewed}
|
reviewed={reviewed}
|
||||||
|
@ -27,7 +27,7 @@ import { ExchangeAddConfirmPage } from "./ExchangeAddConfirm";
|
|||||||
import { ExchangeSetUrlPage } from "./ExchangeSetUrl";
|
import { ExchangeSetUrlPage } from "./ExchangeSetUrl";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
currency: string;
|
currency?: string;
|
||||||
onBack: () => void;
|
onBack: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,6 +55,12 @@ export const WithDemoAsKnownExchange = createExample(TestedComponent, {
|
|||||||
{
|
{
|
||||||
currency: "TESTKUDOS",
|
currency: "TESTKUDOS",
|
||||||
exchangeBaseUrl: "https://exchange.demo.taler.net/",
|
exchangeBaseUrl: "https://exchange.demo.taler.net/",
|
||||||
|
tos: {
|
||||||
|
currentVersion: "1",
|
||||||
|
acceptedVersion: "1",
|
||||||
|
content: "content of tos",
|
||||||
|
contentType: "text/plain",
|
||||||
|
},
|
||||||
paytoUris: [],
|
paytoUris: [],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
@ -22,11 +22,13 @@ import {
|
|||||||
AcceptManualWithdrawalResult,
|
AcceptManualWithdrawalResult,
|
||||||
AmountJson,
|
AmountJson,
|
||||||
Amounts,
|
Amounts,
|
||||||
|
NotificationType,
|
||||||
} from "@gnu-taler/taler-util";
|
} from "@gnu-taler/taler-util";
|
||||||
import { ReserveCreated } from "./ReserveCreated";
|
import { ReserveCreated } from "./ReserveCreated";
|
||||||
import { route } from "preact-router";
|
import { route } from "preact-router";
|
||||||
import { Pages } from "../NavigationBar";
|
import { Pages } from "../NavigationBar";
|
||||||
import { useAsyncAsHook } from "../hooks/useAsyncAsHook";
|
import { useAsyncAsHook } from "../hooks/useAsyncAsHook";
|
||||||
|
import { ExchangeAddPage } from "./ExchangeAddPage";
|
||||||
|
|
||||||
export function ManualWithdrawPage(): VNode {
|
export function ManualWithdrawPage(): VNode {
|
||||||
const [success, setSuccess] = useState<
|
const [success, setSuccess] = useState<
|
||||||
@ -39,7 +41,9 @@ export function ManualWithdrawPage(): VNode {
|
|||||||
>(undefined);
|
>(undefined);
|
||||||
const [error, setError] = useState<string | undefined>(undefined);
|
const [error, setError] = useState<string | undefined>(undefined);
|
||||||
|
|
||||||
const state = useAsyncAsHook(() => wxApi.listExchanges());
|
const state = useAsyncAsHook(wxApi.listExchanges, [
|
||||||
|
NotificationType.ExchangeAdded,
|
||||||
|
]);
|
||||||
|
|
||||||
async function doCreate(
|
async function doCreate(
|
||||||
exchangeBaseUrl: string,
|
exchangeBaseUrl: string,
|
||||||
@ -61,6 +65,12 @@ export function ManualWithdrawPage(): VNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const [addingExchange, setAddingExchange] = useState(false);
|
||||||
|
|
||||||
|
if (addingExchange) {
|
||||||
|
return <ExchangeAddPage onBack={() => setAddingExchange(false)} />;
|
||||||
|
}
|
||||||
|
|
||||||
if (success) {
|
if (success) {
|
||||||
return (
|
return (
|
||||||
<ReserveCreated
|
<ReserveCreated
|
||||||
@ -91,6 +101,7 @@ export function ManualWithdrawPage(): VNode {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<CreateManualWithdraw
|
<CreateManualWithdraw
|
||||||
|
onAddExchange={() => setAddingExchange(true)}
|
||||||
error={error}
|
error={error}
|
||||||
exchangeList={exchangeList}
|
exchangeList={exchangeList}
|
||||||
onCreate={doCreate}
|
onCreate={doCreate}
|
||||||
|
@ -49,6 +49,52 @@ export const WithOneExchange = createExample(TestedComponent, {
|
|||||||
{
|
{
|
||||||
currency: "USD",
|
currency: "USD",
|
||||||
exchangeBaseUrl: "http://exchange.taler",
|
exchangeBaseUrl: "http://exchange.taler",
|
||||||
|
tos: {
|
||||||
|
currentVersion: "1",
|
||||||
|
acceptedVersion: "1",
|
||||||
|
content: "content of tos",
|
||||||
|
contentType: "text/plain",
|
||||||
|
},
|
||||||
|
paytoUris: ["payto://x-taler-bank/bank.rpi.sebasjm.com/exchangeminator"],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
export const WithExchangeInDifferentState = createExample(TestedComponent, {
|
||||||
|
deviceName: "this-is-the-device-name",
|
||||||
|
permissionsEnabled: true,
|
||||||
|
setDeviceName: () => Promise.resolve(),
|
||||||
|
knownExchanges: [
|
||||||
|
{
|
||||||
|
currency: "USD",
|
||||||
|
exchangeBaseUrl: "http://exchange1.taler",
|
||||||
|
tos: {
|
||||||
|
currentVersion: "1",
|
||||||
|
acceptedVersion: "1",
|
||||||
|
content: "content of tos",
|
||||||
|
contentType: "text/plain",
|
||||||
|
},
|
||||||
|
paytoUris: ["payto://x-taler-bank/bank.rpi.sebasjm.com/exchangeminator"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
currency: "USD",
|
||||||
|
exchangeBaseUrl: "http://exchange2.taler",
|
||||||
|
tos: {
|
||||||
|
currentVersion: "2",
|
||||||
|
acceptedVersion: "1",
|
||||||
|
content: "content of tos",
|
||||||
|
contentType: "text/plain",
|
||||||
|
},
|
||||||
|
paytoUris: ["payto://x-taler-bank/bank.rpi.sebasjm.com/exchangeminator"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
currency: "USD",
|
||||||
|
exchangeBaseUrl: "http://exchange3.taler",
|
||||||
|
tos: {
|
||||||
|
currentVersion: "1",
|
||||||
|
content: "content of tos",
|
||||||
|
contentType: "text/plain",
|
||||||
|
},
|
||||||
paytoUris: ["payto://x-taler-bank/bank.rpi.sebasjm.com/exchangeminator"],
|
paytoUris: ["payto://x-taler-bank/bank.rpi.sebasjm.com/exchangeminator"],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
@ -17,14 +17,19 @@
|
|||||||
import { ExchangeListItem, i18n } from "@gnu-taler/taler-util";
|
import { ExchangeListItem, i18n } from "@gnu-taler/taler-util";
|
||||||
import { Fragment, h, VNode } from "preact";
|
import { Fragment, h, VNode } from "preact";
|
||||||
import { Checkbox } from "../components/Checkbox";
|
import { Checkbox } from "../components/Checkbox";
|
||||||
import { LinkPrimary } from "../components/styled";
|
import {
|
||||||
|
DestructiveText,
|
||||||
|
LinkPrimary,
|
||||||
|
SuccessText,
|
||||||
|
WarningText,
|
||||||
|
} from "../components/styled";
|
||||||
import { useDevContext } from "../context/devContext";
|
import { useDevContext } from "../context/devContext";
|
||||||
import { useAsyncAsHook } from "../hooks/useAsyncAsHook";
|
import { useAsyncAsHook } from "../hooks/useAsyncAsHook";
|
||||||
import { useBackupDeviceName } from "../hooks/useBackupDeviceName";
|
import { useBackupDeviceName } from "../hooks/useBackupDeviceName";
|
||||||
import { useExtendedPermissions } from "../hooks/useExtendedPermissions";
|
import { useExtendedPermissions } from "../hooks/useExtendedPermissions";
|
||||||
import { useLang } from "../hooks/useLang";
|
import { useLang } from "../hooks/useLang";
|
||||||
import { Pages } from "../NavigationBar";
|
import { Pages } from "../NavigationBar";
|
||||||
// import { strings as messages } from "../i18n/strings";
|
import { buildTermsOfServiceStatus } from "../utils";
|
||||||
import * as wxApi from "../wxApi";
|
import * as wxApi from "../wxApi";
|
||||||
|
|
||||||
export function SettingsPage(): VNode {
|
export function SettingsPage(): VNode {
|
||||||
@ -65,25 +70,8 @@ export interface ViewProps {
|
|||||||
knownExchanges: Array<ExchangeListItem>;
|
knownExchanges: Array<ExchangeListItem>;
|
||||||
}
|
}
|
||||||
|
|
||||||
// type LangsNames = {
|
|
||||||
// [P in keyof typeof messages]: string;
|
|
||||||
// };
|
|
||||||
|
|
||||||
// const names: LangsNames = {
|
|
||||||
// es: "Español [es]",
|
|
||||||
// en: "English [en]",
|
|
||||||
// fr: "Français [fr]",
|
|
||||||
// de: "Deutsch [de]",
|
|
||||||
// sv: "Svenska [sv]",
|
|
||||||
// it: "Italiano [it]",
|
|
||||||
// };
|
|
||||||
|
|
||||||
export function SettingsView({
|
export function SettingsView({
|
||||||
knownExchanges,
|
knownExchanges,
|
||||||
// lang,
|
|
||||||
// changeLang,
|
|
||||||
// deviceName,
|
|
||||||
// setDeviceName,
|
|
||||||
permissionsEnabled,
|
permissionsEnabled,
|
||||||
togglePermissions,
|
togglePermissions,
|
||||||
developerMode,
|
developerMode,
|
||||||
@ -92,30 +80,6 @@ export function SettingsView({
|
|||||||
return (
|
return (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
<section>
|
<section>
|
||||||
<h2>
|
|
||||||
<i18n.Translate>Known exchanges</i18n.Translate>
|
|
||||||
</h2>
|
|
||||||
{!knownExchanges || !knownExchanges.length ? (
|
|
||||||
<div>No exchange yet!</div>
|
|
||||||
) : (
|
|
||||||
<Fragment>
|
|
||||||
<table>
|
|
||||||
{knownExchanges.map((e, idx) => (
|
|
||||||
<tr key={idx}>
|
|
||||||
<td>{e.currency}</td>
|
|
||||||
<td>
|
|
||||||
<a href={e.exchangeBaseUrl}>{e.exchangeBaseUrl}</a>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
))}
|
|
||||||
</table>
|
|
||||||
</Fragment>
|
|
||||||
)}
|
|
||||||
<div style={{ display: "flex", justifyContent: "space-between" }}>
|
|
||||||
<div />
|
|
||||||
<LinkPrimary href={Pages.exchange_add}>Add an exchange</LinkPrimary>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<h2>
|
<h2>
|
||||||
<i18n.Translate>Permissions</i18n.Translate>
|
<i18n.Translate>Permissions</i18n.Translate>
|
||||||
</h2>
|
</h2>
|
||||||
@ -126,6 +90,61 @@ export function SettingsView({
|
|||||||
enabled={permissionsEnabled}
|
enabled={permissionsEnabled}
|
||||||
onToggle={togglePermissions}
|
onToggle={togglePermissions}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<h2>
|
||||||
|
<i18n.Translate>Known exchanges</i18n.Translate>
|
||||||
|
</h2>
|
||||||
|
{!knownExchanges || !knownExchanges.length ? (
|
||||||
|
<div>No exchange yet!</div>
|
||||||
|
) : (
|
||||||
|
<Fragment>
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>currency</th>
|
||||||
|
<th>url</th>
|
||||||
|
<th>term of service</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{knownExchanges.map((e, idx) => {
|
||||||
|
function Status(): VNode {
|
||||||
|
const status = buildTermsOfServiceStatus(
|
||||||
|
e.tos.content,
|
||||||
|
e.tos.acceptedVersion,
|
||||||
|
e.tos.currentVersion,
|
||||||
|
);
|
||||||
|
switch (status) {
|
||||||
|
case "accepted":
|
||||||
|
return <SuccessText>ok</SuccessText>;
|
||||||
|
case "changed":
|
||||||
|
return <WarningText>changed!</WarningText>;
|
||||||
|
case "new":
|
||||||
|
case "notfound":
|
||||||
|
return <DestructiveText>not accepted</DestructiveText>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<tr key={idx}>
|
||||||
|
<td>{e.currency}</td>
|
||||||
|
<td>
|
||||||
|
<a href={e.exchangeBaseUrl}>{e.exchangeBaseUrl}</a>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<Status />
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</Fragment>
|
||||||
|
)}
|
||||||
|
<div style={{ display: "flex", justifyContent: "space-between" }}>
|
||||||
|
<div />
|
||||||
|
<LinkPrimary href={Pages.exchange_add}>Add an exchange</LinkPrimary>
|
||||||
|
</div>
|
||||||
|
|
||||||
<h2>Config</h2>
|
<h2>Config</h2>
|
||||||
<Checkbox
|
<Checkbox
|
||||||
label="Developer mode"
|
label="Developer mode"
|
||||||
|
@ -350,11 +350,13 @@ export function acceptTip(req: AcceptTipRequest): Promise<void> {
|
|||||||
return callBackend("acceptTip", req);
|
return callBackend("acceptTip", req);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function onUpdateNotification(messageType: Array<NotificationType>, doCallback: () => void): () => void {
|
export function onUpdateNotification(messageTypes: Array<NotificationType>, doCallback: () => void): () => void {
|
||||||
// eslint-disable-next-line no-undef
|
// eslint-disable-next-line no-undef
|
||||||
const port = chrome.runtime.connect({ name: "notifications" });
|
const port = chrome.runtime.connect({ name: "notifications" });
|
||||||
const listener = (message: MessageFromBackend): void => {
|
const listener = (message: MessageFromBackend): void => {
|
||||||
if (messageType.includes(message.type)) {
|
const shouldNotify = messageTypes.includes(message.type)
|
||||||
|
console.log("Notification arrived, should notify?", shouldNotify, message.type, messageTypes)
|
||||||
|
if (shouldNotify) {
|
||||||
doCallback();
|
doCallback();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user