Skip to content

Commit

Permalink
Update homepage (#169)
Browse files Browse the repository at this point in the history
* update homepage

* added TODOs

* fix next config

* update components

* implement burn

* implement renewals

* fix

* e2e tests for the home page

* fixes

* fix build error

* fix purchase history

---------

Co-authored-by: Sergej <[email protected]>
  • Loading branch information
cuteolaf and Szegoo authored Jun 25, 2024
1 parent 1c477d9 commit e284313
Show file tree
Hide file tree
Showing 15 changed files with 602 additions and 124 deletions.
47 changes: 47 additions & 0 deletions cypress/e2e/home.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import 'cypress';

describe('E2E tests for the index page', () => {
beforeEach(() => {
cy.visit('/');
// Initializing the API connections and fetching data
cy.get('[data-cy="loading"]').should('exist');
// Fetching complete
cy.get('[data-cy="loading"]', { timeout: 60 * 1000 }).should('not.exist');
});

it('Test UI elements on the home page', () => {
cy.get('[data-cy="upcoming-burn"]').should('exist');
cy.get('[data-cy="previous-burn"]').should('exist');
cy.get('[data-cy="total-burn"]').should('exist');
cy.get('[data-cy="cores-sold"]').should('exist');
cy.get('[data-cy="cores-on-sale"]').should('exist');
cy.get('[data-cy="current-price"]').should('exist');
cy.get('[data-cy="renewals"]').should('exist');
cy.get('[data-cy="renewal-cost"]').should('exist');
cy.get('[data-cy="price-increase"]').should('exist');

// Buttons
cy.get('[data-cy="btn-purchase-a-core"]').should('exist');
cy.get('[data-cy="btn-manage-regions"]').should('exist');
cy.get('[data-cy="btn-manage-paras"]').should('exist');
cy.get('[data-cy="btn-track-consumption"]').should('exist');

// Purchase history table
cy.get('[data-cy="purchase-history-table"]').should('exist');
});

it('Test button: Purchase a core', () => {
cy.get('[data-cy="btn-purchase-a-core"]').click();
cy.url({ timeout: 60 * 1000 }).should('contain', 'purchase');
});

it('Test button: Manage your regions', () => {
cy.get('[data-cy="btn-manage-regions"]').click();
cy.url({ timeout: 60 * 1000 }).should('contain', 'regions');
});

it('Test button: Parachain Dashboard', () => {
cy.get('[data-cy="btn-manage-paras"]').click();
cy.url({ timeout: 60 * 1000 }).should('contain', 'paras');
});
});
2 changes: 1 addition & 1 deletion cypress/e2e/wallet.cy.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import '@chainsafe/cypress-polkadot-wallet';
import { encodeAddress } from '@polkadot/util-crypto';
import '@chainsafe/cypress-polkadot-wallet';
import 'cypress-wait-until';

const ALICE = '5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY';
Expand Down
2 changes: 0 additions & 2 deletions next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ const nextConfig = {
WS_REGIONX_CHAIN: process.env.WS_REGIONX_CHAIN || '',
WS_ROCOCO_RELAY_CHAIN: process.env.WS_ROCOCO_RELAY_CHAIN,
WS_KUSAMA_RELAY_CHAIN: process.env.WS_KUSAMA_RELAY_CHAIN,
KUSAMA_CORETIME_API: process.env.KUSAMA_CORETIME_API,
ROCOCO_CORETIME_API: process.env.ROCOCO_CORETIME_API,
EXPERIMENTAL: process.env.EXPERIMENTAL,
},
};
Expand Down
22 changes: 22 additions & 0 deletions src/apis/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { SUBSCAN_CORETIME_API } from '@/consts';
import { NetworkType } from '@/models';

