Skip to content

Commit

Permalink
feat(app/home/leaderboard): integrate with api
Browse files Browse the repository at this point in the history
  • Loading branch information
KacperKoza343 committed Aug 21, 2024
1 parent 28eaeb9 commit ab87be1
Show file tree
Hide file tree
Showing 14 changed files with 585 additions and 642 deletions.
639 changes: 0 additions & 639 deletions packages/apps/dashboard/ui-2024/src/components/Home/Leaderboard.tsx

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import TableContainer from '@mui/material/TableContainer';
import Paper from '@mui/material/Paper';
import SimpleBar from 'simplebar-react';
import { Table } from '@components/Home/Leaderboard/components/Table/Table';
import { SelectNetwork } from '@components/Home/Leaderboard/components/SelectNetwork';
import { useLeaderboardDetails } from '@services/api/use-leaderboard-details';
import Loader from '@components/Loader';
import Stack from '@mui/material/Stack';
import { handleErrorMessage } from '@services/handle-error-message';

const Leaderboard = () => {
const { data, status, error } = useLeaderboardDetails();

if (status === 'pending') {
return <Loader height="30vh" />;
}

if (status === 'error') {
return (
<Stack sx={{ paddingTop: '2rem' }}>{handleErrorMessage(error)}</Stack>
);
}

return (
<>
<TableContainer
component={Paper}
sx={{ padding: '32px', marginTop: '30px' }}
>
<div className="mobile-select">
<SelectNetwork />
</div>
<SimpleBar>
<Table data={data} />
</SimpleBar>
</TableContainer>
</>
);
};

export default Leaderboard;
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import recording from '@assets/recording.png';
import reputation from '@assets/reputation.png';
import exchange from '@assets/exchange.png';
import human from '@assets/human.png';

