better info response types

This commit is contained in:
Ste Vaidis 2022-12-11 21:12:54 +02:00
parent 496c096531
commit 24c99868e1
7 changed files with 109 additions and 56 deletions

View File

@ -1,3 +1,5 @@
import { ReactNode } from "react";
export interface IGetGlobalResponse { export interface IGetGlobalResponse {
active_cryptocurrencies: number; active_cryptocurrencies: number;
markets: number; markets: number;
@ -17,18 +19,37 @@ export interface IGetCoinsCountResponse {
} }
export interface IGetCoinInfoResponse { export interface IGetCoinInfoResponse {
[key: string]: any; name: string;
id: string;
image: {
large: string;
};
description: {
en: string;
}
market_data: {
low_24h: { usd: number };
high_24h: { usd: number };
ath: { usd: number };
atl: { usd: number };
price_change_percentage_24h: number;
price_change_percentage_7d: number;
price_change_percentage_14d: number;
price_change_percentage_30d: number;
price_change_percentage_60d: number;
price_change_percentage_200d: number;
price_change_percentage_1y: number;
}
}
export interface IGetCoinInfoData {
data: IGetCoinInfoResponse
} }
export interface IGetCoinInfoRequest { export interface IGetCoinInfoRequest {
id: string; id: string;
} }
// export interface IGetCoinChartRequest {
// page: number;
// per_page: number;
// }
export interface IChartDataItem { export interface IChartDataItem {
[index: number]: number, [index: number]: number,
} }

View File

@ -1,3 +1,4 @@
import React from 'react'
import { useParams } from 'react-router-dom'; import { useParams } from 'react-router-dom';
import { useGetCoinInfoQuery } from '../coinApi'; import { useGetCoinInfoQuery } from '../coinApi';
@ -12,22 +13,25 @@ import CoinInfo from './coinInfo';
const CoinDetails = (): JSX.Element => { const CoinDetails = (): JSX.Element => {
const { id } = useParams(); const { id } = useParams();
const { const {
data: data, data,
error: errorInfo, error,
isLoading: isLoadingInfo, isLoading,
isSuccess: isSuccessInfo, isSuccess,
refetch: refetchInfo
} = useGetCoinInfoQuery(id ? id : ''); } = useGetCoinInfoQuery(id ? id : '');
React.useEffect(() => {
console.log(data)
}, [])
return ( return (
<div className="details"> <div className="details">
{isLoading && <div>Loading...</div>}
{ {
data && isSuccessInfo && <> data && isSuccess && <>
<div className="details-title"> <div className="details-title">
<img src={data.image.large} width="28" height="28" /> <img src={data.image.large} width="28" height="28" />
<h1>{data.name}</h1> <h1>{data.name}</h1>
</div> </div>
<Box> <Box>
<Grid container> <Grid container>
<Grid item xs={12} sm={12} md={8}> <Grid item xs={12} sm={12} md={8}>
@ -39,8 +43,8 @@ const CoinDetails = (): JSX.Element => {
<Grid item xs={12} style={{marginTop: 20}}> <Grid item xs={12} style={{marginTop: 20}}>
<CoinChart coin={data.id} /> <CoinChart coin={data.id} />
</Grid> </Grid>
<Grid item xs={12}> <Grid item xs={12} style={{marginTop: 40}}>
<div dangerouslySetInnerHTML={{ __html: data.description.en }} /> <div style={{lineHeight: 2}} dangerouslySetInnerHTML={{ __html: data.description.en }} />
</Grid> </Grid>
</Grid> </Grid>
</Box> </Box>

View File

@ -27,7 +27,7 @@ const CoinInfo = (props: ICoinInfoProps): JSX.Element => {
Current price: ${data.tickers[0].converted_last.usd} Current price: ${data.tickers[0].converted_last.usd}
</Grid> </Grid>
<Grid item xs={12} style={{ marginTop: 20 }}> <Grid item xs={12} style={{ marginTop: 20 }}>
Homepage: <a target="_blank" href={data.links.homepage}>{data.links.homepage}</a> Homepage: <a target="_blank" href={data.links.homepage[0]}>{data.links.homepage[0]}</a>
</Grid> </Grid>
<Grid item style={{ marginTop: 20 }}> <Grid item style={{ marginTop: 20 }}>
Votes: {data.sentiment_votes_up_percentage}% Votes: {data.sentiment_votes_up_percentage}%
@ -38,29 +38,37 @@ const CoinInfo = (props: ICoinInfoProps): JSX.Element => {
</Grid> </Grid>
<Grid container justifyContent="flex-start" style={{ marginTop: 30, marginBottom: 30 }}> <Grid container justifyContent="flex-start" style={{ marginTop: 30, marginBottom: 30 }}>
{data.links.subreddit_url && {data.links.subreddit_url &&
<Button style={{ marginRight: 10 }} variant="outlined" startIcon={<RedditIcon />} href={data.links.subreddit_url}> <Button style={{ marginRight: 10, marginTop: 10 }} variant="outlined" startIcon={<RedditIcon />} href={data.links.subreddit_url}>
Reddit Reddit
</Button> </Button>
} }
{data.links.twitter_screen_name && {data.links.twitter_screen_name &&
<Button style={{ marginRight: 10 }} variant="outlined" startIcon={<TwitterIcon />} href={`https://twitter.com/${data.links.twitter_screen_name}`}> <Button style={{ marginRight: 10, marginTop: 10 }} variant="outlined" startIcon={<TwitterIcon />} href={`https://twitter.com/${data.links.twitter_screen_name}`}>
Twitter Twitter
</Button> </Button>
} }
{ {
Object.entries(data.links.chat_url).map( Object.entries(data.links.chat_url).map(
([key, value]) => Boolean(value) ([key, value]) => {
&& <Button if (Boolean(value)) {
console.log(value);
const domain = new URL(String(value));
const label = domain.hostname.split(".")[0]
return (
<Button
key={key} key={key}
style={{ marginRight: 10 }} style={{ marginRight: 10, marginTop: 10 }}
variant="outlined" variant="outlined"
href={String(value)} href={String(value)}
startIcon={<LinkIcon />} startIcon={<LinkIcon />}
> >
Discord {label}
</Button> </Button>
) )
} }
}
)
}
</Grid> </Grid>
</div> </div>
) )

View File

@ -5,12 +5,17 @@ import TableContainer from '@mui/material/TableContainer';
import TableHead from '@mui/material/TableHead'; import TableHead from '@mui/material/TableHead';
import TableRow from '@mui/material/TableRow'; import TableRow from '@mui/material/TableRow';
export interface ICoinStatsProps { import { IGetCoinInfoResponse, IGetCoinInfoData } from '../coinApi-types'
[key: string]: any;
interface ICoinStatsProps {
data: IGetCoinInfoResponse;
} }
const CoinStats = (props: ICoinStatsProps): JSX.Element => { const CoinStats = (props: ICoinStatsProps): JSX.Element => {
console.log("CoinStats props", props)
const { data } = props; const { data } = props;
const tableData = [ const tableData = [
{title: "24h Hight", value: `$${data.market_data.low_24h.usd}`}, {title: "24h Hight", value: `$${data.market_data.low_24h.usd}`},
{title: "24h Low", value: `$${data.market_data.high_24h.usd}`}, {title: "24h Low", value: `$${data.market_data.high_24h.usd}`},

View File

@ -12,7 +12,17 @@ import { useGetCoinsListQuery, useGetGlobalQuery } from '../coinApi';
import Pager from './coinListPager'; import Pager from './coinListPager';
export interface IData {
id: string;
image: string;
name: string;
market_cap_rank: number;
symbol: string;
current_price: string;
high_24h: number;
low_24h: number;
price_change_percentage_24h: number;
}
const CoinList = (): JSX.Element => { const CoinList = (): JSX.Element => {
@ -74,7 +84,7 @@ const CoinList = (): JSX.Element => {
</TableHead> </TableHead>
<TableBody> <TableBody>
{ {
data.map((row: any, index: any) => ( data.map((row: IData, index: number) => (
<TableRow <TableRow
key={row.name} key={row.name}
sx={{ '&:last-child td, &:last-child th': { border: 0 } }} sx={{ '&:last-child td, &:last-child th': { border: 0 } }}
@ -119,7 +129,7 @@ const CoinList = (): JSX.Element => {
</Table> </Table>
</TableContainer> </TableContainer>
} }
<Pager page={page} per_page={per_page} setSearchParams={setSearchParams} /> <Pager page={page} per_page={per_page}/>
</div> </div>
) )
} }

View File

@ -6,7 +6,12 @@ import ButtonGroup from '@mui/material/ButtonGroup';
import Typography from '@mui/material/Typography'; import Typography from '@mui/material/Typography';
import Grid from '@mui/material/Grid'; import Grid from '@mui/material/Grid';
const Pager = (props:any): JSX.Element => { export interface IPagerProps {
page: number;
per_page: number;
}
const Pager = (props: IPagerProps): JSX.Element => {
const { page, per_page, } = props; const { page, per_page, } = props;
const { data, error, isLoading, isSuccess, refetch } = useGetCoinsCountQuery(); const { data, error, isLoading, isSuccess, refetch } = useGetCoinsCountQuery();
const navigate = useNavigate(); const navigate = useNavigate();

View File

@ -3,7 +3,7 @@
## What's inside ## What's inside
- **Frontend:** Typescript using React, Redux-Toolkit, MaterialUI, react-charts-2 - **Frontend:** Typescript using React, Redux-Toolkit, Material-UI, react-chartjs-2
- **Backend:** Javascript using Express - **Backend:** Javascript using Express
![Screenshot](./screenshot.png) ![Screenshot](./screenshot.png)