Skip to content

Commit

Permalink
feat: token
Browse files Browse the repository at this point in the history
  • Loading branch information
Peterbjx committed Apr 27, 2024
1 parent b4a7815 commit 18499c7
Show file tree
Hide file tree
Showing 28 changed files with 318 additions and 407 deletions.
2 changes: 1 addition & 1 deletion .env.example
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
NEXT_PUBLIC_NETWORK_TYPE = 'TESTNET'
NEXT_PUBLIC_SYMBOL = 'ELF'
NEXT_PUBLIC_API_URL=http://localhost:4000
NEXT_PUBLIC_API_URL=https://aelfscan.io
NEXT_PUBLIC_REMOTE_URL=http://localhost:3001
2 changes: 1 addition & 1 deletion .env.test
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
NEXT_PUBLIC_NETWORK_TYPE = 'TESTNET'
NEXT_PUBLIC_CHAIN_ID = 'AELF'
NEXT_PUBLIC_SYMBOL = 'ELF'
NEXT_PUBLIC_API_URL = http://192.168.10.179:8001
NEXT_PUBLIC_API_URL = https://aelfscan.io
NEXT_PUBLIC_REMOTE_URL = http://localhost:3001
NEXT_PUBLIC_CMS_URL = http://192.168.66.62:3200
2 changes: 1 addition & 1 deletion next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ const nextConfig = {
},
{
source: '/api/:path*',
destination: 'http://192.168.10.179:8001/api/:path*',
destination: 'https://aelfscan.io/api/:path*',
// permanent: false,
basePath: false,
},
Expand Down
15 changes: 10 additions & 5 deletions src/_api/fetchBlocks.ts
Original file line number Diff line number Diff line change
@@ -1,42 +1,47 @@
import request from '@_api';
import { IBlocksDetailData, IBlocksDetailRequestParams, IBlocksRequestParams, TChainID } from './type';

const defaultTokenList = {
total: 0,
blocks: [],
};

export async function fetchBlocks(params: IBlocksRequestParams) {
const result = await request.block.getBlockList({
params: params,
});
const { data } = result;
const data = result?.data || defaultTokenList;
return data;
}

export async function fetchLatestBlocksList(params: { chainId: TChainID }) {
const result = await request.block.getLatestBlocksList({
params: params,
});
const { data } = result;
const data = result?.data || defaultTokenList;
return data;
}

export async function fetchServerBlocks(params: IBlocksRequestParams) {
const result = await request.block.getServerBlockList({
params: params,
});
const { data } = result;
const data = result?.data || defaultTokenList;
return data;
}

export async function fetchServerBlocksDetail(params: IBlocksDetailRequestParams): Promise<IBlocksDetailData> {
const result = await request.block.getServerBlockDetail({
params: params,
});
const { data } = result;
const data = result?.data;
return data;
}

export async function fetchBlocksDetail(params: IBlocksDetailRequestParams): Promise<IBlocksDetailData> {
const result = await request.block.getBlockDetail({
params: params,
});
const { data } = result;
const data = result?.data || {};
return data;
}
3 changes: 1 addition & 2 deletions src/_api/fetchCMS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ export async function fetchCMS() {
return child.label === 'Blocks';
});
}
// return item.headerMenu_id?.path === 'blockchain' || item.headerMenu_id?.path === '/tokens';
return item.headerMenu_id?.path === 'blockchain';
return item.headerMenu_id?.path === 'blockchain' || item.headerMenu_id?.path === '/tokens';
});
data.headerMenuList = headerMenuList;
return data;
Expand Down
45 changes: 45 additions & 0 deletions src/_api/fetchTokens.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import request from '@_api';
import {
ITokenHoldersRequestParams,
ITokenTransfersRequestParams,
ITokenDetailRequestParams,
TTokenListRequestParams,
} from './type';
import { IHolderTableData, ITokenDetail, ITokenList, ITransferTableData } from '@app/[chain]/token/[tokenSymbol]/type';

export async function fetchTokenList(params: TTokenListRequestParams): Promise<ITokenList> {
const result = await request.tx.getTransactionDetail({
params: params,
});
const data = result?.data;
return data;
}
export async function fetchServerTokenList(params: TTokenListRequestParams): Promise<ITokenList> {
const result = await request.tx.getTransactionDetail({
params: params,
});
const data = result?.data;
return data;
}
export async function fetchTokenDetail(params: ITokenDetailRequestParams): Promise<ITokenDetail> {
const result = await request.tx.getTransactionDetail({
params: params,
});
const data = result?.data;
return data;
}
export async function fetchTokenDetailTransfers(params: ITokenTransfersRequestParams): Promise<ITransferTableData> {
const result = await request.tx.getTransactionDetail({
params: params,
});
const data = result?.data;
return data;
}

