better interface names

This commit is contained in:
Ste Vaidis 2022-12-12 10:57:34 +02:00
parent c09ef3e077
commit c23c025181
15 changed files with 104 additions and 230 deletions

View File

@ -1,38 +0,0 @@
.App {
text-align: center;
}
.App-logo {
height: 40vmin;
pointer-events: none;
}
@media (prefers-reduced-motion: no-preference) {
.App-logo {
animation: App-logo-spin infinite 20s linear;
}
}
.App-header {
background-color: #282c34;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: calc(10px + 2vmin);
color: white;
}
.App-link {
color: #61dafb;
}
@keyframes App-logo-spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}

View File

@ -1,9 +0,0 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
import App from './App';
test('renders learn react link', () => {
render(<App />);
const linkElement = screen.getByText(/learn react/i);
expect(linkElement).toBeInTheDocument();
});

View File

@ -1,21 +1,20 @@
// Route import React from 'react';
import { BrowserRouter, Routes, Route } from "react-router-dom"; import { BrowserRouter, Routes, Route } from "react-router-dom";
// Components import Box from '@mui/material/Box';
import Grid from '@mui/material/Grid';
import Container from '@mui/material/Container';
import { ThemeProvider, createTheme } from '@mui/material/styles';
import Header from './Header' import Header from './Header'
import CoinList from './coinList/coinList'; import CoinList from './coinList/coinList';
import CoinDetails from './coinDetails/coinDetails'; import CoinDetails from './coinDetails/coinDetails';
import * as React from 'react';
import { ThemeProvider, createTheme } from '@mui/material/styles';
import Grid from '@mui/material/Grid';
import Box from '@mui/material/Box';
import Container from '@mui/material/Container';
const ColorModeContext = React.createContext({ toggleColorMode: () => { } }); const ColorModeContext = React.createContext({ toggleColorMode: () => { } });
function App() { function App() {
const [mode, setMode] = React.useState<'light' | 'dark'>('light'); const [mode, setMode] = React.useState<'light' | 'dark'>('light');
const colorMode = React.useMemo( const colorMode = React.useMemo(
() => ({ () => ({
toggleColorMode: () => { toggleColorMode: () => {
@ -24,6 +23,7 @@ function App() {
}), }),
[], [],
); );
const theme = React.useMemo( const theme = React.useMemo(
() => () =>
createTheme({ createTheme({

View File

@ -1,44 +1,43 @@
// Material UI import React from 'react';
import * as React from 'react';
import AppBar from '@mui/material/AppBar';
import Box from '@mui/material/Box';
import Toolbar from '@mui/material/Toolbar';
import Typography from '@mui/material/Typography';
import Button from '@mui/material/Button';
import IconButton from '@mui/material/IconButton';
import MenuIcon from '@mui/icons-material/Menu';
import { useTheme } from '@mui/material/styles';
import Brightness4Icon from '@mui/icons-material/Brightness4';
import Brightness7Icon from '@mui/icons-material/Brightness7';
import { Link } from "react-router-dom"; import { Link } from "react-router-dom";
const ColorModeContext = React.createContext({ toggleColorMode: () => {} }); import Box from '@mui/material/Box';
import AppBar from '@mui/material/AppBar';
import Toolbar from '@mui/material/Toolbar';
import Typography from '@mui/material/Typography';
import IconButton from '@mui/material/IconButton';
import Brightness4Icon from '@mui/icons-material/Brightness4';
import Brightness7Icon from '@mui/icons-material/Brightness7';
import { useTheme } from '@mui/material/styles';
export interface HeaderProps { const ColorModeContext = React.createContext({ toggleColorMode: () => { } });
colorMode: any;
theme: any; interface HeaderProps {
colorMode: {
toggleColorMode: () => void;
}
theme: any;
} }
const Header = (props: HeaderProps): JSX.Element => { const Header = (props: HeaderProps): JSX.Element => {
const theme = useTheme(); const theme = useTheme();
const colorMode = React.useContext(ColorModeContext); const colorMode = React.useContext(ColorModeContext);
return ( return (
<Box style={{marginBottom: 60}} sx={{ flexGrow: 1 }}> <Box style={{ marginBottom: 60 }} sx={{ flexGrow: 1 }}>
<AppBar position="static"> <AppBar position="static">
<Toolbar> <Toolbar>
<Typography variant="h6" component="div" sx={{ flexGrow: 1 }}> <Typography variant="h6" component="div" sx={{ flexGrow: 1 }}>
<Link to={'/'}> <Link to={'/'}>
CoinGecko Data CoinGecko Data
</Link> </Link>
</Typography> </Typography>
<IconButton sx={{ ml: 1 }} onClick={props.colorMode.toggleColorMode} color="inherit"> <IconButton sx={{ ml: 1 }} onClick={props.colorMode.toggleColorMode} color="inherit">
{props.theme.palette.mode === 'dark' ? <Brightness7Icon /> : <Brightness4Icon />} {props.theme.palette.mode === 'dark' ? <Brightness7Icon /> : <Brightness4Icon />}
</IconButton> </IconButton>
</Toolbar> </Toolbar>
</AppBar> </AppBar>
</Box> </Box>
); );
} }
export default Header; export default Header;

View File

@ -1,24 +1,36 @@
import { ReactNode } from "react"; import { ReactNode } from "react";
export interface IGetGlobalResponse { export interface IGlobalResponse {
active_cryptocurrencies: number; active_cryptocurrencies: number;
markets: number; markets: number;
} }
export interface IGetCoinsListRequest { export interface ICoinsListRequest {
page: number; page: number;
per_page: number; per_page: number;
} }
export interface IGetCoinsListResponse { export interface ICoinsListItem {
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;
}
export interface ICoinsListResponse {
[key: string]: any; [key: string]: any;
} }
export interface IGetCoinsCountResponse { export interface ICoinsCountResponse {
count: number; count: number;
} }
export interface IGetCoinInfoResponse { export interface ICoinInfoResponse {
name: string; name: string;
id: string; id: string;
image: { image: {
@ -42,11 +54,11 @@ export interface IGetCoinInfoResponse {
} }
} }
export interface IGetCoinInfoData { export interface ICoinInfoData {
data: IGetCoinInfoResponse data: ICoinInfoResponse
} }
export interface IGetCoinInfoRequest { export interface ICoinInfoRequest {
id: string; id: string;
} }
@ -54,7 +66,7 @@ export interface IChartDataItem {
[index: number]: number, [index: number]: number,
} }
export interface IGetCoinChartRequest { export interface ICoinChartRequest {
coin: string; coin: string;
days: string; days: string;
} }

View File

@ -1,12 +1,13 @@
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react' import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'
import { import {
IGetGlobalResponse, IGlobalResponse,
IGetCoinsListRequest, ICoinsListRequest,
IGetCoinsListResponse, ICoinsListItem,
IGetCoinsCountResponse, ICoinsListResponse,
IGetCoinInfoRequest, ICoinsCountResponse,
IGetCoinInfoResponse, ICoinInfoRequest,
IGetCoinChartRequest, ICoinInfoResponse,
ICoinChartRequest,
IGetCoinChartResponse, IGetCoinChartResponse,
} from './coinApi-types' } from './coinApi-types'
@ -20,19 +21,19 @@ const coinChartUrl = (coin: string, days: string) => `/coin/${coin}/chart/${days
export const coinListApi = createApi({ export const coinListApi = createApi({
baseQuery: fetchBaseQuery({ baseUrl: baseUrl }), baseQuery: fetchBaseQuery({ baseUrl: baseUrl }),
endpoints: (builder) => ({ endpoints: (builder) => ({
getGlobal: builder.query<IGetGlobalResponse, void>({ getGlobal: builder.query<IGlobalResponse, void>({
query: () => globalUrl, query: () => globalUrl,
}), }),
getCoinsList: builder.query<IGetCoinsListResponse, IGetCoinsListRequest>({ getCoinsList: builder.query<ICoinsListItem[], ICoinsListRequest>({
query: (payload: IGetCoinsListRequest) => `${marketsUrl}?per_page=${payload.per_page}&page=${payload.page}`, query: (payload: ICoinsListRequest) => `${marketsUrl}?per_page=${payload.per_page}&page=${payload.page}`,
}), }),
getCoinsCount: builder.query<IGetCoinsCountResponse, void>({ getCoinsCount: builder.query<ICoinsCountResponse, void>({
query: () => countUrl, query: () => countUrl,
}), }),
getCoinInfo: builder.query<IGetCoinInfoResponse, string>({ getCoinInfo: builder.query<ICoinInfoResponse, string>({
query: (id: string) => coinInfoUrl(id), query: (id: string) => coinInfoUrl(id),
}), }),
getCoinChart: builder.query<IGetCoinChartResponse, IGetCoinChartRequest>({ getCoinChart: builder.query<IGetCoinChartResponse, ICoinChartRequest>({
query: (payload: {coin: string, days: string}) => coinChartUrl(payload.coin, payload.days), query: (payload: {coin: string, days: string}) => coinChartUrl(payload.coin, payload.days),
}), }),
}), }),

View File

@ -23,7 +23,7 @@ import {
IChartDataItem, IChartDataItem,
IChartData, IChartData,
IChartDataFormatted IChartDataFormatted
} from './coinChart-types'; } from './coinDetails-types';
ChartJS.register( ChartJS.register(
CategoryScale, CategoryScale,

View File

@ -1,3 +1,5 @@
import { ICoinInfoResponse } from '../coinApi-types'
export interface ICoinChartProps { export interface ICoinChartProps {
coin: string; coin: string;
} }
@ -18,3 +20,16 @@ export interface IChartDataFormattedItem {
} }
export interface IChartDataFormatted extends Array<IChartDataFormattedItem> { }; export interface IChartDataFormatted extends Array<IChartDataFormattedItem> { };
export interface ICoinInfoProps {
[key: string]: any;
}
export interface ICoinStatsProps {
data: ICoinInfoResponse;
}
export interface IStatsRow {
title: string;
value: string;
}

View File

@ -4,25 +4,10 @@ import GitHubIcon from '@mui/icons-material/GitHub';
import RedditIcon from '@mui/icons-material/Reddit'; import RedditIcon from '@mui/icons-material/Reddit';
import TwitterIcon from '@mui/icons-material/Twitter'; import TwitterIcon from '@mui/icons-material/Twitter';
import LinkIcon from '@mui/icons-material/Link'; import LinkIcon from '@mui/icons-material/Link';
import Button from '@mui/material/Button'; import Button from '@mui/material/Button';
import Grid from '@mui/material/Grid'; import Grid from '@mui/material/Grid';
import { IGetCoinInfoResponse } from '../coinApi-types' import { ICoinInfoProps } from './coinDetails-types'
// export interface ICoinInfoProps {
// [key: string]: any;
// }
// interface ICoinInfoProps {
// data: IGetCoinInfoResponse;
// }
export interface ICoinInfoProps {
[key: string]: any;
}
const CoinInfo = (props: ICoinInfoProps): JSX.Element => { const CoinInfo = (props: ICoinInfoProps): JSX.Element => {
const { data } = props; const { data } = props;

View File

@ -2,23 +2,11 @@ import Table from '@mui/material/Table';
import TableBody from '@mui/material/TableBody'; import TableBody from '@mui/material/TableBody';
import TableCell from '@mui/material/TableCell'; import TableCell from '@mui/material/TableCell';
import TableContainer from '@mui/material/TableContainer'; import TableContainer from '@mui/material/TableContainer';
import TableHead from '@mui/material/TableHead';
import TableRow from '@mui/material/TableRow'; import TableRow from '@mui/material/TableRow';
import { IGetCoinInfoResponse } from '../coinApi-types' import { ICoinStatsProps, ICoinInfoProps, IStatsRow } from './coinDetails-types'
interface ICoinStatsProps {
data: IGetCoinInfoResponse;
}
interface IRow {
title: string;
value: string;
}
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 = [
@ -42,7 +30,7 @@ const CoinStats = (props: ICoinStatsProps): JSX.Element => {
<Table size="small" > <Table size="small" >
<TableBody> <TableBody>
{ {
tableData.map((row: IRow, index: number) => ( tableData.map((row: IStatsRow, index: number) => (
<TableRow key={row.title}> <TableRow key={row.title}>
<TableCell align="left">{row.title}</TableCell> <TableCell align="left">{row.title}</TableCell>
<TableCell align="right">{row.value}</TableCell> <TableCell align="right">{row.value}</TableCell>

View File

@ -1,64 +1,4 @@
export interface IGetAssetsResponse { export interface IPagerProps {
result: { [key: string]: any }; page: number;
error: [] per_page: number;
} }
export interface IGetPairsResponse {
[key: string]: any;
}
export interface IGetDataResponse {
result: { [key: string]: any };
error: []
}
export interface IGetDataRequest {
pair: string;
interval: number;
}
export interface IOHLCData {
close: number;
date: Date;
high: number;
low: number;
open: number;
volume: number;
}
export interface ChartProps {
data: IOHLCData[];
itemWidth: number;
}
export interface InitialData {
readonly data: IOHLCData[];
readonly height: number;
readonly width: number;
readonly ratio: number;
readonly crosshair?: boolean;
}
export interface IProps {
id: string;
pair: string;
}
export interface IChartState {
assets: { [key: string]: any };
pairs: { [key: string]: any };
data: { [key: string]: any };
items: {
id: string;
pair: string;
data?: IOHLCData[]
}[]
}
export interface IintervalValue {
label: string;
value: number;
}
export interface IintervalValues extends Array<IintervalValue> { }

View File

@ -9,21 +9,10 @@ import TableHead from '@mui/material/TableHead';
import TableRow from '@mui/material/TableRow'; import TableRow from '@mui/material/TableRow';
import { useGetCoinsListQuery, useGetGlobalQuery } from '../coinApi'; import { useGetCoinsListQuery, useGetGlobalQuery } from '../coinApi';
import { ICoinsListItem } from '../coinApi-types';
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 => {
// From URL // From URL
@ -39,7 +28,6 @@ const CoinList = (): JSX.Element => {
return ( return (
<div className="coin-list"> <div className="coin-list">
{isLoading || globalIsLoading && <div>Loading...</div>} {isLoading || globalIsLoading && <div>Loading...</div>}
{ {
globalData && globalData &&
<span className="globalText"> <span className="globalText">
@ -47,7 +35,6 @@ const CoinList = (): JSX.Element => {
<br /> <br />
</span> </span>
} }
{ {
data && isSuccess && data && isSuccess &&
<TableContainer style={{ marginTop: 20 }}> <TableContainer style={{ marginTop: 20 }}>
@ -84,7 +71,7 @@ const CoinList = (): JSX.Element => {
</TableHead> </TableHead>
<TableBody> <TableBody>
{ {
data.map((row: IData, index: number) => ( data.map((row: ICoinsListItem, 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 } }}

View File

@ -6,14 +6,11 @@ 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';
export interface IPagerProps { import { IPagerProps } from './coinList-types';
page: number;
per_page: number;
}
const Pager = (props: IPagerProps): JSX.Element => { 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 } = useGetCoinsCountQuery();
const navigate = useNavigate(); const navigate = useNavigate();
const lastPage = (data: number) => Math.ceil(data / per_page) const lastPage = (data: number) => Math.ceil(data / per_page)

View File

@ -10,7 +10,7 @@ body {
a { a {
text-decoration: none; text-decoration: none;
color: rgb(59, 84, 177) color: #1976d2;
} }
.coin-list a { .coin-list a {

View File

@ -2,12 +2,9 @@ import { combineReducers, configureStore } from '@reduxjs/toolkit'
import { TypedUseSelectorHook, useDispatch, useSelector } from 'react-redux'; import { TypedUseSelectorHook, useDispatch, useSelector } from 'react-redux';
import { coinListApi } from './coinApi'; import { coinListApi } from './coinApi';
// import listSliceReducer from './chartList/chartList-slice'
// Reducers // Reducers
const rootReducer = combineReducers({ const rootReducer = combineReducers({
// list: listSliceReducer,
[coinListApi.reducerPath]: coinListApi.reducer, [coinListApi.reducerPath]: coinListApi.reducer,
}) })