improve staking dashboard

This commit is contained in:
João Geonizeli
2021-09-06 21:26:27 -03:00
parent 361048ab67
commit dcdb611b53
6 changed files with 55 additions and 83 deletions

View File

@@ -21,7 +21,7 @@ const MenuItems: MenuItem[] = [
path: "/dashboard", path: "/dashboard",
}, },
{ {
label: "Histórico de Investimentos", label: "Pedidos de Investimentos",
path: "/orders/stake", path: "/orders/stake",
}, },
{ {

View File

@@ -2,36 +2,35 @@ import type { FC } from "react";
import React from "react"; import React from "react";
import useSWR from "swr"; import useSWR from "swr";
import { Spinner } from "../../components";
import { useCurrentUser } from "../../contexts/UserProvider"; import { useCurrentUser } from "../../contexts/UserProvider";
import type { import { Messages } from "../../messages";
Vault as VaultType, import type { YieldwatchResponse } from "../../types/yieldwatch";
YieldwatchResponse, import { VaultCard } from "./Vault";
} from "../../types/yieldwatch";
import { Vault } from "./Vault";
const exampleVault: Partial<VaultType> = {
chainId: 1,
name: "Cake-Cake Staking",
depositedTokens: 0,
totalRewards: 0,
};
export const Dashbaord: FC = () => { export const Dashbaord: FC = () => {
const { user } = useCurrentUser(); const { user } = useCurrentUser();
const { data } = useSWR<YieldwatchResponse>( const { data } = useSWR<YieldwatchResponse>(
`https://www.yieldwatch.net/api/all/${user?.walletAddress}?platforms=pancake` `https://www.yieldwatch.net/api/all/${user?.walletAddress}?platforms=pancake`
); );
const isLoading = !data; const isLoading = !data;
const vaults = data?.result?.PancakeSwap?.staking?.vaults;
const vaults = data?.result?.PancakeSwap?.staking?.vaults ?? [exampleVault]; if (isLoading)
return (
<div className="w-full grid place-items-center">
<Spinner />
</div>
);
if (!vaults?.length) return <Messages.NoHistory historyName="Staking" />;
return ( return (
<div className="grid place-items-center w-full h-5 mt-32"> <div className="grid place-items-center w-full h-full mt-20">
<div className="max-w-3xl grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4"> <div className="max-w-3xl grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
{vaults?.map((vault) => ( {vaults?.map((vault) => (
<Vault key={vault.name} isLoading={isLoading} vault={vault} /> <VaultCard key={vault.name} vault={vault} />
))} ))}
</div> </div>
</div> </div>

View File

@@ -6,19 +6,19 @@ import { useLazyLoadQuery } from "react-relay";
import { graphql } from "babel-plugin-relay/macro"; import { graphql } from "babel-plugin-relay/macro";
import BigNumber from "bignumber.js"; import BigNumber from "bignumber.js";
import type { Vault as VaultType } from "../../../types/yieldwatch"; import type { Vault } from "../../../types/yieldwatch";
import { RemoveStakeModal } from "./RemoveStakeModal"; import { RemoveStakeModal } from "./RemoveStakeModal";
import type { VaultQuery } from "./__generated__/VaultQuery.graphql"; import { formatTokenBalance } from "../../../utils/tokenBalance";
import type { VaultCardQuery } from "./__generated__/VaultCardQuery.graphql";
type VaultProps = { type VaultProps = {
vault: Partial<VaultType>; vault: Vault;
isLoading: boolean;
}; };
export const Vault: FC<VaultProps> = ({ vault, isLoading }) => { export const VaultCard: FC<VaultProps> = ({ vault }) => {
const { stakeOrders } = useLazyLoadQuery<VaultQuery>( const { stakeOrders } = useLazyLoadQuery<VaultCardQuery>(
graphql` graphql`
query VaultQuery( query VaultCardQuery(
$status: ProcessStatus! $status: ProcessStatus!
$poolName: String! $poolName: String!
$amount: Float! $amount: Float!
@@ -40,7 +40,7 @@ export const Vault: FC<VaultProps> = ({ vault, isLoading }) => {
`, `,
{ {
status: "PROCESSING", status: "PROCESSING",
poolName: vault.name ?? "", poolName: vault.name,
amount: 0, amount: 0,
} }
); );
@@ -56,8 +56,7 @@ export const Vault: FC<VaultProps> = ({ vault, isLoading }) => {
return BigNumber.sum(acc, current.node.amount); return BigNumber.sum(acc, current.node.amount);
}, new BigNumber(0)); }, new BigNumber(0));
const totalDepositedAndRewarded = const totalDepositedAndRewarded = vault.depositedTokens + vault.totalRewards;
(vault.depositedTokens ?? 0) + (vault.totalRewards ?? 0);
let totalStaked = BigNumber.sum( let totalStaked = BigNumber.sum(
alreadyOnUnstakeOrder, alreadyOnUnstakeOrder,
@@ -67,13 +66,8 @@ export const Vault: FC<VaultProps> = ({ vault, isLoading }) => {
totalStaked = totalStaked.isLessThan(0.0001) ? new BigNumber(0) : totalStaked; totalStaked = totalStaked.isLessThan(0.0001) ? new BigNumber(0) : totalStaked;
const totalStakedFixed = totalStaked.toFixed(4); const totalStakedFixed = totalStaked.toFixed(4);
const totalDeposited = ( const totalDeposited = formatTokenBalance(vault.depositedTokens);
totalStaked.isEqualTo(0) ? 0 : vault.depositedTokens const totalRewarded = formatTokenBalance(vault.totalRewards);
)?.toFixed(4);
const totalRewarded = (
totalStaked.isEqualTo(0) ? 0 : vault.totalRewards
)?.toFixed(4);
return ( return (
<> <>
@@ -83,53 +77,29 @@ export const Vault: FC<VaultProps> = ({ vault, isLoading }) => {
stakedCake={totalStakedFixed} stakedCake={totalStakedFixed}
poolName={vault.name} poolName={vault.name}
/> />
<div className="shadow-lg px-4 py-6 w-full bg-white dark:bg-gray-800 rounded-lg"> <div className="shadow-lg px-4 py-6 mb-4 w-full bg-white rounded-lg">
<div className="flex justify-between"> <div className="flex justify-between">
<p className="text-sm w-max text-gray-700 dark:text-white font-semibold border-b border-gray-200"> <p className="text-sm w-max text-gray-700 font-semibold border-b border-gray-200">
{vault.name} {vault.name}
</p> </p>
<button onClick={handleRemoveStakeModal} aria-label="Remover Stake"> <button onClick={handleRemoveStakeModal} aria-label="Remover Stake">
<XCircleIcon className="h-5 w-5 text-red-500" /> <XCircleIcon className="h-5 w-5 text-red-500" />
</button> </button>
</div> </div>
<div className="flex items-end space-x-2 my-6">
<p <div className="mt-6">
className={cx(
"text-5xl text-black dark:text-white font-bold",
isLoading
? "w-36 h-10 inline-block animate-pulse bg-gray-300 rounded"
: ""
)}
>
{!isLoading && totalStakedFixed}
</p>
</div>
<div className="dark:text-white">
<div className="flex items-center pb-2 mb-2 text-sm space-x-12 md:space-x-24 justify-between border-b border-gray-200"> <div className="flex items-center pb-2 mb-2 text-sm space-x-12 md:space-x-24 justify-between border-b border-gray-200">
<p>Depositado</p> <p>Depositado</p>
<div <div className={cx("flex items-end text-xs")}>{totalDeposited}</div>
className={cx( </div>
"flex items-end text-xs", <div className="flex items-center pb-2 mb-2 text-sm space-x-12 md:space-x-24 justify-between border-b border-gray-200">
isLoading <p>Ganho</p>
? "w-10 h-4 inline-block animate-pulse bg-gray-300 rounded" <div className={cx("flex items-end text-xs")}>{totalRewarded}</div>
: ""
)}
>
{!isLoading && totalDeposited}
</div>
</div> </div>
<div className="flex items-center text-sm space-x-12 md:space-x-24 justify-between"> <div className="flex items-center text-sm space-x-12 md:space-x-24 justify-between">
<p>Ganho</p> <p>Rendimento</p>
<div <div className={cx("flex items-end text-xs whitespace-nowrap")}>
className={cx( {`${(vault.poolInfo.apr * 100).toFixed(2)} %`}
"flex items-end text-xs",
isLoading
? "w-10 h-4 inline-block animate-pulse bg-gray-300 rounded"
: ""
)}
>
{!isLoading && totalRewarded}
</div> </div>
</div> </div>
</div> </div>

View File

@@ -4,12 +4,12 @@
import { ConcreteRequest } from "relay-runtime"; import { ConcreteRequest } from "relay-runtime";
export type ProcessStatus = "CANCELED" | "COMPLETED" | "PROCESSING" | "%future added value"; export type ProcessStatus = "CANCELED" | "COMPLETED" | "PROCESSING" | "%future added value";
export type VaultQueryVariables = { export type VaultCardQueryVariables = {
status: ProcessStatus; status: ProcessStatus;
poolName: string; poolName: string;
amount: number; amount: number;
}; };
export type VaultQueryResponse = { export type VaultCardQueryResponse = {
readonly stakeOrders: { readonly stakeOrders: {
readonly edges: ReadonlyArray<{ readonly edges: ReadonlyArray<{
readonly node: { readonly node: {
@@ -18,15 +18,15 @@ export type VaultQueryResponse = {
}>; }>;
}; };
}; };
export type VaultQuery = { export type VaultCardQuery = {
readonly response: VaultQueryResponse; readonly response: VaultCardQueryResponse;
readonly variables: VaultQueryVariables; readonly variables: VaultCardQueryVariables;
}; };
/* /*
query VaultQuery( query VaultCardQuery(
$status: ProcessStatus! $status: ProcessStatus!
$poolName: String! $poolName: String!
$amount: Float! $amount: Float!
@@ -115,7 +115,7 @@ return {
], ],
"kind": "Fragment", "kind": "Fragment",
"metadata": null, "metadata": null,
"name": "VaultQuery", "name": "VaultCardQuery",
"selections": [ "selections": [
{ {
"alias": null, "alias": null,
@@ -163,7 +163,7 @@ return {
(v0/*: any*/) (v0/*: any*/)
], ],
"kind": "Operation", "kind": "Operation",
"name": "VaultQuery", "name": "VaultCardQuery",
"selections": [ "selections": [
{ {
"alias": null, "alias": null,
@@ -209,14 +209,14 @@ return {
] ]
}, },
"params": { "params": {
"cacheID": "6565697f7f43e955abee8a8a1eeb8e9b", "cacheID": "1bbb395dae29c85a1be62eb32995458d",
"id": null, "id": null,
"metadata": {}, "metadata": {},
"name": "VaultQuery", "name": "VaultCardQuery",
"operationKind": "query", "operationKind": "query",
"text": "query VaultQuery(\n $status: ProcessStatus!\n $poolName: String!\n $amount: Float!\n) {\n stakeOrders(filter: {status: [$status], poolName: {eq: $poolName}, amount: {lt: $amount}}) {\n edges {\n node {\n amount\n id\n }\n }\n }\n}\n" "text": "query VaultCardQuery(\n $status: ProcessStatus!\n $poolName: String!\n $amount: Float!\n) {\n stakeOrders(filter: {status: [$status], poolName: {eq: $poolName}, amount: {lt: $amount}}) {\n edges {\n node {\n amount\n id\n }\n }\n }\n}\n"
} }
}; };
})(); })();
(node as any).hash = 'e5dced4589579717b408bc2f555b98ab'; (node as any).hash = 'dbf07265190b32d9f6f4e66c5e3d851f';
export default node; export default node;

View File

@@ -1 +1 @@
export * from "./Vault"; export * from "./VaultCard";

View File

@@ -0,0 +1,3 @@
export const formatTokenBalance = (value: number) => {
return Math.round(value * 10000) / 10000;
};