From 5cda50bdad3796d8e8867c80228b4604d8646e30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Geonizeli?= Date: Tue, 17 Aug 2021 19:17:05 -0300 Subject: [PATCH] add stake modal --- app/javascript/src/components/Modal/Modal.tsx | 73 +++++++ app/javascript/src/components/Modal/index.ts | 1 + app/javascript/src/components/PoolListing.tsx | 17 -- .../src/components/{ => SideNav}/SideNav.tsx | 2 +- .../src/components/SideNav/index.ts | 1 + app/javascript/src/components/index.ts | 1 + .../{components => pages/Home}/Container.tsx | 0 .../src/{components => pages/Home}/Header.tsx | 0 app/javascript/src/pages/Home/Home.tsx | 6 +- .../src/{components => pages/Home}/Pool.tsx | 26 +-- app/javascript/src/pages/Home/PoolListing.tsx | 42 ++++ .../src/pages/Home/StakeOrderModal.tsx | 92 +++++++++ .../__generated__/PoolListingQuery.graphql.ts | 189 ++++++++++++++++++ 13 files changed, 417 insertions(+), 33 deletions(-) create mode 100644 app/javascript/src/components/Modal/Modal.tsx create mode 100644 app/javascript/src/components/Modal/index.ts delete mode 100644 app/javascript/src/components/PoolListing.tsx rename app/javascript/src/components/{ => SideNav}/SideNav.tsx (97%) create mode 100644 app/javascript/src/components/SideNav/index.ts rename app/javascript/src/{components => pages/Home}/Container.tsx (100%) rename app/javascript/src/{components => pages/Home}/Header.tsx (100%) rename app/javascript/src/{components => pages/Home}/Pool.tsx (79%) create mode 100644 app/javascript/src/pages/Home/PoolListing.tsx create mode 100644 app/javascript/src/pages/Home/StakeOrderModal.tsx create mode 100644 app/javascript/src/pages/Home/__generated__/PoolListingQuery.graphql.ts diff --git a/app/javascript/src/components/Modal/Modal.tsx b/app/javascript/src/components/Modal/Modal.tsx new file mode 100644 index 0000000..3069ba2 --- /dev/null +++ b/app/javascript/src/components/Modal/Modal.tsx @@ -0,0 +1,73 @@ +import type { FC } from "react"; +import React, { Fragment } from "react"; +import { Dialog, Transition } from "@headlessui/react"; + +type Props = { + isOpen: boolean; + setIsOpen: (state: boolean) => void; + title: string; + className?: string; +}; + +export const Modal: FC = ({ + isOpen, + setIsOpen, + children, + title, + className = "", +}) => { + const closeModal = () => { + setIsOpen(false); + }; + + return ( + + +
+ + + + + + +
+ + {title} + +
{children}
+
+
+
+
+
+ ); +}; diff --git a/app/javascript/src/components/Modal/index.ts b/app/javascript/src/components/Modal/index.ts new file mode 100644 index 0000000..1ecfeed --- /dev/null +++ b/app/javascript/src/components/Modal/index.ts @@ -0,0 +1 @@ +export * from "./Modal"; diff --git a/app/javascript/src/components/PoolListing.tsx b/app/javascript/src/components/PoolListing.tsx deleted file mode 100644 index f26942b..0000000 --- a/app/javascript/src/components/PoolListing.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import React from "react"; - -import { pools } from "../constants/Pools"; -import { Pool } from "./Pool"; - -export const PoolListing = () => { - return ( -
- {pools - .filter((pool) => !pool.isFinished) - .sort((a, b) => (a.sortOrder ?? 0) - (b.sortOrder ?? 0)) - .map((pool) => ( - - ))} -
- ); -}; diff --git a/app/javascript/src/components/SideNav.tsx b/app/javascript/src/components/SideNav/SideNav.tsx similarity index 97% rename from app/javascript/src/components/SideNav.tsx rename to app/javascript/src/components/SideNav/SideNav.tsx index 2ab45f7..61c71bd 100644 --- a/app/javascript/src/components/SideNav.tsx +++ b/app/javascript/src/components/SideNav/SideNav.tsx @@ -2,7 +2,7 @@ import * as React from "react"; import { Link } from "react-router-dom"; import { Transition } from "@headlessui/react"; -import { useApp } from "../contexts/AppProvider"; +import { useApp } from "../../contexts/AppProvider"; type MenuItem = { label: string; diff --git a/app/javascript/src/components/SideNav/index.ts b/app/javascript/src/components/SideNav/index.ts new file mode 100644 index 0000000..f039eea --- /dev/null +++ b/app/javascript/src/components/SideNav/index.ts @@ -0,0 +1 @@ +export * from "./SideNav"; diff --git a/app/javascript/src/components/index.ts b/app/javascript/src/components/index.ts index 9bb8c6e..aaab6bd 100644 --- a/app/javascript/src/components/index.ts +++ b/app/javascript/src/components/index.ts @@ -1,2 +1,3 @@ export * from "./Navbar"; export * from "./SideNav"; +export * from "./Modal"; diff --git a/app/javascript/src/components/Container.tsx b/app/javascript/src/pages/Home/Container.tsx similarity index 100% rename from app/javascript/src/components/Container.tsx rename to app/javascript/src/pages/Home/Container.tsx diff --git a/app/javascript/src/components/Header.tsx b/app/javascript/src/pages/Home/Header.tsx similarity index 100% rename from app/javascript/src/components/Header.tsx rename to app/javascript/src/pages/Home/Header.tsx diff --git a/app/javascript/src/pages/Home/Home.tsx b/app/javascript/src/pages/Home/Home.tsx index 9dbe107..4c02147 100644 --- a/app/javascript/src/pages/Home/Home.tsx +++ b/app/javascript/src/pages/Home/Home.tsx @@ -1,9 +1,9 @@ import type { FC } from "react"; import React from "react"; -import { Container } from "../../components/Container"; -import { Header } from "../../components/Header"; -import { PoolListing } from "../../components/PoolListing"; +import { Container } from "./Container"; +import { Header } from "./Header"; +import { PoolListing } from "./PoolListing"; export const Home: FC = () => { return ( diff --git a/app/javascript/src/components/Pool.tsx b/app/javascript/src/pages/Home/Pool.tsx similarity index 79% rename from app/javascript/src/components/Pool.tsx rename to app/javascript/src/pages/Home/Pool.tsx index e16eca1..2bfdc2f 100644 --- a/app/javascript/src/components/Pool.tsx +++ b/app/javascript/src/pages/Home/Pool.tsx @@ -1,16 +1,19 @@ +import type { FC } from "react"; import React from "react"; -import type { PoolConfig } from "../types"; -import { useBsc } from "../contexts/BscProvider"; -import { getPriceInBusd } from "../utils/getPrice"; -import { getApr } from "../utils/apr"; -import { getTotalStaked } from "../utils/getTotalStaked"; +import type { PoolConfig } from "../../types"; +import { useBsc } from "../../contexts/BscProvider"; +import { getApr } from "../../utils/apr"; +import { getPriceInBusd } from "../../utils/getPrice"; +import { getTotalStaked } from "../../utils/getTotalStaked"; +import { StakeOrderModal } from "./StakeOrderModal"; type PoolProps = { pool: PoolConfig; + cakeBalance: string; }; -export const Pool = ({ pool }: PoolProps) => { +export const Pool: FC = ({ pool, cakeBalance }) => { const { provider, pancake: { router }, @@ -77,12 +80,7 @@ export const Pool = ({ pool }: PoolProps) => { />

- Investir:{" "} - {pool.stakingToken.symbol} -

-

- Receber:{" "} - {pool.earningToken.symbol} + Pool: {pool.earningToken.symbol}

Rendimento: @@ -92,6 +90,10 @@ export const Pool = ({ pool }: PoolProps) => { `${apr.value}%` )}
+
); diff --git a/app/javascript/src/pages/Home/PoolListing.tsx b/app/javascript/src/pages/Home/PoolListing.tsx new file mode 100644 index 0000000..f18208e --- /dev/null +++ b/app/javascript/src/pages/Home/PoolListing.tsx @@ -0,0 +1,42 @@ +import { graphql } from "babel-plugin-relay/macro"; +import React from "react"; +import { useLazyLoadQuery } from "react-relay"; + +import { pools } from "../../constants/Pools"; +import { Pool } from "./Pool"; +import type { PoolListingQuery } from "./__generated__/PoolListingQuery.graphql"; + +export const PoolListing = () => { + const { balances } = useLazyLoadQuery( + graphql` + query PoolListingQuery { + balances { + edges { + node { + currency { + name + } + amount + } + } + } + } + `, + {} + ); + + const cakeBalance = + balances.edges.find((edge) => edge.node.currency.name === "CAKE")?.node + .amount ?? "0"; + + return ( +
+ {pools + .filter((pool) => !pool.isFinished) + .sort((a, b) => (a.sortOrder ?? 0) - (b.sortOrder ?? 0)) + .map((pool) => ( + + ))} +
+ ); +}; diff --git a/app/javascript/src/pages/Home/StakeOrderModal.tsx b/app/javascript/src/pages/Home/StakeOrderModal.tsx new file mode 100644 index 0000000..c5785fb --- /dev/null +++ b/app/javascript/src/pages/Home/StakeOrderModal.tsx @@ -0,0 +1,92 @@ +import type { ChangeEvent, FC } from "react"; +import React, { useState } from "react"; +import cx from "classnames"; +import { BigNumber } from "bignumber.js"; + +import { Modal } from "../../components"; + +type Props = { + poolName: string; + cakeBalance: string; +}; + +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"; + +export const StakeOrderModal: FC = ({ poolName, cakeBalance }) => { + const [isOpen, setIsOpen] = useState(false); + const [investAmountInput, setInvestAmountInput] = useState("0"); + + const avaliableCake = new BigNumber(cakeBalance); + const investAmount = new BigNumber(investAmountInput); + + const handleButtonClick = () => { + setIsOpen((prevState) => !prevState); + }; + + const onSubmit = () => {}; + + const handleInvestInput = ({ + currentTarget: { value }, + }: ChangeEvent) => { + const newInvestAmount = new BigNumber(value); + + if ( + newInvestAmount.isLessThanOrEqualTo(avaliableCake) && + newInvestAmount.isGreaterThanOrEqualTo(0) + ) { + setInvestAmountInput(value); + } + }; + + const stakeAvaliable = + avaliableCake.isGreaterThan(0) && + avaliableCake.isLessThanOrEqualTo(investAmount); + + return ( +
+ + + CAKE disponível: {cakeBalance} +
+
+ + +
+ {avaliableCake.isEqualTo(0) && ( + Você não possuí saldo. + )} + +
+
+
+ ); +}; diff --git a/app/javascript/src/pages/Home/__generated__/PoolListingQuery.graphql.ts b/app/javascript/src/pages/Home/__generated__/PoolListingQuery.graphql.ts new file mode 100644 index 0000000..c359895 --- /dev/null +++ b/app/javascript/src/pages/Home/__generated__/PoolListingQuery.graphql.ts @@ -0,0 +1,189 @@ +/* tslint:disable */ +/* eslint-disable */ +// @ts-nocheck + +import { ConcreteRequest } from "relay-runtime"; +export type PoolListingQueryVariables = {}; +export type PoolListingQueryResponse = { + readonly balances: { + readonly edges: ReadonlyArray<{ + readonly node: { + readonly currency: { + readonly name: string; + }; + readonly amount: string; + }; + }>; + }; +}; +export type PoolListingQuery = { + readonly response: PoolListingQueryResponse; + readonly variables: PoolListingQueryVariables; +}; + + + +/* +query PoolListingQuery { + balances { + edges { + node { + currency { + name + id + } + amount + id + } + } + } +} +*/ + +const node: ConcreteRequest = (function(){ +var v0 = { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "name", + "storageKey": null +}, +v1 = { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "amount", + "storageKey": null +}, +v2 = { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "id", + "storageKey": null +}; +return { + "fragment": { + "argumentDefinitions": [], + "kind": "Fragment", + "metadata": null, + "name": "PoolListingQuery", + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "BalanceConnection", + "kind": "LinkedField", + "name": "balances", + "plural": false, + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "BalanceEdge", + "kind": "LinkedField", + "name": "edges", + "plural": true, + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "Balance", + "kind": "LinkedField", + "name": "node", + "plural": false, + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "Currency", + "kind": "LinkedField", + "name": "currency", + "plural": false, + "selections": [ + (v0/*: any*/) + ], + "storageKey": null + }, + (v1/*: any*/) + ], + "storageKey": null + } + ], + "storageKey": null + } + ], + "storageKey": null + } + ], + "type": "Query", + "abstractKey": null + }, + "kind": "Request", + "operation": { + "argumentDefinitions": [], + "kind": "Operation", + "name": "PoolListingQuery", + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "BalanceConnection", + "kind": "LinkedField", + "name": "balances", + "plural": false, + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "BalanceEdge", + "kind": "LinkedField", + "name": "edges", + "plural": true, + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "Balance", + "kind": "LinkedField", + "name": "node", + "plural": false, + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "Currency", + "kind": "LinkedField", + "name": "currency", + "plural": false, + "selections": [ + (v0/*: any*/), + (v2/*: any*/) + ], + "storageKey": null + }, + (v1/*: any*/), + (v2/*: any*/) + ], + "storageKey": null + } + ], + "storageKey": null + } + ], + "storageKey": null + } + ] + }, + "params": { + "cacheID": "6abf5e963429e49993af50df156f8e1c", + "id": null, + "metadata": {}, + "name": "PoolListingQuery", + "operationKind": "query", + "text": "query PoolListingQuery {\n balances {\n edges {\n node {\n currency {\n name\n id\n }\n amount\n id\n }\n }\n }\n}\n" + } +}; +})(); +(node as any).hash = '4fefb238e24b79198799686599255e6c'; +export default node;