export const EntityIcon: React.FC<{ role: string }> = ({ role }) => {
let src = '';
switch (role) {
case 'Job Launcher':
return (
<div className="icon-table">
<span>JL</span>
</div>
);
case 'Recording Oracle':
src = recording;
break;
case 'Reputation Oracle':
src = reputation;
break;
case 'Exchange Oracle':
src = exchange;
break;
case 'HUMAN App':
src = human;
break;
default:
src = human;
break;
}

return (
<div className="icon-table">
<img src={src} alt="logo" />
</div>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
export const ReputationLabel: React.FC<{ reputation: string }> = ({
reputation,
}) => {
switch (reputation) {
case 'High':
return (
<div className="reputation-table reputation-table-high">
{reputation}
</div>
);
case 'Medium':
return (
<div className="reputation-table reputation-table-medium">
{reputation}
</div>
);
case 'Low':
return (
<div className="reputation-table reputation-table-low">
{reputation}
</div>
);
case 'Coming soon':
return (
<div className="reputation-table reputation-table-soon">
{reputation}
</div>
);
default:
return (
<div className="reputation-table reputation-table-soon">
Coming soon
</div>
);
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import Select, { SelectChangeEvent } from '@mui/material/Select';
import FormControl from '@mui/material/FormControl';
import InputLabel from '@mui/material/InputLabel';
import MenuItem from '@mui/material/MenuItem';
import HumanIcon from '@components/Icons/HumanIcon';
import {
leaderboardSearchSelectConfig,
useLeaderboardSearch,
} from '@utils/hooks/use-leaderboard-search';
import { NetworkIcon } from '@components/NetworkIcon';

export const SelectNetwork = () => {
const {
setChainId,
filterParams: { chainId },
} = useLeaderboardSearch();
const handleChange = (event: SelectChangeEvent<number>) => {
const value = event.target.value;
if (typeof value === 'number') {
setChainId(value);
}
};

return (
<FormControl fullWidth size="small">
<InputLabel id="network-select-label">By Network</InputLabel>
<Select<number>
labelId="network-select-label"
id="network-select"
value={chainId}
label="By Network"
onChange={handleChange}
>
{leaderboardSearchSelectConfig.map((selectItem) => {
if ('allNetworksId' in selectItem) {
return (
<MenuItem className="select-item" value={-1}>
<HumanIcon />
All Networks
</MenuItem>
);
}

return (
<MenuItem className="select-item" value={selectItem.id}>
<NetworkIcon chainId={selectItem.id} />
{selectItem.name}
</MenuItem>
);
})}
</Select>
</FormControl>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
import React, { useMemo, useState } from 'react';
import TableRow from '@mui/material/TableRow';
import TableCell, { tableCellClasses } from '@mui/material/TableCell';
import MuiTable from '@mui/material/Table';
import TableBody from '@mui/material/TableBody';
import Grid from '@mui/material/Grid';
import AbbreviateClipboard from '@components/SearchResults/AbbreviateClipboard';
import { useNavigate } from 'react-router-dom';
import { ReputationLabel } from '@components/Home/Leaderboard/components/ReputationLabel';
import { EntityIcon } from '@components/Home/Leaderboard/components/EntityIcon';
import { TableHead } from '@components/Home/Leaderboard/components/Table/TableHead';
import { LeaderBoardData } from '@services/api/use-leaderboard-details';
import {
getComparator,
Order,
SortableFieldsInLeaderBoardData,
stableSort,
} from '@components/Home/Leaderboard/components/Table/sorting';
import { useLeaderboardSearch } from '@utils/hooks/use-leaderboard-search';
import { getNetwork } from '@utils/config/networks';
import { NetworkIcon } from '@components/NetworkIcon';
import { colorPalette } from '@assets/styles/color-palette';

export const Table = ({ data }: { data: LeaderBoardData }) => {
const navigate = useNavigate();
const {
filterParams: { chainId },
} = useLeaderboardSearch();
const [order, setOrder] = useState<Order>('asc');
const [orderBy, setOrderBy] =
useState<SortableFieldsInLeaderBoardData>('role');

const handleRequestSort = (
_event: React.MouseEvent<unknown>,
property: SortableFieldsInLeaderBoardData
) => {
const isAsc = orderBy === property && order === 'asc';
setOrder(isAsc ? 'desc' : 'asc');
setOrderBy(property);
};

const visibleRows = useMemo(() => {
let filteredRows = data;
if (chainId !== -1) {
filteredRows = data.filter((elem) => elem.chainId === chainId);
}

return stableSort(filteredRows, getComparator(order, orderBy));
}, [chainId, data, order, orderBy]);

return (
<MuiTable
sx={{
minWidth: 650,
[`& .${tableCellClasses.root}`]: {
borderBottom: 'none',
},
}}
aria-label="simple table"
>
<TableHead
onRequestSort={handleRequestSort}
order={order}
orderBy={orderBy}
rowCount={data.length}
/>
<TableBody>
{visibleRows.map((row) => (
<TableRow
onClick={() => navigate(`/search/${row.chainId}/${row.address}`)}
key={row.address}
className="home-page-table-row"
sx={{
':hover': {
backgroundColor: colorPalette.overlay.light,
},
}}
>
<TableCell>
<EntityIcon role={row.role} />
{row.role}
</TableCell>
<TableCell>
<Grid
container
wrap="nowrap"
alignItems="center"
sx={{ gap: '18px' }}
>
<AbbreviateClipboard value={row.address} />
</Grid>
</TableCell>
<TableCell>{row.amountStaked} HMT</TableCell>
<TableCell>
<Grid
container
wrap="nowrap"
alignItems="center"
justifyContent="center"
>
<NetworkIcon chainId={row.chainId} />
{getNetwork(row.chainId)?.name}
</Grid>
</TableCell>
<TableCell>
<ReputationLabel reputation={row.reputation} />
</TableCell>
<TableCell>{row.fee}%</TableCell>
</TableRow>
))}
</TableBody>
</MuiTable>
);
};
Loading

0 comments on commit ab87be1

Please sign in to comment.