diff --git a/public/locales/en.json b/public/locales/en.json index 9c33f13..c89e29a 100644 --- a/public/locales/en.json +++ b/public/locales/en.json @@ -757,6 +757,9 @@ }, "sendTransaction": { + "title": "Send transaction", + "siteTitle": "Send transaction", + "modalTitle": "Send transaction", "modalSubmit": "Send", @@ -792,6 +795,7 @@ "payLargeConfirmHalf": "Are you sure you want to send <1 />? This is over half your balance!", "payLargeConfirmAll": "Are you sure you want to send <1 />? This is your entire balance!", + "errorNotificationTitle": "Transaction failed", "successNotificationTitle": "Transaction successful", "successNotificationContent": "You sent <1 /> from <3 /> to <5 />.", "successNotificationButton": "View transaction" diff --git a/src/global/AppRouter.tsx b/src/global/AppRouter.tsx index d55ab4b..bce97db 100644 --- a/src/global/AppRouter.tsx +++ b/src/global/AppRouter.tsx @@ -6,6 +6,8 @@ import { DashboardPage } from "@pages/dashboard/DashboardPage"; import { WalletsPage } from "@pages/wallets/WalletsPage"; +import { SendTransactionPage } from "@pages/transactions/send/SendTransactionPage"; + import { AddressPage } from "@pages/addresses/AddressPage"; import { BlocksPage } from "@pages/blocks/BlocksPage"; import { BlockPage } from "@pages/blocks/BlockPage"; @@ -39,6 +41,9 @@ { path: "/me/names", name: "myNames", component: }, + // Payments + { path: "/send", name: "sendTransaction", component: }, + // Network explorer { path: "/network/addresses/:address", name: "address", component: }, { path: "/network/addresses/:address/transactions", name: "addressTransactions", diff --git a/src/layout/nav/AppHeader.tsx b/src/layout/nav/AppHeader.tsx index 1b21729..eb0ec3c 100644 --- a/src/layout/nav/AppHeader.tsx +++ b/src/layout/nav/AppHeader.tsx @@ -41,7 +41,11 @@ {/* Send and receive buttons */} {bps.md && - }>{t("nav.send")} + }> + + {t("nav.send")} + + }>{t("nav.request")} } diff --git a/src/pages/transactions/send/SendTransactionModal.tsx b/src/pages/transactions/send/SendTransactionModal.tsx index 562da27..614547f 100644 --- a/src/pages/transactions/send/SendTransactionModal.tsx +++ b/src/pages/transactions/send/SendTransactionModal.tsx @@ -1,22 +1,19 @@ // Copyright (c) 2020-2021 Drew Lemmy // This file is part of KristWeb 2 under GPL-3.0. // Full details: https://github.com/tmpim/KristWeb2/blob/master/LICENSE.txt -import React, { Dispatch, SetStateAction } from "react"; -import { Modal, Button, notification } from "antd"; +import { Dispatch, SetStateAction } from "react"; +import { Modal, notification } from "antd"; -import { useTranslation, Trans } from "react-i18next"; +import { useTranslation } from "react-i18next"; import { translateError } from "@utils/i18n"; -import { Link } from "react-router-dom"; - import { useWallets, Wallet } from "@wallets"; import { NoWalletsModal } from "@comp/results/NoWalletsResult"; import { KristTransaction } from "@api/types"; -import { KristValue } from "@comp/krist/KristValue"; -import { ContextualAddress } from "@comp/addresses/ContextualAddress"; import { useTransactionForm } from "./SendTransactionForm"; +import { NotifSuccessContents, NotifSuccessButton } from "./Success"; interface Props { visible: boolean; @@ -56,7 +53,7 @@ // Display errors as notifications in the modal onError: err => notification.error({ - message: t("error"), + message: t("sendTransaction.errorNotificationTitle"), description: translateError(t, err, "sendTransaction.errorUnknown") }) }); @@ -102,35 +99,3 @@ {contextHolder} ; } - -function NotifSuccessContents({ tx }: { tx: KristTransaction }): JSX.Element { - const { t } = useTranslation(); - - return - You sent - - from - - to - - ; -} - -function NotifSuccessButton({ tx }: { tx: KristTransaction }): JSX.Element { - const { t } = useTranslation(); - - return - - ; -} diff --git a/src/pages/transactions/send/SendTransactionPage.less b/src/pages/transactions/send/SendTransactionPage.less new file mode 100644 index 0000000..05ef43d --- /dev/null +++ b/src/pages/transactions/send/SendTransactionPage.less @@ -0,0 +1,29 @@ +// Copyright (c) 2020-2021 Drew Lemmy +// This file is part of KristWeb 2 under GPL-3.0. +// Full details: https://github.com/tmpim/KristWeb2/blob/master/LICENSE.txt +@import (reference) "../../../App.less"; + +.send-transaction-page { + .send-transaction-container { + //display: flex; + flex-direction: column; + + margin: 0 auto; + width: 100%; + max-width: 768px; + + background: @kw-light; + border-radius: @kw-big-card-border-radius; + + padding: @padding-lg; + + .send-transaction-submit { + float: right; + } + } + + .send-transaction-alert { + max-width: 768px; + margin: 0 auto @margin-md auto; + } +} diff --git a/src/pages/transactions/send/SendTransactionPage.tsx b/src/pages/transactions/send/SendTransactionPage.tsx new file mode 100644 index 0000000..adeedd9 --- /dev/null +++ b/src/pages/transactions/send/SendTransactionPage.tsx @@ -0,0 +1,99 @@ +// Copyright (c) 2020-2021 Drew Lemmy +// This file is part of KristWeb 2 under GPL-3.0. +// Full details: https://github.com/tmpim/KristWeb2/blob/master/LICENSE.txt +import { useState } from "react"; +import { Button, Alert } from "antd"; +import { SendOutlined } from "@ant-design/icons"; + +import { useTranslation } from "react-i18next"; +import { translateError } from "@utils/i18n"; + +import { PageLayout } from "@layout/PageLayout"; + +import { useWallets } from "@wallets"; +import { NoWalletsResult } from "@comp/results/NoWalletsResult"; + +import { KristTransaction } from "@api/types"; + +import { useTransactionForm } from "./SendTransactionForm"; +import { NotifSuccessContents, NotifSuccessButton } from "./Success"; + +import "./SendTransactionPage.less"; + +export function SendTransactionPage(): JSX.Element { + // TODO: use this page for pre-filled transaction links? + const { t } = useTranslation(); + + // The success or error alert + const [alert, setAlert] = useState(null); + + // Create the transaction form + const { isSubmitting, triggerSubmit, txForm } = useTransactionForm({ + onSuccess: tx => setAlert(), + onError: err => setAlert() + }); + + // Don't show the form if there are no wallets. + const { addressList } = useWallets(); + const hasWallets = addressList?.length > 0; + + return + {hasWallets + ? <> + {/* Show the success/error alert if available */} + {alert} + +
+ {txForm} + + {/* Send submit button */} + + + {/* Clearfix for submit button floated right */} +
+
+ + : } + ; +} + +function AlertSuccess({ tx }: { tx: KristTransaction }): JSX.Element { + const { t } = useTranslation(); + + return } + action={} + />; +} + +function AlertError({ err }: { err: Error }): JSX.Element { + const { t } = useTranslation(); + + return ; +} diff --git a/src/pages/transactions/send/Success.tsx b/src/pages/transactions/send/Success.tsx new file mode 100644 index 0000000..fde162b --- /dev/null +++ b/src/pages/transactions/send/Success.tsx @@ -0,0 +1,44 @@ +// Copyright (c) 2020-2021 Drew Lemmy +// This file is part of KristWeb 2 under GPL-3.0. +// Full details: https://github.com/tmpim/KristWeb2/blob/master/LICENSE.txt +import { Button } from "antd"; + +import { useTranslation, Trans } from "react-i18next"; + +import { Link } from "react-router-dom"; + +import { KristTransaction } from "@api/types"; +import { KristValue } from "@comp/krist/KristValue"; +import { ContextualAddress } from "@comp/addresses/ContextualAddress"; + +export function NotifSuccessContents({ tx }: { tx: KristTransaction }): JSX.Element { + const { t } = useTranslation(); + + return + You sent + + from + + to + + ; +} + +export function NotifSuccessButton({ tx }: { tx: KristTransaction }): JSX.Element { + const { t } = useTranslation(); + + return + + ; +}