add unstake dialog do stake report
This commit is contained in:
@@ -1,12 +1,15 @@
|
|||||||
import type { FC } from "react";
|
import type { FC } from "react";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import useSWR from "swr";
|
import useSWR from "swr";
|
||||||
import cx from "classnames";
|
|
||||||
|
|
||||||
import { useCurrentUser } from "../../contexts/UserProvider";
|
import { useCurrentUser } from "../../contexts/UserProvider";
|
||||||
import type { Vault, YieldwatchResponse } from "../../types/yieldwatch";
|
import type {
|
||||||
|
Vault as VaultType,
|
||||||
|
YieldwatchResponse,
|
||||||
|
} from "../../types/yieldwatch";
|
||||||
|
import { Vault } from "./Vault";
|
||||||
|
|
||||||
const exampleVault: Partial<Vault> = {
|
const exampleVault: Partial<VaultType> = {
|
||||||
chainId: 1,
|
chainId: 1,
|
||||||
name: "Cake-Cake Staking",
|
name: "Cake-Cake Staking",
|
||||||
depositedTokens: 0,
|
depositedTokens: 0,
|
||||||
@@ -28,57 +31,7 @@ export const Dashbaord: FC = () => {
|
|||||||
<div className="grid place-items-center w-full h-5 mt-32">
|
<div className="grid place-items-center w-full h-5 mt-32">
|
||||||
<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) => (
|
||||||
<div
|
<Vault key={vault.name} isLoading={isLoading} vault={vault} />
|
||||||
key={vault.chainId}
|
|
||||||
className="shadow-lg px-4 py-6 w-full bg-white dark:bg-gray-800 rounded-lg"
|
|
||||||
>
|
|
||||||
<p className="text-sm w-max text-gray-700 dark:text-white font-semibold border-b border-gray-200">
|
|
||||||
{vault.name}
|
|
||||||
</p>
|
|
||||||
<div className="flex items-end space-x-2 my-6">
|
|
||||||
<p
|
|
||||||
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 &&
|
|
||||||
(
|
|
||||||
(vault.depositedTokens ?? 0) + (vault.totalRewards ?? 0)
|
|
||||||
).toFixed(4)}
|
|
||||||
</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">
|
|
||||||
<p>Depositado</p>
|
|
||||||
<div
|
|
||||||
className={cx(
|
|
||||||
"flex items-end text-xs",
|
|
||||||
isLoading
|
|
||||||
? "w-10 h-4 inline-block animate-pulse bg-gray-300 rounded"
|
|
||||||
: ""
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
{!isLoading && vault.depositedTokens?.toFixed(4)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="flex items-center text-sm space-x-12 md:space-x-24 justify-between">
|
|
||||||
<p>Ganho</p>
|
|
||||||
<div
|
|
||||||
className={cx(
|
|
||||||
"flex items-end text-xs",
|
|
||||||
isLoading
|
|
||||||
? "w-10 h-4 inline-block animate-pulse bg-gray-300 rounded"
|
|
||||||
: ""
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
{!isLoading && vault.totalRewards?.toFixed(4)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -0,0 +1,94 @@
|
|||||||
|
import BigNumber from "bignumber.js";
|
||||||
|
import type { ChangeEvent, FC } from "react";
|
||||||
|
import React, { useState } from "react";
|
||||||
|
import cx from "classnames";
|
||||||
|
|
||||||
|
import { Modal } from "../../../components";
|
||||||
|
|
||||||
|
const inputBaseStyles =
|
||||||
|
"rounded-lg border-transparent flex-1 appearance-none border border-gray-300 w-full py-2 px-4 bg-white text-gray-700 placeholder-gray-400 shadow-sm text-base focus:outline-none focus:ring-2 focus:ring-blue-600 focus:border-transparent mb-3";
|
||||||
|
|
||||||
|
type RemoveStakeModal = {
|
||||||
|
setIsOpen: React.Dispatch<React.SetStateAction<boolean>>;
|
||||||
|
isOpen: boolean;
|
||||||
|
stakedCake: string;
|
||||||
|
poolName?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const RemoveStakeModal: FC<RemoveStakeModal> = ({
|
||||||
|
setIsOpen,
|
||||||
|
isOpen,
|
||||||
|
// stakedCake,
|
||||||
|
poolName,
|
||||||
|
}) => {
|
||||||
|
const [amountInput, setAmountInput] = useState<string>("0");
|
||||||
|
const stakedCake = "44.00";
|
||||||
|
const avaliableCake = new BigNumber(stakedCake);
|
||||||
|
|
||||||
|
const handleClose = () => {
|
||||||
|
setIsOpen(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
const onSubmit = () => {};
|
||||||
|
|
||||||
|
const handleInvestInput = ({
|
||||||
|
currentTarget: { value },
|
||||||
|
}: ChangeEvent<HTMLInputElement>) => {
|
||||||
|
const newInvestAmount = new BigNumber(value);
|
||||||
|
|
||||||
|
if (
|
||||||
|
newInvestAmount.isLessThanOrEqualTo(avaliableCake) &&
|
||||||
|
newInvestAmount.isGreaterThanOrEqualTo(0)
|
||||||
|
) {
|
||||||
|
setAmountInput(value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleMaxButton = () => {
|
||||||
|
setAmountInput(stakedCake);
|
||||||
|
};
|
||||||
|
|
||||||
|
const amountToUnstake = new BigNumber(amountInput);
|
||||||
|
|
||||||
|
const stakeAvaliable =
|
||||||
|
amountToUnstake.isGreaterThan(0) &&
|
||||||
|
amountToUnstake.isLessThanOrEqualTo(avaliableCake);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Modal
|
||||||
|
isOpen={isOpen}
|
||||||
|
setIsOpen={handleClose}
|
||||||
|
title={`Remover investido em ${poolName}`}
|
||||||
|
>
|
||||||
|
<span className="mb-2">CAKE disponível: {stakedCake}</span>
|
||||||
|
<form onSubmit={onSubmit} className="bg-white py-2">
|
||||||
|
<div className="flex flex-row">
|
||||||
|
<input
|
||||||
|
className={cx(inputBaseStyles)}
|
||||||
|
type="number"
|
||||||
|
value={amountInput}
|
||||||
|
onChange={handleInvestInput}
|
||||||
|
/>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
disabled={amountInput === stakedCake}
|
||||||
|
className="flex items-center mb-3 ml-3 font-bold rounded-full text-red-500"
|
||||||
|
onClick={handleMaxButton}
|
||||||
|
>
|
||||||
|
Max
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
{avaliableCake.isEqualTo(0) && (
|
||||||
|
<span className="text-red-500 mb-1">Você não possuí saldo.</span>
|
||||||
|
)}
|
||||||
|
<button
|
||||||
|
className="cursor-pointer py-2 px-4 disabled:opacity-50 disabled:cursor-default bg-red-600 hover:bg-red-700 focus:ring-red-500 focus:ring-offset-red-200 text-white w-full transition ease-in duration-200 text-center text-base font-semibold shadow-md focus:outline-none focus:ring-2 focus:ring-offset-2 rounded-lg"
|
||||||
|
disabled={!stakeAvaliable}
|
||||||
|
type="submit"
|
||||||
|
>
|
||||||
|
Remover Stake
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
};
|
||||||
90
app/javascript/src/pages/Dashboard/Vault/Vault.tsx
Normal file
90
app/javascript/src/pages/Dashboard/Vault/Vault.tsx
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
import type { FC } from "react";
|
||||||
|
import React, { useState } from "react";
|
||||||
|
import cx from "classnames";
|
||||||
|
import { XCircleIcon } from "@heroicons/react/outline";
|
||||||
|
|
||||||
|
import type { Vault as VaultType } from "../../../types/yieldwatch";
|
||||||
|
import { RemoveStakeModal } from "./RemoveStakeModal";
|
||||||
|
|
||||||
|
type VaultProps = {
|
||||||
|
vault: Partial<VaultType>;
|
||||||
|
isLoading: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const Vault: FC<VaultProps> = ({ vault, isLoading }) => {
|
||||||
|
const [removeStakeModalIsOpen, setRemoveStakeModalIsOpen] =
|
||||||
|
useState<boolean>(false);
|
||||||
|
|
||||||
|
const totalDepositedAndRewarded = (
|
||||||
|
(vault.depositedTokens ?? 0) + (vault.totalRewards ?? 0)
|
||||||
|
).toFixed(4);
|
||||||
|
|
||||||
|
const totalDeposited = vault.depositedTokens?.toFixed(4);
|
||||||
|
const totalRewarded = vault.totalRewards?.toFixed(4);
|
||||||
|
|
||||||
|
const handleRemoveStakeModal = () => {
|
||||||
|
setRemoveStakeModalIsOpen(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<RemoveStakeModal
|
||||||
|
isOpen={removeStakeModalIsOpen}
|
||||||
|
setIsOpen={setRemoveStakeModalIsOpen}
|
||||||
|
stakedCake={totalDepositedAndRewarded}
|
||||||
|
poolName={vault.name}
|
||||||
|
/>
|
||||||
|
<div className="shadow-lg px-4 py-6 w-full bg-white dark:bg-gray-800 rounded-lg">
|
||||||
|
<div className="flex justify-between">
|
||||||
|
<p className="text-sm w-max text-gray-700 dark:text-white font-semibold border-b border-gray-200">
|
||||||
|
{vault.name}
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<button onClick={handleRemoveStakeModal} aria-label="Remover Stake">
|
||||||
|
<XCircleIcon className="h-5 w-5 text-red-500" />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div className="flex items-end space-x-2 my-6">
|
||||||
|
<p
|
||||||
|
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 && totalDepositedAndRewarded}
|
||||||
|
</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">
|
||||||
|
<p>Depositado</p>
|
||||||
|
<div
|
||||||
|
className={cx(
|
||||||
|
"flex items-end text-xs",
|
||||||
|
isLoading
|
||||||
|
? "w-10 h-4 inline-block animate-pulse bg-gray-300 rounded"
|
||||||
|
: ""
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
{!isLoading && totalDeposited}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="flex items-center text-sm space-x-12 md:space-x-24 justify-between">
|
||||||
|
<p>Ganho</p>
|
||||||
|
<div
|
||||||
|
className={cx(
|
||||||
|
"flex items-end text-xs",
|
||||||
|
isLoading
|
||||||
|
? "w-10 h-4 inline-block animate-pulse bg-gray-300 rounded"
|
||||||
|
: ""
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
{!isLoading && totalRewarded}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
1
app/javascript/src/pages/Dashboard/Vault/index.ts
Normal file
1
app/javascript/src/pages/Dashboard/Vault/index.ts
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export * from "./Vault";
|
||||||
Reference in New Issue
Block a user