export const fetchPurchaseHistoryData = async (
network: NetworkType,
regionBegin: number,
page: number,
row: number
) => {
const res = await fetch(
`${SUBSCAN_CORETIME_API[network]}/api/scan/broker/purchased`,
{
method: 'POST',
body: JSON.stringify({
region_begin: regionBegin,
row,
page,
}),
}
);
return res;
};
2 changes: 1 addition & 1 deletion src/components/Elements/Address/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export const Address = ({
};

return (
<Stack direction='row' gap='0.5rem' alignItems='center'>
<Stack direction='row' gap='0.5rem' alignItems='center' width='fit-content'>
<IconButton onClick={onCopy}>
<Identicon value={value} theme='polkadot' size={size} />
</IconButton>
Expand Down
18 changes: 15 additions & 3 deletions src/components/Elements/Link/index.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,29 @@
import { Button } from '@mui/material';
import { Box, useTheme } from '@mui/material';
import React from 'react';

interface LinkProps {
href: string;
target?: string;
children: React.ReactNode;
}

export const Link = ({ href, target = '_blank', children }: LinkProps) => {
const theme = useTheme();

const onClick = () => {
if (!href) return;
window.open(href, target);
};

return <Button onClick={onClick}>{children}</Button>;
return (
<Box
onClick={onClick}
sx={{
width: 'fit-content',
cursor: 'pointer',
color: theme.palette.primary.main,
}}
>
{children}
</Box>
);
};
62 changes: 36 additions & 26 deletions src/components/Tables/PurchaseHistoryTable/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -77,15 +77,15 @@ export const PurchaseHistoryTable = ({ data }: PurchaseHistoryTableProps) => {
index
) => (
<StyledTableRow key={index}>
<StyledTableCell>
<StyledTableCell align='center'>
<Link
href={`${SUBSCAN_URL[network]}/extrinsic/${extrinsic_index}`}
target='_blank'
>
{extrinsic_index}
</Link>
</StyledTableCell>
<StyledTableCell>
<StyledTableCell align='center'>
<Link
href={`${SUBSCAN_URL[network]}/account/${address}`}
target='_blank'
Expand All @@ -98,12 +98,12 @@ export const PurchaseHistoryTable = ({ data }: PurchaseHistoryTableProps) => {
/>
</Link>
</StyledTableCell>
<StyledTableCell align='right'>{core}</StyledTableCell>
<StyledTableCell align='right'>
<StyledTableCell align='center'>{core}</StyledTableCell>
<StyledTableCell align='center'>
{planckBnToUnit(price.toString(), decimals)}
</StyledTableCell>
<StyledTableCell>{type}</StyledTableCell>
<StyledTableCell>
<StyledTableCell align='center'>{type}</StyledTableCell>
<StyledTableCell align='center'>
{timeAgo.format(timestamp * 1000, 'round-minute')}
</StyledTableCell>
</StyledTableRow>
Expand All @@ -113,27 +113,37 @@ export const PurchaseHistoryTable = ({ data }: PurchaseHistoryTableProps) => {
</Table>
</TableContainer>
<Stack alignItems='center'>
<TableFooter sx={{ alignItems: 'center' }}>
<TableRow>
<TablePagination
rowsPerPageOptions={[10, 25, { label: 'All', value: -1 }]}
colSpan={3}
count={data.length}
rowsPerPage={rowsPerPage}
page={page}
slotProps={{
select: {
inputProps: {
'aria-label': 'rows per page',
<Table>
<TableFooter>
<TableRow>
<TablePagination
rowsPerPageOptions={[10, 25, { label: 'All', value: -1 }]}
colSpan={3}
count={data.length}
rowsPerPage={rowsPerPage}
page={page}
slotProps={{
select: {
inputProps: {
'aria-label': 'rows per page',
},
native: true,
},
}}
sx={{
'.MuiTablePagination-spacer': {
flex: '0 0 0',
},
'.MuiTablePagination-toolbar': {
justifyContent: 'center',
},
native: true,
},
}}
onPageChange={handleChangePage}
onRowsPerPageChange={handleChangeRowsPerPage}
/>
</TableRow>
</TableFooter>
}}
onPageChange={handleChangePage}
onRowsPerPageChange={handleChangeRowsPerPage}
/>
</TableRow>
</TableFooter>
</Table>
</Stack>
</Stack>
);
Expand Down
2 changes: 1 addition & 1 deletion src/hooks/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
export * from './parasInfo';
export * from './purchaseHistory';
export * from './renewableParas';
export * from './sale';
74 changes: 74 additions & 0 deletions src/hooks/sale/burnInfo.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import { useEffect, useState } from 'react';

import { sleep } from '@/utils/functions';

import { fetchPurchaseHistoryData } from '@/apis';
import { NetworkType, PurchaseHistoryResponse } from '@/models';

import { useSaleHistory } from './saleHistory';

export const useBurnInfo = (network: NetworkType) => {
const [totalBurn, setTotalBurn] = useState(0);
const [loading, setLoading] = useState(false);
const [currentBurn, setCurrentBurn] = useState(0);
const [prevBurn, setPrevBurn] = useState(0);

const saleHistory = useSaleHistory(network, 0, 100);

useEffect(() => {
const asyncFetchData = async () => {
setLoading(false);
setTotalBurn(0);
setCurrentBurn(0);
setPrevBurn(0);

if (saleHistory.isError) {
return;
}
if (saleHistory.loading) {
setLoading(true);
return;
}

const regionBegins = saleHistory.data
.map((item) => item.region_begin)
.sort((a, b) => b - a);

await sleep(1000); // 5 req/s limit in free plan

let total = 0;
for (let idx = 0; idx < regionBegins.length; ++idx) {
const regionBegin = regionBegins[idx];

const res = await fetchPurchaseHistoryData(
network,
regionBegin,
0,
1000
);
if (res.status !== 200) {
idx--;
continue;
}

const { message, data } = await res.json();
if (message !== 'Success') continue;

const { list } = data as PurchaseHistoryResponse;
const burn = list
? list.reduce((acc, { price }) => acc + parseInt(price), 0)
: 0;
total += burn;

if (idx === 0) setCurrentBurn(burn);
else if (idx === 1) setPrevBurn(burn);

await sleep(500);
}
setTotalBurn(total);
setLoading(false);
};
asyncFetchData();
}, [network, saleHistory.loading, saleHistory.isError]);
return { loading, totalBurn, currentBurn, prevBurn };
};
3 changes: 3 additions & 0 deletions src/hooks/sale/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export * from './burnInfo';
export * from './purchaseHistory';
export * from './saleHistory';
47 changes: 22 additions & 25 deletions src/hooks/purchaseHistory.ts → src/hooks/sale/purchaseHistory.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useEffect, useState } from 'react';

import { SUBSCAN_CORETIME_API } from '@/consts';
import { fetchPurchaseHistoryData } from '@/apis';
import {
NetworkType,
PurchaseHistoryItem,
Expand All @@ -19,35 +19,31 @@ export const usePurchaseHistory = (

useEffect(() => {
const asyncFetchData = async () => {
setLoading(true);
setData([]);
setError(false);
setLoading(false);

if (regionBegin === 0) return;

try {
const res = await fetch(
`${SUBSCAN_CORETIME_API[network]}/api/scan/broker/purchased`,
{
method: 'POST',
body: JSON.stringify({
region_begin: regionBegin,
row,
page,
}),
}
setLoading(true);
const res = await fetchPurchaseHistoryData(
network,
regionBegin,
page,
row
);
if (res.status !== 200) {
setError(true);
} else {
const jsonData = await res.json();
if (jsonData.message !== 'Success') {
const { message, data } = await res.json();
if (message !== 'Success') {
setError(true);
setData([]);
} else {
if (jsonData.data.count == 0) {
setData([]);
setLoading(false);
return;
}
const data = jsonData.data as PurchaseHistoryResponse;
const { list } = data as PurchaseHistoryResponse;

setData(
data.list.map(
list.map(
({
account: { address },
core,
Expand All @@ -61,17 +57,18 @@ export const usePurchaseHistory = (
core,
extrinsic_index,
timestamp: block_timestamp,
price,
price: parseInt(price),
type: purchased_type,
}) as PurchaseHistoryItem
} as PurchaseHistoryItem)
)
);
}
}
} catch {
setError(true);
} finally {
setLoading(false);
}
setLoading(false);
};
asyncFetchData();
}, [network, regionBegin, page, row]);
Expand Down
Loading

0 comments on commit e284313

Please sign in to comment.