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";
// 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 CoinList from './coinList/coinList';
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: () => { } });
function App() {
const [mode, setMode] = React.useState<'light' | 'dark'>('light');
const colorMode = React.useMemo(
() => ({
toggleColorMode: () => {
@ -24,6 +23,7 @@ function App() {
}),
[],
);
const theme = React.useMemo(
() =>
createTheme({

View File

@ -1,44 +1,43 @@
// Material UI
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 React from 'react';
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 {
colorMode: any;
theme: any;
const ColorModeContext = React.createContext({ toggleColorMode: () => { } });
interface HeaderProps {
colorMode: {
toggleColorMode: () => void;
}
theme: any;
}
const Header = (props: HeaderProps): JSX.Element => {
const theme = useTheme();
const colorMode = React.useContext(ColorModeContext);
return (
<Box style={{marginBottom: 60}} sx={{ flexGrow: 1 }}>
<AppBar position="static">
<Toolbar>
<Typography variant="h6" component="div" sx={{ flexGrow: 1 }}>
<Link to={'/'}>
CoinGecko Data
</Link>
</Typography>
<IconButton sx={{ ml: 1 }} onClick={props.colorMode.toggleColorMode} color="inherit">
{props.theme.palette.mode === 'dark' ? <Brightness7Icon /> : <Brightness4Icon />}
</IconButton>
</Toolbar>
</AppBar>
</Box>
);
const theme = useTheme();
const colorMode = React.useContext(ColorModeContext);
return (
<Box style={{ marginBottom: 60 }} sx={{ flexGrow: 1 }}>
<AppBar position="static">
<Toolbar>
<Typography variant="h6" component="div" sx={{ flexGrow: 1 }}>
<Link to={'/'}>
CoinGecko Data
</Link>
</Typography>
<IconButton sx={{ ml: 1 }} onClick={props.colorMode.toggleColorMode} color="inherit">
{props.theme.palette.mode === 'dark' ? <Brightness7Icon /> : <Brightness4Icon />}
</IconButton>
</Toolbar>
</AppBar>
</Box>
);
}
export default Header;

View File

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

View File

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

View File

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

View File

@ -1,3 +1,5 @@
import { ICoinInfoResponse } from '../coinApi-types'
export interface ICoinChartProps {
coin: string;
}
@ -18,3 +20,16 @@ export interface 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 TwitterIcon from '@mui/icons-material/Twitter';
import LinkIcon from '@mui/icons-material/Link';
import Button from '@mui/material/Button';
import Grid from '@mui/material/Grid';
import { IGetCoinInfoResponse } from '../coinApi-types'
// export interface ICoinInfoProps {
// [key: string]: any;
// }
// interface ICoinInfoProps {
// data: IGetCoinInfoResponse;
// }
export interface ICoinInfoProps {
[key: string]: any;
}
import { ICoinInfoProps } from './coinDetails-types'
const CoinInfo = (props: ICoinInfoProps): JSX.Element => {
const { data } = props;

View File

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

View File

@ -1,64 +1,4 @@
export interface IGetAssetsResponse {
result: { [key: string]: any };
error: []
export interface IPagerProps {
page: number;
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 { useGetCoinsListQuery, useGetGlobalQuery } from '../coinApi';
import { ICoinsListItem } from '../coinApi-types';
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 => {
// From URL
@ -39,7 +28,6 @@ const CoinList = (): JSX.Element => {
return (
<div className="coin-list">
{isLoading || globalIsLoading && <div>Loading...</div>}
{
globalData &&
<span className="globalText">
@ -47,7 +35,6 @@ const CoinList = (): JSX.Element => {
<br />
</span>
}
{
data && isSuccess &&
<TableContainer style={{ marginTop: 20 }}>
@ -84,7 +71,7 @@ const CoinList = (): JSX.Element => {
</TableHead>
<TableBody>
{
data.map((row: IData, index: number) => (
data.map((row: ICoinsListItem, index: number) => (
<TableRow
key={row.name}
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 Grid from '@mui/material/Grid';
export interface IPagerProps {
page: number;
per_page: number;
}
import { IPagerProps } from './coinList-types';
const Pager = (props: IPagerProps): JSX.Element => {
const { page, per_page, } = props;
const { data, error, isLoading, isSuccess, refetch } = useGetCoinsCountQuery();
const { data, error, isLoading, isSuccess } = useGetCoinsCountQuery();
const navigate = useNavigate();
const lastPage = (data: number) => Math.ceil(data / per_page)

View File

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

View File

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