From d4349cd753dc75f2b791a1c7fab07015a6a3f8f8 Mon Sep 17 00:00:00 2001 From: TranKhanhDuy Date: Fri, 8 Sep 2023 17:13:28 +0700 Subject: [PATCH 01/11] add NFT Txs' tab in page: /wallet --- .../Wallet/NFTToken/NFTCard/NFTCard.js | 90 ++++++++++++ .../NFTToken/NFTCard/NFTCard.module.scss | 80 ++++++++++ .../NFTToken/NFTCard/NFTCardSkeleton.js | 90 ++++++++++++ .../Wallet/NFTToken/NFTCard/index.js | 1 + .../Wallet/NFTToken/NFTTable/NFTTable.js | 115 +++++++++++++++ .../NFTToken/NFTTable/NFTTable.module.scss | 139 ++++++++++++++++++ .../NFTToken/NFTTable/NFTTableSkeleton.js | 65 ++++++++ .../Wallet/NFTToken/NFTTable/index.js | 1 + src/components/Wallet/NFTToken/NFTToken.js | 96 ++++++++++++ .../Wallet/NFTToken/NFTToken.module.scss | 25 ++++ src/components/Wallet/NFTToken/index.js | 1 + src/components/Wallet/Tabs/Tabs.js | 15 +- src/containers/Wallet/Wallet.js | 18 ++- src/lib/api.js | 28 ++-- 14 files changed, 739 insertions(+), 25 deletions(-) create mode 100644 src/components/Wallet/NFTToken/NFTCard/NFTCard.js create mode 100644 src/components/Wallet/NFTToken/NFTCard/NFTCard.module.scss create mode 100644 src/components/Wallet/NFTToken/NFTCard/NFTCardSkeleton.js create mode 100644 src/components/Wallet/NFTToken/NFTCard/index.js create mode 100644 src/components/Wallet/NFTToken/NFTTable/NFTTable.js create mode 100644 src/components/Wallet/NFTToken/NFTTable/NFTTable.module.scss create mode 100644 src/components/Wallet/NFTToken/NFTTable/NFTTableSkeleton.js create mode 100644 src/components/Wallet/NFTToken/NFTTable/index.js create mode 100644 src/components/Wallet/NFTToken/NFTToken.js create mode 100644 src/components/Wallet/NFTToken/NFTToken.module.scss create mode 100644 src/components/Wallet/NFTToken/index.js diff --git a/src/components/Wallet/NFTToken/NFTCard/NFTCard.js b/src/components/Wallet/NFTToken/NFTCard/NFTCard.js new file mode 100644 index 000000000..fa5de7153 --- /dev/null +++ b/src/components/Wallet/NFTToken/NFTCard/NFTCard.js @@ -0,0 +1,90 @@ +import React, { memo } from "react"; +import classNames from "classnames/bind"; +import { checkStatus } from "../NFTTable/NFTTable"; +import { NavLink } from "react-router-dom"; +import { _, reduceString, setAgoTime } from "src/lib/scripts"; +import { formatOrai } from "src/helpers/helper"; +import consts from "src/constants/consts"; +import styles from "./NFTCard.module.scss"; + +const cx = classNames.bind(styles); + +const NFTCard = memo(({ data = [], address }) => { + if (!Array.isArray(data)) { + return <>; + } + const reduceStringAdress = (title, value, toHref = "") => { + return ( + + +
{title}
+ + + {value ? ( +
+ + {reduceString(value, 6, 6)} + +
+ ) : ( +
-
+ )} + + + ); + }; + + return ( +
+ {data.map(item => { + return ( +
+ + + {reduceStringAdress("TxHash", item?.tx_hash, `${consts.PATH.TXLIST}/${item.tx_hash}`)} + + + + + + + + + + + + + {reduceStringAdress("Creator", item?.creator, `${consts.PATH.TXLIST}/${item.creator}`)} + {reduceStringAdress("Contract address", item?.contract_address, `${consts.PATH.TXLIST}/${item.contract_address}`)} + {reduceStringAdress("Contract", item?.contract, `${consts.PATH.TXLIST}/${item.contract}`)} + + + + + + +
+
NFT ID
+
+ {item?.nft_id} +
+
NFT Name
+
+ {item?.nft_name} +
+
Creator Type
+
+ {item?.creator_type.toUpperCase()} +
+
Time
+
+ {setAgoTime(item?.timestamp)} +
+
+ ); + })} +
+ ); +}); + +export default NFTCard; diff --git a/src/components/Wallet/NFTToken/NFTCard/NFTCard.module.scss b/src/components/Wallet/NFTToken/NFTCard/NFTCard.module.scss new file mode 100644 index 000000000..ccd9ffa05 --- /dev/null +++ b/src/components/Wallet/NFTToken/NFTCard/NFTCard.module.scss @@ -0,0 +1,80 @@ +@import "src/styles/utils"; + +.nftToken-card-list { + &-item { + padding: 15px; + margin-bottom: 15px; + background-color: var(--common-containerBackgroundColor); + box-shadow: 0px 2px 8px var(--common-boxShadowColor); + border-radius: 8px; + + table { + width: 100%; + tr { + td { + padding-bottom: 15px; + } + + td:nth-child(1) { + text-align: left; + width: 40%; + } + td:nth-child(2) { + text-align: right; + width: 60%; + } + } + } + + .item-title { + color: var(--common-textColor); + font-family: 'IBM Plex Sans'; + font-style: normal; + font-weight: 500; + font-size: 16px; + line-height: 150%; + } + + .item-text { + color: var(--common-textColor); + font-family: 'IBM Plex Sans'; + font-style: normal; + font-weight: normal; + font-size: 16px; + line-height: 150%; + } + + .item-link { + color: var(--common-linkColor); + font-family: 'IBM Plex Sans'; + font-style: normal; + font-weight: normal; + font-size: 16px; + line-height: 150%; + } + + .item-status { + width: 50px; + } + + .address-data-cell { + display: flex; + flex-direction: row; + justify-content: flex-end; + align-items: center; + + &-with-owner-badge { + justify-content: space-between; + } + + .address { + color: var(--common-linkColor); + font-family: 'IBM Plex Sans'; + font-style: normal; + font-weight: normal; + font-size: 16px; + line-height: 150%; + } + } + } +} diff --git a/src/components/Wallet/NFTToken/NFTCard/NFTCardSkeleton.js b/src/components/Wallet/NFTToken/NFTCard/NFTCardSkeleton.js new file mode 100644 index 000000000..06ce2d787 --- /dev/null +++ b/src/components/Wallet/NFTToken/NFTCard/NFTCardSkeleton.js @@ -0,0 +1,90 @@ +import React, { memo } from "react"; +import Skeleton from "@material-ui/lab/Skeleton"; +import classNames from "classnames/bind"; +import styles from "./NFTCard.module.scss"; + +const CwCardSkeleton = memo(({ rows = 10 }) => { + const cx = classNames.bind(styles); + + let CwCardSkeletonItems = []; + for (let i = 1; i <= rows; i++) { + CwCardSkeletonItems.push( +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
TxHash
+
+ +
+
NFT ID
+
+ +
+
NFT Name
+ +
+
Creator Type
+
+ +
+
Creator
+
+ +
+
Contract address
+
+ +
+
Contract
+
+ +
+
Time
+
+ +
+
+ ); + } + + return
{CwCardSkeletonItems}
; +}); + +export default CwCardSkeleton; diff --git a/src/components/Wallet/NFTToken/NFTCard/index.js b/src/components/Wallet/NFTToken/NFTCard/index.js new file mode 100644 index 000000000..25e7c7b31 --- /dev/null +++ b/src/components/Wallet/NFTToken/NFTCard/index.js @@ -0,0 +1 @@ +export { default } from "./NFTCard"; diff --git a/src/components/Wallet/NFTToken/NFTTable/NFTTable.js b/src/components/Wallet/NFTToken/NFTTable/NFTTable.js new file mode 100644 index 000000000..52394c880 --- /dev/null +++ b/src/components/Wallet/NFTToken/NFTTable/NFTTable.js @@ -0,0 +1,115 @@ +import React, { memo, useMemo } from "react"; +import classNames from "classnames/bind"; +import { NavLink } from "react-router-dom"; +import consts from "src/constants/consts"; +import { _, reduceString, setAgoTime } from "src/lib/scripts"; +import { formatOrai } from "src/helpers/helper"; +import { tableThemes } from "src/constants/tableThemes"; +import ThemedTable from "src/components/common/ThemedTable"; +import styles from "./NFTTable.module.scss"; +import { string } from "prop-types"; + +const cx = classNames.bind(styles); + +export const getHeaderRow = () => { + const txHashHeaderCell =
TxHash
; + const contractAddrHeaderCell =
Contract address
; + const contractHeaderCell =
Contract
; + const creatorHeaderCell =
Creator
; + const creatorTypeHeaderCell =
Creator Type
; + const nftNameHeaderCell =
NFT Name
; + const nftIDHeaderCell =
NFT ID
; + const timeHeaderCell =
Time
; + + let headerCells = [ + txHashHeaderCell, + nftIDHeaderCell, + nftNameHeaderCell, + creatorTypeHeaderCell, + creatorHeaderCell, + contractAddrHeaderCell, + contractHeaderCell, + timeHeaderCell, + ]; + let headerCellStyles = [ + { width: "14%", minWidth: "180px" }, // TxHash + { width: "8%", minWidth: "80px" }, // NFT ID + { width: "14%", minWidth: "120px" }, // NFT Name + { width: "12%", minWidth: "120px" }, // Creator type + { width: "14%", minWidth: "180px" }, // Creator + { width: "14%", minWidth: "180px" }, // Contract address + { width: "14%", minWidth: "180px" }, // Contract + { width: "12%", minWidth: "120px" }, // Time + ]; + + return { + headerCells, + headerCellStyles, + }; +}; + +const reduceStringAdress = (value, toHref = "", isStyle, rawString = false) => { + const result = _.isNil(value) ? ( +
-
+ ) : ( + + {isStyle === 1 ?
{rawString ? value : reduceString(value, 6, 6)}
: rawString ? value : reduceString(value, 6, 6)} +
+ ); + return result; +}; + +const NFTTable = memo(({ data = [], address }) => { + const getDataRows = data => { + if (!Array.isArray(data)) { + return []; + } + + return data.map(item => { + const txHashDataCell = reduceStringAdress(item?.tx_hash, `${consts.PATH.TXLIST}/${item.tx_hash}`); + + const contractAddrDataCell = reduceStringAdress(item?.contract_address, `${consts.PATH.ACCOUNT}/${item?.contract_address}`); + const contractDataCell = reduceStringAdress(item?.contract, `${consts.PATH.ACCOUNT}/${item?.contract}`); + const creatorDataCell = reduceStringAdress(item?.creator, `${consts.PATH.ACCOUNT}/${item?.creator}`); + + const creatorTypeDataCell = _.isNil(item?.creator_type) ? ( +
-
+ ) : ( +
+ {item.creator_type.toUpperCase()} +
+ ); + + const nftNameDataCell = _.isNil(item?.nft_name) ? ( +
-
+ ) : ( +
+ {item.nft_name} +
+ ); + + const nftIDDataCell = _.isNil(item?.nft_id) ? ( +
-
+ ) : ( +
+ {item.nft_id} +
+ ); + + const timeDataCell = _.isNil(item?.timestamp) ? ( +
-
+ ) : ( +
{setAgoTime(item.timestamp)}
+ ); + + return [txHashDataCell, nftIDDataCell, nftNameDataCell, creatorTypeDataCell, creatorDataCell, contractAddrDataCell, contractDataCell, timeDataCell]; + }); + }; + + const headerRow = useMemo(() => getHeaderRow(), []); + const dataRows = useMemo(() => getDataRows(data), [data, getDataRows]); + + return ; +}); + +export default NFTTable; diff --git a/src/components/Wallet/NFTToken/NFTTable/NFTTable.module.scss b/src/components/Wallet/NFTToken/NFTTable/NFTTable.module.scss new file mode 100644 index 000000000..a0612e27b --- /dev/null +++ b/src/components/Wallet/NFTToken/NFTTable/NFTTable.module.scss @@ -0,0 +1,139 @@ +@import "src/styles/utils"; +.align-left { + text-align: left; +} + +.align-right { + text-align: right; +} + +.align-center { + text-align: center; +} + +.header-cell { + color: var(--common-textColor); + font-family: 'IBM Plex Sans'; + font-style: normal; + font-weight: bold; + font-size: 14px; + line-height: 150%; +} + +.skeleton-data-cell { + box-sizing: border-box; + height: 32px; +} + +.sm-contract-data-cell { + color: var(--common-linkColor); + font-family: 'IBM Plex Sans'; + font-style: normal; + font-weight: normal; + font-size: 14px; + line-height: 150%; +} + +.type-data-cell { + display: flex; + flex-direction: row; + justify-content: flex-start; + align-items: center; + + .first-message-type { + padding: 6px 10px; + margin-right: 5px; + border: 1px solid #5f51ff; + box-sizing: border-box; + border-radius: 4px; + color: #5f51ff; + font-family: 'IBM Plex Sans'; + font-style: normal; + font-weight: normal; + font-size: 12px; + line-height: 150%; + } + + .number-of-message { + color: #5f51ff; + font-family: 'IBM Plex Sans'; + font-style: normal; + font-weight: normal; + font-size: 12px; + line-height: 150%; + } +} + +.result-data-cell { + display: flex; + flex-direction: row; + justify-content: center; + + img { + margin-right: 9px; + } +} + +.amount-data-cell { + display: flex; + flex-direction: row; + justify-content: flex-end; + + p { + margin-right: 8px; + } + + span:nth-child(1) { + padding-right: 4px; + } + + span:nth-child(2) { + text-transform: uppercase; + } +} + +.fee-data-cell { + span:nth-child(1) { + padding-right: 4px; + } + + span:nth-child(2) { + text-transform: uppercase; + } +} + +.time-data-cell, +.height-data-cell { + display: block; + color: var(--common-textColor); + font-family: 'IBM Plex Sans'; + font-style: normal; + font-weight: normal; + font-size: 14px; + line-height: 150%; +} + +.transfer-status { + display: block; + min-width: 40px; + text-align: center; + padding: 7px; + border-radius: 4px; + font-family: "IBM Plex Sans"; + font-style: normal; + font-weight: bold; + font-size: 11px; + line-height: 150%; + + &-in { + background: var(--common-transactions-amountTransactionBackgroundInColor); + color: var(--common-transactions-amountTransactionTextInColor); + border: 1px solid var(--common-transactions-amountTransactionLabelInColor); + } + + &-out { + background: var(--common-transactions-amountTransactionBackgroundOutColor); + color: var(--common-transactions-amountTransactionTextOutColor); + border: 1px solid var(--common-transactions-amountTransactionLabelOutColor); + } +} diff --git a/src/components/Wallet/NFTToken/NFTTable/NFTTableSkeleton.js b/src/components/Wallet/NFTToken/NFTTable/NFTTableSkeleton.js new file mode 100644 index 000000000..1ac0c3054 --- /dev/null +++ b/src/components/Wallet/NFTToken/NFTTable/NFTTableSkeleton.js @@ -0,0 +1,65 @@ +import React, {memo, useMemo} from "react"; +import Skeleton from "@material-ui/lab/Skeleton"; +import classNames from "classnames/bind"; +import {tableThemes} from "src/constants/tableThemes"; +import ThemedTable from "src/components/common/ThemedTable"; +import {getHeaderRow} from "./NFTTable"; +import styles from "./NFTTable.module.scss"; + +const NFTTableSkeleton = memo(({rows = 10}) => { + const cx = classNames.bind(styles); + const getDataRows = rows => { + let dataRows = []; + for (let i = 1; i <= rows; i++) { + const txHashDataCell = ( +
+ +
+ ); + + const ageDataCell = ( +
+ +
+ ); + + const fromDataCell = ( +
+ +
+ ); + + const statusDataCell = ( +
+ +
+ ); + + const toDataCell = ( +
+ +
+ ); + + const valueDataCell = ( +
+ +
+ ); + const tokenDataCell = ( +
+ +
+ ); + dataRows.push([txHashDataCell, ageDataCell, fromDataCell, statusDataCell, toDataCell, valueDataCell, tokenDataCell]); + } + return dataRows; + }; + + const headerRow = useMemo(() => getHeaderRow(), []); + const dataRows = useMemo(() => getDataRows(rows), [rows]); + + return ; +}); + +export default NFTTableSkeleton; diff --git a/src/components/Wallet/NFTToken/NFTTable/index.js b/src/components/Wallet/NFTToken/NFTTable/index.js new file mode 100644 index 000000000..d3bf319e9 --- /dev/null +++ b/src/components/Wallet/NFTToken/NFTTable/index.js @@ -0,0 +1 @@ +export { default } from "./NFTTable"; \ No newline at end of file diff --git a/src/components/Wallet/NFTToken/NFTToken.js b/src/components/Wallet/NFTToken/NFTToken.js new file mode 100644 index 000000000..8f59d0e9f --- /dev/null +++ b/src/components/Wallet/NFTToken/NFTToken.js @@ -0,0 +1,96 @@ +import React, { memo, useEffect, useState } from "react"; +import { useGet } from "restful-react"; +import { useTheme } from "@material-ui/core/styles"; +import useMediaQuery from "@material-ui/core/useMediaQuery"; +import classNames from "classnames/bind"; +import Pagination from "src/components/common/Pagination"; +import NoResult from "src/components/common/NoResult"; +import NFTTable from "./NFTTable"; +import NFTTableSkeleton from "./NFTTable/NFTTableSkeleton"; +import NFTCardSkeleton from "./NFTCard/NFTCardSkeleton"; +import { getListNFTToken, getListOWContract } from "src/lib/api"; +import NFTCard from "./NFTCard"; +import styles from "./NFTToken.module.scss"; +import { NavLink } from "react-router-dom"; +import consts from "src/constants/consts"; +import { typeExport } from "src/containers/Account/Account"; + +const cx = classNames.bind(styles); + +const NFTToken = memo(({ account = "", address = "", isOw20 = false }) => { + const theme = useTheme(); + const isLargeScreen = useMediaQuery(theme.breakpoints.up("lg")); + const [dataCw, setDataCw] = useState({ + data: [], + page: { + limit: 10, + page_id: 1, + }, + }); + const { data, page } = dataCw; + const [path, setPath] = useState(() => { + if (!isOw20) { + return getListNFTToken(address, page); + } + return getListOWContract(address, page); + }); + + const { data: dataRes } = useGet({ + path, + }); + + useEffect(() => { + if (dataRes) { + setDataCw({ + ...dataCw, + data: dataRes?.data, + page: { + ...dataCw.page, + ...dataRes?.page, + }, + }); + } + }, [dataRes]); + + const totalPages = page?.total_page ?? 0; + const currentPage = page?.page_id ?? 1; + + const onPageChange = newPage => { + const pageObj = { + ...page, + page_id: newPage, + }; + if (!isOw20) { + return setPath(getListNFTToken(address, pageObj)); + } + return setPath(getListOWContract(address, pageObj)); + }; + + const tableSekeleton = () => { + return isLargeScreen ? : ; + }; + + return ( +
+ {!dataRes ? ( + tableSekeleton() + ) : Array.isArray(data) && data.length > 0 ? ( + <> + {isLargeScreen ? : } + {totalPages > 0 && onPageChange(page)} />} + + [ Download{" "} + + CSV Export + {" "} + ] + + + ) : ( + + )} +
+ ); +}); + +export default NFTToken; diff --git a/src/components/Wallet/NFTToken/NFTToken.module.scss b/src/components/Wallet/NFTToken/NFTToken.module.scss new file mode 100644 index 000000000..b234ff64e --- /dev/null +++ b/src/components/Wallet/NFTToken/NFTToken.module.scss @@ -0,0 +1,25 @@ +.cw20 { + overflow-x: auto; + width: 100%; + + .text { + display: flex; + flex-direction: row; + justify-content: flex-end; + color: var(--common-textColor); + align-items: center; + font-family: 'IBM Plex Sans'; + font-style: normal; + font-weight: normal; + font-size: 14px; + line-height: 150%; + margin-top: -16px; + + &-link { + color: var(--common-linkColor); + margin: 4px; + } + } + + +} \ No newline at end of file diff --git a/src/components/Wallet/NFTToken/index.js b/src/components/Wallet/NFTToken/index.js new file mode 100644 index 000000000..9488f3d4f --- /dev/null +++ b/src/components/Wallet/NFTToken/index.js @@ -0,0 +1 @@ +export { default } from "./NFTToken"; \ No newline at end of file diff --git a/src/components/Wallet/Tabs/Tabs.js b/src/components/Wallet/Tabs/Tabs.js index d5c8c548c..a305691ee 100644 --- a/src/components/Wallet/Tabs/Tabs.js +++ b/src/components/Wallet/Tabs/Tabs.js @@ -1,17 +1,17 @@ /* eslint-disable react-hooks/exhaustive-deps */ import * as React from "react"; import cn from "classnames/bind"; -import {useGet} from "restful-react"; +import { useGet } from "restful-react"; import ContactIcon from "src/icons/Tabs/ProposalsTabIcon"; import ValidatorsIcon from "src/icons/Tabs/ValidatorsTabIcon"; import TransactionsIcon from "src/icons/Tabs/TransactionsTabIcon"; -import {getListCwToken} from "src/lib/api"; +import { getListCwToken } from "src/lib/api"; import styles from "./Tabs.module.scss"; const cx = cn.bind(styles); -export default function({activeTab, setActiveTab, isBecomeValidator, address}) { - const {data: dataRes} = useGet({ +export default function({ activeTab, setActiveTab, isBecomeValidator, address }) { + const { data: dataRes } = useGet({ path: getListCwToken(address), }); @@ -23,7 +23,12 @@ export default function({activeTab, setActiveTab, isBecomeValidator, address}) { {dataRes?.data && dataRes?.data?.length > 0 && (
setActiveTab(6)}> -
CW-20 Token Txns
+
CW-20 Token Txs
+
+ )} + {dataRes?.data && dataRes?.data?.length > 0 && ( +
setActiveTab(7)}> +
NFT Txs
)} {isBecomeValidator && ( diff --git a/src/containers/Wallet/Wallet.js b/src/containers/Wallet/Wallet.js index 7b45c7599..0b8345fe7 100644 --- a/src/containers/Wallet/Wallet.js +++ b/src/containers/Wallet/Wallet.js @@ -2,33 +2,34 @@ import * as React from "react"; import cn from "classnames/bind"; import Container from "@material-ui/core/Container"; -import {useSelector} from "react-redux"; -import {useGet} from "restful-react"; -import {_} from "src/lib/scripts"; +import { useSelector } from "react-redux"; +import { useGet } from "restful-react"; +import { _ } from "src/lib/scripts"; import consts from "src/constants/consts"; import PageTitle from "src/components/common/PageTitle"; import TitleWrapper from "src/components/common/TitleWrapper"; import StatusBar from "src/components/Wallet/StatusBar"; import Tabs from "src/components/Wallet/Tabs"; -import {RegisterDetail} from "src/components/Wallet/Register"; +import { RegisterDetail } from "src/components/Wallet/Register"; import Transaction from "src/components/Wallet/Transaction"; import Contact from "src/components/Wallet/Contact"; import CwToken from "src/components/Wallet/CwToken"; +import NFTToken from "src/components/Wallet/NFTToken"; import styles from "./Wallet.module.scss"; const cx = cn.bind(styles); export default function(props) { const [activeTab, setActiveTab] = React.useState(0); - const {address} = useSelector(state => state.wallet); + const { address } = useSelector(state => state.wallet); const path = consts.API.VALIDATOR + "/" + address; - const {data} = useGet({ + const { data } = useGet({ path: path, }); const isBecomeValidator = !data ? false : data.operator_address ? true : false; - const {data: walletInfo} = useGet({ + const { data: walletInfo } = useGet({ path: `${consts.LCD_API_BASE}${consts.LCD_API.ACCOUNT_DETAIL}/accounts/${address}`, }); @@ -41,8 +42,9 @@ export default function(props) { {activeTab === 0 && } {activeTab === 6 && } + {activeTab === 7 && } {activeTab === 3 && isBecomeValidator && } {activeTab === 4 && } - + ); } diff --git a/src/lib/api.js b/src/lib/api.js index 0828b303f..a01b46925 100644 --- a/src/lib/api.js +++ b/src/lib/api.js @@ -80,35 +80,39 @@ export const getListTxs = cancelToken => { }; export const getListCwToken = (address, page) => { - return `${consts.API_BASE}${consts.API.OW20_SMART_CONTRACTS}/${address}?limit=${page?.limit || 1}&page_id=${page?.page_id || 1}` -} + return `${consts.API_BASE}${consts.API.OW20_SMART_CONTRACTS}/${address}?limit=${page?.limit || 1}&page_id=${page?.page_id || 1}`; +}; + +export const getListNFTToken = (address, page) => { + return `https://api.testnet.scan.orai.io/v1/nft_transaction/${address}?limit=${page?.limit || 1}&page_id=${page?.page_id || 1}`; +}; export const getListOWContract = (address, page) => { - return `${consts.API_BASE}${consts.API.OW20_SMART_CONTRACTS}${consts.API.OW20_CONTRACT}/${address}?limit=${page?.limit || 1}&page_id=${page?.page_id || 1}` -} + return `${consts.API_BASE}${consts.API.OW20_SMART_CONTRACTS}${consts.API.OW20_CONTRACT}/${address}?limit=${page?.limit || 1}&page_id=${page?.page_id || 1}`; +}; -export const getGeckoMarketBalance = async (ids = '', currency = 'usd') => { +export const getGeckoMarketBalance = async (ids = "", currency = "usd") => { // remove undefined - ids = ids.replace(new RegExp("\,undefined", "gm"), ""); + ids = ids.replace(new RegExp(",undefined", "gm"), ""); return ids ? await axios(`${consts.API_COINGECKO.PRICE(ids, currency)}`) : { data: {} }; }; -export const getImagesValidator = async (address) => { +export const getImagesValidator = async address => { return await axios.get(`${consts.API_BASE}${consts.API.GET_IMAGES_VALIDATORS}/${address}`); -} +}; export const getListRequest = (aiOracle, aiRequest) => { return axios.get(`${consts.LCD_API_BASE}${consts.LCD_API.WASM}/${aiOracle}/smart/${aiRequest}`); }; -export const uploadImagesValidator = async (data) => { +export const uploadImagesValidator = async data => { return await axios({ url: `${consts.API_BASE}${consts.API.UPLOAD_IMAGES_VALIDATORS}`, ...data }); }; -export const uploadSchema = async (data) => { +export const uploadSchema = async data => { return await axios({ url: `${consts.API_CONTRACT_DEPLOY}${consts.PATH_CONTRACT.UPLOAD_SCHEMA}`, ...data }); }; -export const axiosCall = async (data) => { +export const axiosCall = async data => { return await axios({ ...data }); -}; \ No newline at end of file +}; From 5df534c760111d7c6f90f7902f4e38e5b454820b Mon Sep 17 00:00:00 2001 From: TranKhanhDuy Date: Fri, 8 Sep 2023 18:20:39 +0700 Subject: [PATCH 02/11] clean code --- .../NFTToken/NFTCard/NFTCardSkeleton.js | 90 +++++-------------- src/components/Wallet/Tabs/Tabs.js | 7 +- src/lib/api.js | 2 +- 3 files changed, 28 insertions(+), 71 deletions(-) diff --git a/src/components/Wallet/NFTToken/NFTCard/NFTCardSkeleton.js b/src/components/Wallet/NFTToken/NFTCard/NFTCardSkeleton.js index 06ce2d787..7ae70a079 100644 --- a/src/components/Wallet/NFTToken/NFTCard/NFTCardSkeleton.js +++ b/src/components/Wallet/NFTToken/NFTCard/NFTCardSkeleton.js @@ -5,79 +5,35 @@ import styles from "./NFTCard.module.scss"; const CwCardSkeleton = memo(({ rows = 10 }) => { const cx = classNames.bind(styles); - let CwCardSkeletonItems = []; + const dataSource = [ + { title: "TxHash" }, + { title: "NFT ID" }, + { title: "NFT Name" }, + { title: "Creator Type" }, + { title: "Creator" }, + { title: "Contract address" }, + { title: "Contract" }, + { title: "Time" }, + ]; + for (let i = 1; i <= rows; i++) { CwCardSkeletonItems.push(
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + {dataSource.map(({ title }) => { + return ( + + + + + )})} +
-
TxHash
-
- -
-
NFT ID
-
- -
-
NFT Name
- -
-
Creator Type
-
- -
-
Creator
-
- -
-
Contract address
-
- -
-
Contract
-
- -
-
Time
-
- -
+
{title}
+
+ +
diff --git a/src/components/Wallet/Tabs/Tabs.js b/src/components/Wallet/Tabs/Tabs.js index a305691ee..0a94b06d4 100644 --- a/src/components/Wallet/Tabs/Tabs.js +++ b/src/components/Wallet/Tabs/Tabs.js @@ -11,9 +11,10 @@ import styles from "./Tabs.module.scss"; const cx = cn.bind(styles); export default function({ activeTab, setActiveTab, isBecomeValidator, address }) { - const { data: dataRes } = useGet({ + const response = useGet({ path: getListCwToken(address), }); + const dataRes = response?.data?.data; return (
@@ -21,12 +22,12 @@ export default function({ activeTab, setActiveTab, isBecomeValidator, address })
Transactions
- {dataRes?.data && dataRes?.data?.length > 0 && ( + {dataRes && dataRes?.length > 0 && (
setActiveTab(6)}>
CW-20 Token Txs
)} - {dataRes?.data && dataRes?.data?.length > 0 && ( + {dataRes && dataRes?.length > 0 && (
setActiveTab(7)}>
NFT Txs
diff --git a/src/lib/api.js b/src/lib/api.js index a01b46925..9449a2cc3 100644 --- a/src/lib/api.js +++ b/src/lib/api.js @@ -53,7 +53,7 @@ export const getFastestNode = (apiArr = []) => { ) ); return Promise.race(promiseArr); -}; +};∏ export const getValidator = async (validatorInfo, cancelToken) => { return await axios(`${consts.API_BASE}${consts.API.VALIDATOR}/${validatorInfo}`, cancelToken); From b13e277ae794cb15919df25d875680b18d4b8afb Mon Sep 17 00:00:00 2001 From: TranKhanhDuy Date: Fri, 8 Sep 2023 18:40:13 +0700 Subject: [PATCH 03/11] fix format --- src/components/Wallet/NFTToken/NFTToken.js | 7 ------ src/lib/api.js | 26 +++++++++++----------- 2 files changed, 13 insertions(+), 20 deletions(-) diff --git a/src/components/Wallet/NFTToken/NFTToken.js b/src/components/Wallet/NFTToken/NFTToken.js index 8f59d0e9f..fad18515f 100644 --- a/src/components/Wallet/NFTToken/NFTToken.js +++ b/src/components/Wallet/NFTToken/NFTToken.js @@ -78,13 +78,6 @@ const NFTToken = memo(({ account = "", address = "", isOw20 = false }) => { <> {isLargeScreen ? : } {totalPages > 0 && onPageChange(page)} />} - - [ Download{" "} - - CSV Export - {" "} - ] - ) : ( diff --git a/src/lib/api.js b/src/lib/api.js index 9449a2cc3..8ae98dc06 100644 --- a/src/lib/api.js +++ b/src/lib/api.js @@ -53,7 +53,7 @@ export const getFastestNode = (apiArr = []) => { ) ); return Promise.race(promiseArr); -};∏ +}; export const getValidator = async (validatorInfo, cancelToken) => { return await axios(`${consts.API_BASE}${consts.API.VALIDATOR}/${validatorInfo}`, cancelToken); @@ -80,39 +80,39 @@ export const getListTxs = cancelToken => { }; export const getListCwToken = (address, page) => { - return `${consts.API_BASE}${consts.API.OW20_SMART_CONTRACTS}/${address}?limit=${page?.limit || 1}&page_id=${page?.page_id || 1}`; -}; + return `${consts.API_BASE}${consts.API.OW20_SMART_CONTRACTS}/${address}?limit=${page?.limit || 1}&page_id=${page?.page_id || 1}` +} export const getListNFTToken = (address, page) => { return `https://api.testnet.scan.orai.io/v1/nft_transaction/${address}?limit=${page?.limit || 1}&page_id=${page?.page_id || 1}`; }; export const getListOWContract = (address, page) => { - return `${consts.API_BASE}${consts.API.OW20_SMART_CONTRACTS}${consts.API.OW20_CONTRACT}/${address}?limit=${page?.limit || 1}&page_id=${page?.page_id || 1}`; -}; + return `${consts.API_BASE}${consts.API.OW20_SMART_CONTRACTS}${consts.API.OW20_CONTRACT}/${address}?limit=${page?.limit || 1}&page_id=${page?.page_id || 1}` +} -export const getGeckoMarketBalance = async (ids = "", currency = "usd") => { +export const getGeckoMarketBalance = async (ids = '', currency = 'usd') => { // remove undefined - ids = ids.replace(new RegExp(",undefined", "gm"), ""); + ids = ids.replace(new RegExp("\,undefined", "gm"), ""); return ids ? await axios(`${consts.API_COINGECKO.PRICE(ids, currency)}`) : { data: {} }; }; -export const getImagesValidator = async address => { +export const getImagesValidator = async (address) => { return await axios.get(`${consts.API_BASE}${consts.API.GET_IMAGES_VALIDATORS}/${address}`); -}; +} export const getListRequest = (aiOracle, aiRequest) => { return axios.get(`${consts.LCD_API_BASE}${consts.LCD_API.WASM}/${aiOracle}/smart/${aiRequest}`); }; -export const uploadImagesValidator = async data => { +export const uploadImagesValidator = async (data) => { return await axios({ url: `${consts.API_BASE}${consts.API.UPLOAD_IMAGES_VALIDATORS}`, ...data }); }; -export const uploadSchema = async data => { +export const uploadSchema = async (data) => { return await axios({ url: `${consts.API_CONTRACT_DEPLOY}${consts.PATH_CONTRACT.UPLOAD_SCHEMA}`, ...data }); }; -export const axiosCall = async data => { +export const axiosCall = async (data) => { return await axios({ ...data }); -}; +}; \ No newline at end of file From b92befba1b1d0be51651a98c5449320bddcca5ca Mon Sep 17 00:00:00 2001 From: Hau Nguyen Van Date: Mon, 11 Sep 2023 09:53:34 +0700 Subject: [PATCH 04/11] remove field hardcode screen verified contract details --- .../ComponentContract/ComponentContract.js | 128 +++++++++--------- 1 file changed, 61 insertions(+), 67 deletions(-) diff --git a/src/containers/VerifiedContract/ComponentContract/ComponentContract.js b/src/containers/VerifiedContract/ComponentContract/ComponentContract.js index 401eb9862..94e64927d 100644 --- a/src/containers/VerifiedContract/ComponentContract/ComponentContract.js +++ b/src/containers/VerifiedContract/ComponentContract/ComponentContract.js @@ -49,14 +49,6 @@ export const ItemCodeContract = ({ contractName, compilerVersion, contractVerifi
{contractName ?? "-"}
- - -
Compiler Version:
- - -
{compilerVersion ?? "-"}
- - @@ -67,18 +59,10 @@ export const ItemCodeContract = ({ contractName, compilerVersion, contractVerifi -
Optimization Enabled:
- - -
Yes with 200 runs
- - - - -
Other Settings:
+
Compiler Version:
-
Default evmVersion, MIT license
+
{compilerVersion ?? "-"}
@@ -156,12 +140,11 @@ export const HandleItemContract = ({ schema, onHandle, handleText, onClickCopy, }, [schema]); useMemo(() => { - const obj = root && root.reduce( - (acc, _, index) => { - return { ...acc, [index + 1]: activeTab } - }, - {} - ); + const obj = + root && + root.reduce((acc, _, index) => { + return { ...acc, [index + 1]: activeTab }; + }, {}); setState(obj); }, [activeTab]); @@ -170,29 +153,36 @@ export const HandleItemContract = ({ schema, onHandle, handleText, onClickCopy, {root.map((msg, index) => { return (
-
setState({ - ...state, - [index + 1]: !state[index + 1] - })}> -
{index + 1}. {msg.fieldName}
+
+ setState({ + ...state, + [index + 1]: !state[index + 1], + }) + }> +
+ {index + 1}. {msg.fieldName} +
onClickCopy(msg.fieldName)}>
-
- setState({ - ...state, - [index + 1]: !state[index + 1] - }) - }> +
+ setState({ + ...state, + [index + 1]: !state[index + 1], + }) + }>
- {msg.fieldList.map((item, subInd) => + {msg.fieldList.map((item, subInd) => (
{item.isRequired ? "*" : ""}
- )} + ))}
-
- {json?.[index + 1] && } + {json?.[index + 1] && ( + + )} {/*
uint256
*/}
-
- ) +
+ ); })} -
+
); }; @@ -356,7 +350,7 @@ ItemContract.defaultProps = { leftHeader: undefined, label: "", msg: {}, - onClickCopy: () => { }, - onClickLinkChain: () => { }, - onClickDownArrow: () => { }, + onClickCopy: () => {}, + onClickLinkChain: () => {}, + onClickDownArrow: () => {}, }; From b21d1110c99efddb7ae3f854b39dd8c8bb4054b6 Mon Sep 17 00:00:00 2001 From: Hau Nguyen Van Date: Mon, 11 Sep 2023 11:48:16 +0700 Subject: [PATCH 05/11] remove text connect to web3 screen verified contract --- .../WriteContract/WriteContract.js | 63 ++++++++++++------- 1 file changed, 39 insertions(+), 24 deletions(-) diff --git a/src/containers/VerifiedContract/WriteContract/WriteContract.js b/src/containers/VerifiedContract/WriteContract/WriteContract.js index 8254d2080..2da559b59 100644 --- a/src/containers/VerifiedContract/WriteContract/WriteContract.js +++ b/src/containers/VerifiedContract/WriteContract/WriteContract.js @@ -4,8 +4,8 @@ import styles from "./WriteContract.module.scss"; import HeaderContract from "../HeaderContract"; import { useSelector } from "react-redux"; import { useDispatch } from "react-redux"; -import { HandleItemContract } from '../ComponentContract'; -import { onExecute } from '../ContractInteraction'; +import { HandleItemContract } from "../ComponentContract"; +import { onExecute } from "../ContractInteraction"; import copy from "copy-to-clipboard"; import { showAlert } from "src/store/modules/global"; import { useHistory } from "src/hooks"; @@ -13,28 +13,43 @@ import { useHistory } from "src/hooks"; const cx = classNames.bind(styles); const WriteContract = memo(({ data }) => { - const { address } = useSelector(state => state.wallet); - const history = useHistory(); - const [activeTab, setActiveTab] = useState(true); - const activeThemeId = useSelector(state => state.activeThemeId); - const dispatch = useDispatch(); - const onClickCopy = (msg) => { - copy(JSON.stringify(msg)) - dispatch( - showAlert({ - show: true, - message: "Copied", - autoHideDuration: 1500, - }) - ); - } - return ( -
- } onClickLink={() => address && history.push(`/account/${address}`)} label={address ? "Connect to web3" : "Connect to wallet"} activeTab={activeTab} setActiveTab={setActiveTab} /> -
- -
- ); + const { address } = useSelector(state => state.wallet); + const history = useHistory(); + const [activeTab, setActiveTab] = useState(true); + const activeThemeId = useSelector(state => state.activeThemeId); + const dispatch = useDispatch(); + const onClickCopy = msg => { + copy(JSON.stringify(msg)); + dispatch( + showAlert({ + show: true, + message: "Copied", + autoHideDuration: 1500, + }) + ); + }; + return ( +
+ } + onClickLink={() => address && history.push(`/account/${address}`)} + label={address ? "" : "Connect to wallet"} + activeTab={activeTab} + setActiveTab={setActiveTab} + /> +
+ +
+ ); }); export default WriteContract; From cb01e88bc9e99ba8fab24ea39d13df7a78d3e8dc Mon Sep 17 00:00:00 2001 From: Pham Tu Date: Mon, 11 Sep 2023 14:22:08 +0700 Subject: [PATCH 06/11] fixed displaying --- src/components/SmartContract/MoreInfo.js | 8 +-- .../ComponentContract/ComponentContract.js | 3 +- .../ComponentContract.module.scss | 6 +++ .../ReadContract/ReadContract.js | 53 +++++++++++-------- .../WriteContract/WriteContract.js | 4 +- 5 files changed, 45 insertions(+), 29 deletions(-) diff --git a/src/components/SmartContract/MoreInfo.js b/src/components/SmartContract/MoreInfo.js index 41a0e36d9..cd9bd496f 100644 --- a/src/components/SmartContract/MoreInfo.js +++ b/src/components/SmartContract/MoreInfo.js @@ -1,8 +1,8 @@ import React from "react"; import PropTypes from "prop-types"; import cn from "classnames/bind"; -import {NavLink} from "react-router-dom"; -import {isNil} from "lodash"; +import { NavLink } from "react-router-dom"; +import { isNil } from "lodash"; import Grid from "@material-ui/core/Grid"; import Skeleton from "@material-ui/lab/Skeleton"; import InfoRow from "src/components/common/InfoRow"; @@ -11,7 +11,7 @@ import consts from "src/constants/consts"; const cx = cn.bind(styles); -const MoreInfo = ({data}) => { +const MoreInfo = ({ data }) => { return (
@@ -57,7 +57,7 @@ const MoreInfo = ({data}) => {
Label
-
{isNil(data?.label) ? "-" : data?.label}
+
{isNil(data?.contract_name) ? "-" : data?.contract_name}
diff --git a/src/containers/VerifiedContract/ComponentContract/ComponentContract.js b/src/containers/VerifiedContract/ComponentContract/ComponentContract.js index 94e64927d..28689f502 100644 --- a/src/containers/VerifiedContract/ComponentContract/ComponentContract.js +++ b/src/containers/VerifiedContract/ComponentContract/ComponentContract.js @@ -183,7 +183,7 @@ export const HandleItemContract = ({ schema, onHandle, handleText, onClickCopy,
{msg.fieldList.map((item, subInd) => ( -
+
{item.isRequired ? "*" : ""} { @@ -202,6 +202,7 @@ export const HandleItemContract = ({ schema, onHandle, handleText, onClickCopy, ))}