diff --git a/public/locales/en.json b/public/locales/en.json index 3c277f5..70ba1a6 100644 --- a/public/locales/en.json +++ b/public/locales/en.json @@ -377,6 +377,9 @@ "walletOverviewNamesCountEmpty": "No names", "walletOverviewSeeMore": "See all {{count, number}}...", "walletOverviewAddWallets": "Add wallets...", + "stakeInfoCardTitle": "Total staked", + "stakeInfoAPY": "APY: <1>{{APY}}%", + "stakeInfoEmptyDescription": "No current stakers, go to Staking and be the first!", "transactionsCardTitle": "Transactions", "transactionsError": "There was an error fetching your transactions. See the console for details.", diff --git a/src/pages/dashboard/BlockValueCard.tsx b/src/pages/dashboard/BlockValueCard.tsx index e8bd432..62dbb27 100644 --- a/src/pages/dashboard/BlockValueCard.tsx +++ b/src/pages/dashboard/BlockValueCard.tsx @@ -19,10 +19,10 @@ const work = useSelector((s: RootState) => s.node.detailedWork); const hasNames = (work?.unpaid || 0) > 0; const soonestDecrease = Math.min(work ? work.decrease.blocks : 0, work ? work.decreasePenalty.blocks : 0); - const soonestDecreaseAmount = work ? (work.decrease.blocks < work.decreasePenalty.blocks ? work.decrease.value + const soonestDecreaseAmount = work ? (work.decrease.blocks < work.decreasePenalty.blocks ? work.decrease.value : (work.decrease.blocks > work.decreasePenalty.blocks ? work.decreasePenalty.value - : work.decrease.value + work.decreasePenalty.value ) ) - : 0; + : work.decrease.value + work.decreasePenalty.value)) + : 0; const resetBlock = Math.max(work ? work.decrease.reset : 0, work ? work.decreasePenalty.reset : 0); return diff --git a/src/pages/dashboard/DashboardPage.less b/src/pages/dashboard/DashboardPage.less index 2e883ed..e0fd5f2 100644 --- a/src/pages/dashboard/DashboardPage.less +++ b/src/pages/dashboard/DashboardPage.less @@ -66,6 +66,28 @@ } } + .dashboard-card-stake-info { + .dashboard-stake-info-main.tenebra-value { + font-size: @heading-4-size; + } + + .dashboard-stake-info-next-decrease { + margin: @margin-sm 0; + } + + .dashboard-stake-info-summary { + color: @kw-purple; + margin-top: @margin-sm; + font-size: @font-size-lg; + } + + .dashboard-stake-info-empty-description { + color: @text-color-secondary; + font-size: 90%; + margin-top: @margin-sm; + } + } + .dashboard-card-block-difficulty { .ant-card-body { height: 100%; diff --git a/src/pages/dashboard/DashboardPage.tsx b/src/pages/dashboard/DashboardPage.tsx index a0b73e2..8244897 100644 --- a/src/pages/dashboard/DashboardPage.tsx +++ b/src/pages/dashboard/DashboardPage.tsx @@ -17,6 +17,8 @@ import { SyncDetailedWork } from "@global/ws/SyncDetailedWork"; import "./DashboardPage.less"; +import React from "react"; +import { StakeInfoCard } from "./StakeInfoCard"; export function DashboardPage(): JSX.Element { @@ -35,8 +37,9 @@ + + - diff --git a/src/pages/dashboard/StakeInfoCard.tsx b/src/pages/dashboard/StakeInfoCard.tsx new file mode 100644 index 0000000..002b997 --- /dev/null +++ b/src/pages/dashboard/StakeInfoCard.tsx @@ -0,0 +1,54 @@ +// Copyright (c) 2020-2021 Drew Lemmy +// This file is part of TenebraWeb 2 under AGPL-3.0. +// Full details: https://github.com/tmpim/TenebraWeb2/blob/master/LICENSE.txt +import { Card, Skeleton } from "antd"; + +import { useSelector } from "react-redux"; +import { RootState } from "@store"; + +import { useTranslation, Trans} from "react-i18next"; + +import { TenebraValue } from "@comp/tenebra/TenebraValue"; + +export function StakeInfoCard(): JSX.Element { + const { t } = useTranslation(); + + const work = useSelector((s: RootState) => s.node.detailedWork); + const secondsPerBlock = useSelector((s: RootState) => s.node.constants.seconds_per_block); + const blocksPerYear = (60 * 60 * 24 * 365.24) / secondsPerBlock; + const totalStaked = work?.total_staked || 0; + const APY = ((blocksPerYear / totalStaked) * 100).toFixed(2); + + return + + {work && <> + {/* Main block value */} + 0} + className="dashboard-stake-info-main" + /> + + {totalStaked > 0 && <> + {/* Base value + names */} +
+
+ + APY {{APY}}% + + {/*{t("dashboard.stakeInfoAPY", { apy: APY })}*/} +
+
+ } + + {/* Filler explanation when there are no unpaid names */} + {totalStaked <= 0 && ( +
+ {t("dashboard.stakeInfoEmptyDescription")} +
+ )} + } +
+
; +} diff --git a/src/style/theme.less b/src/style/theme.less index 9ab8fd4..96809d6 100644 --- a/src/style/theme.less +++ b/src/style/theme.less @@ -39,6 +39,7 @@ @font-size-base: 16px; @font-size-sm: 13px; +@font-size-lg: 20px; @border-color-base: #535c80; @border-color-split: #404962; diff --git a/src/tenebra/api/types.ts b/src/tenebra/api/types.ts index 19979b2..41cce2a 100644 --- a/src/tenebra/api/types.ts +++ b/src/tenebra/api/types.ts @@ -59,6 +59,7 @@ base_value: number; block_value: number; + total_staked: number; decrease: { value: number;