export async function fetchTokenDetailHolders(params: ITokenHoldersRequestParams): Promise<IHolderTableData> {
const result = await request.tx.getTransactionDetail({
params: params,
});
const data = result?.data;
return data;
}
2 changes: 1 addition & 1 deletion src/_api/fetchTransactions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@ export async function fetchTransactionDetails(
const result = await request.tx.getTransactionDetail({
params: params,
});
const { data } = result;
const data = result?.data;
return data;
}
8 changes: 8 additions & 0 deletions src/_api/list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,14 @@ const Transaction_API_List = {
getTransactionDetail: `${SERVER_BASE_API}/app/blockchain/transactionDetail`,
};

const Token_API_List = {
getTokenList: `api/app/token/list`,
getServerTokenList: `api/app/token/list`,
getTokenDetail: `${SERVER_BASE_API}/app/token/detail`,
getTokenDetailTransfers: `api/app/token/transfers`,
getTokenDetailHolders: `api/app/token/holders`,
};

const Common_API_List = {
getPrice: '',
};
Expand Down
29 changes: 29 additions & 0 deletions src/_api/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ export interface ITransactionValues {
export interface ITransactionDetailData {
transactionId: string;
status: TransactionStatus;
confirmed: boolean;
blockHeight: string;
blockConfirmations: number;
timestamp: number;
Expand Down Expand Up @@ -187,3 +188,31 @@ export interface ITransactionDetailData {
export interface ITransactionDetailDataList {
list: ITransactionDetailData[];
}

export interface ITokenHoldersRequestParams {
chainId: TChainID;
symbol: string;
skipCount: number;
maxResultCount: number;
}

export interface ITokenTransfersRequestParams {
chainId: TChainID;
skipCount: number;
maxResultCount: number;
symbol: string;
search: string;
}

export interface ITokenDetailRequestParams {
chainId: TChainID;
symbol: string;
}

export interface TTokenListRequestParams {
chainId: TChainID;
skipCount: number;
maxResultCount: number;
sort: number;
sortBy: number;
}
7 changes: 7 additions & 0 deletions src/_components/DollarCurrency/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export default function DollarCurrency({ price }: { price: string }) {
return (
<div className="ml-1 flex h-6 cursor-pointer items-center rounded bg-ECEEF2 px-4">
<span className="mr-1">${price}</span>
</div>
);
}
12 changes: 8 additions & 4 deletions src/_components/LogsContainer/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,24 @@ import Link from 'next/link';
import addressFormat from '@_utils/urlUtils';
import Copy from '@_components/Copy';
import LogItems from './logItems';
import { useParams } from 'next/navigation';
function LogsContainer({ Logs = [] }: { Logs: ILogsProps[] }) {
const { chain } = useParams();
return (
<div className="log-container">
<div className="log-list">
{Logs.map((item, index) => (
<div key={item.address} className="">
<div key={item.contractInfo?.address} className="">
<DetailContainer
infoList={[
{
label: 'Address',
value: (
<div>
<Link href={`/address${addressFormat(item.address)}`}>{addressFormat(item.address)}</Link>
<Copy value={addressFormat(item.address)} />
<Link href={`/address${addressFormat(item.contractInfo?.address, chain as string)}`}>
{addressFormat(item.contractInfo?.address, chain as string)}
</Link>
{item.contractInfo?.address && <Copy value={addressFormat(item.contractInfo?.address)} />}
</div>
),
},
Expand All @@ -41,7 +45,7 @@ function LogsContainer({ Logs = [] }: { Logs: ILogsProps[] }) {
<DetailContainer
infoList={[
{
label: 'divider' + item.address,
label: 'divider' + item.contractInfo?.address,
value: 'divider',
},
]}
Expand Down
4 changes: 4 additions & 0 deletions src/_utils/formatter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,7 @@ export const divDecimals = (num: number | string, decimals = 8e10) => {
const bigNumber = new BigNumber(num);
return bigNumber.dividedBy(decimals || 8e10).toNumber();
};

export const getPageNumber = (page: number, pageSize: number): number => {
return Math.floor((page - 1) * pageSize);
};
6 changes: 3 additions & 3 deletions src/app/[chain]/block/[hash]/_components/baseinfo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import Copy from '@_components/Copy';
import { useRouter } from 'next/navigation';
import JumpButton, { JumpTypes } from '@_components/JumpButton';
import SizeBytes from '@_components/SizeBytes';
import DollarCurrencyRate from '@_components/DollarCurrencyRate';
import DollarCurrency from '@_components/DollarCurrency';
import addressFormat from '@_utils/urlUtils';
import { StatusEnum } from '@_types/status';
import { useParams } from 'next/navigation';
Expand Down Expand Up @@ -108,7 +108,7 @@ export default function BaseInfo({ data }) {
value: (
<div className="flex items-center text-xs leading-5">
<span className="mr-1">{addSymbol(divDecimals(data.reward.elfReward))}</span>
{data.reward.usdReward && <DollarCurrencyRate price={data.reward.usdReward} />}
{data.reward.usdReward && <DollarCurrency price={data.reward.usdReward} />}
</div>
),
},
Expand All @@ -127,7 +127,7 @@ export default function BaseInfo({ data }) {
value: (
<div className="flex items-center text-xs leading-5">
<span className="mr-1">{addSymbol(divDecimals(data.burntFee.elfFee))}</span>
{data.burntFee.usdFee && <DollarCurrencyRate price={data.burntFee.usdFee} />}
{data.burntFee.usdFee && <DollarCurrency price={data.burntFee.usdFee} />}
</div>
),
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@ import ContractToken from '@_components/ContractToken';
import { thousandsNumber } from '@_utils/formatter';
import { ColumnsType } from 'antd/es/table';
import { IHolderItem } from '../../type';
import { AddressType } from '@_types/common';

export default function getColumns({ currentPage, pageSize }): ColumnsType<IHolderItem> {
export default function getColumns({ currentPage, pageSize, chain }): ColumnsType<IHolderItem> {
return [
{
title: '#',
Expand All @@ -18,9 +17,9 @@ export default function getColumns({ currentPage, pageSize }): ColumnsType<IHold
width: 432,
dataIndex: 'address',
key: 'address',
render: (text) => {
const { address } = JSON.parse(text);
return <ContractToken address={address} type={AddressType.address} chainId="AELf" />;
render: (data) => {
const { address, addressType } = data;
return <ContractToken address={address} type={addressType} chainId={chain} />;
},
},
{
Expand Down
67 changes: 48 additions & 19 deletions src/app/[chain]/token/[tokenSymbol]/_components/Holders/index.tsx
Original file line number Diff line number Diff line change
@@ -1,30 +1,58 @@
'use client';
import Table from '@_components/Table';
import useTableData from '@_hooks/useTable';
import { useMobileContext } from '@app/pageProvider';
import { useMemo } from 'react';
import { fetchHoldersData } from '../../mock';
import { IHolderItem, IHolderTableData, ITokenSearchProps } from '../../type';
import { useCallback, useEffect, useMemo, useState } from 'react';
import { IHolderItem, ITokenSearchProps } from '../../type';
import getColumns from './columns';
import useResponsive, { useMobileAll } from '@_hooks/useResponsive';
import { useMobileAll } from '@_hooks/useResponsive';
import { fetchTokenDetailHolders } from '@_api/fetchTokens';
import { useParams } from 'next/navigation';
import { TChainID } from '@_api/type';
import { getPageNumber } from '@_utils/formatter';
import { pageSizeOption } from '@_utils/contant';

interface HoldersProps extends ITokenSearchProps {
SSRData: IHolderTableData;
}
interface HoldersProps extends ITokenSearchProps {}

export default function Holders({ SSRData, searchType, search, onSearchChange, onSearchInputChange }: HoldersProps) {
export default function Holders({ search, onSearchChange, onSearchInputChange }: HoldersProps) {
const { isMobile } = useMobileAll();

const { loading, total, data, currentPage, pageSize, pageChange, pageSizeChange } = useTableData<
IHolderItem,
IHolderTableData
>({
SSRData,
defaultPageSize: 50,
fetchData: fetchHoldersData,
});
const { chain, tokenSymbol } = useParams();

const [currentPage, setCurrentPage] = useState<number>(1);
const [pageSize, setPageSize] = useState<number>(50);
const [loading, setLoading] = useState<boolean>(false);
const [total, setTotal] = useState<number>(0);
const [data, setData] = useState<IHolderItem[]>();
const fetchData = useCallback(async () => {
setLoading(true);
try {
const params = {
chainId: chain as TChainID,
symbol: tokenSymbol as string,
skipCount: getPageNumber(currentPage, pageSize),
maxResultCount: pageSize,
};
const res = await fetchTokenDetailHolders(params);
setData(res.list);
setTotal(res.total);
} catch (error) {
setLoading(false);
}
}, [chain, tokenSymbol, currentPage, pageSize]);

const pageChange = async (page: number) => {
setCurrentPage(page);
};

const pageSizeChange = async (size) => {
setPageSize(size);
setCurrentPage(1);
};

useEffect(() => {
fetchData();
}, [fetchData]);

const columns = useMemo(() => getColumns({ currentPage, pageSize }), [currentPage, pageSize]);
const columns = useMemo(() => getColumns({ currentPage, pageSize, chain }), [currentPage, pageSize, chain]);
const title = useMemo(() => `A total of ${total} ${total <= 1 ? 'token' : 'tokens'} found`, [total]);

return (
Expand All @@ -46,6 +74,7 @@ export default function Holders({ SSRData, searchType, search, onSearchChange, o
loading={loading}
dataSource={data}
columns={columns}
options={pageSizeOption}
isMobile={isMobile}
rowKey="index"
total={total}
Expand Down
Loading

0 comments on commit 18499c7

Please sign in to comment.