Added loading icon when data is getting fetch for the username

This commit is contained in:
Arnaud Fauconnet 2022-11-04 14:56:00 +01:00
parent 4c9b1927e8
commit 2e9db61173
7 changed files with 113 additions and 39 deletions

View File

@ -37,6 +37,7 @@
"react-dom": "^18.2.0", "react-dom": "^18.2.0",
"react-final-form": "^6.5.9", "react-final-form": "^6.5.9",
"react-hook-form": "^7.38.0", "react-hook-form": "^7.38.0",
"react-loading-icons": "^1.1.0",
"react-router-dom": "^6.4.2", "react-router-dom": "^6.4.2",
"sass": "^1.55.0", "sass": "^1.55.0",
"sass-loader": "^13.1.0", "sass-loader": "^13.1.0",

View File

@ -2,7 +2,7 @@ import axios from "axios";
export const axiosInstance = axios.create({ export const axiosInstance = axios.create({
baseURL: "http://localhost:5276", baseURL: "http://localhost:5276",
timeout: 1000, timeout: 5000,
params : { params : {
shopId: 10, shopId: 10,
} }

View File

@ -0,0 +1,37 @@
import { axiosInstance } from "./axiosInstance";
import { ApiToken, CustomerInfo } from "./types";
const API_TOKEN_NOT_FOUND_ERROR_CODE = 16;
/**
* Get the data of customer
*
* @param token The token, given from WOnD, of the customer
* @returns the data of the customer
*/
export async function fetchCustomerInfo(token: ApiToken, id: number): Promise<CustomerInfo> {
function timeout(ms: number) {
return new Promise(resolve => setTimeout(resolve, ms))
}
await timeout(3000);
const res = await axiosInstance.get("/getCustomer", {
params: { token, id }
})
if (res.data.getCustomer.result == "ERROR"){
const code: number = res.data.getCustomer.errorCode;
// if (code == API_TOKEN_NOT_FOUND_ERROR_CODE)
// navigate('/')
const msg: string = res.data.getCustomer.message;
throw new Error(`Couldn't get user info\nError code: ${code}\nError message: ${msg}`);
}
const customerInfo: CustomerInfo = {
name: res.data.getCustomer.customer.description, // yes i know...
balance: res.data.getCustomer.customer.prepayBalanceCash
}
return customerInfo;
}

View File

@ -1,3 +1,3 @@
export * from "./isTokenValid"; export * from "./isTokenValid";
export * from "./login"; export * from "./login";
export * from "./getCustomerInfo"; export * from "./fetchCustomerInfo";

View File

@ -1,11 +1,12 @@
import React, { useContext, useEffect, useState } from "react"; import React, { useContext, useEffect, useState, MouseEvent } from "react";
import "@scss/transactions.scss"; import "@scss/transactions.scss";
import { ThreeDots as LoadingIcon } from "react-loading-icons";
import Table from "@components/Transactions/Table" import Table from "@components/Transactions/Table"
import userContext from "@ts/userContext" import userContext from "@ts/userContext"
import AppBar from "@theme/modules/components/AppBar"; import AppBar from "@theme/modules/components/AppBar";
import Toolbar from "@theme/modules/components/Toolbar"; import Toolbar from "@theme/modules/components/Toolbar";
import Typography from "@theme/modules/components/Typography"; import Typography from "@theme/modules/components/Typography";
import { Box, Link, TextFieldProps, TextField } from "@mui/material"; import { Box, Link, TextFieldProps, TextField, Button } from "@mui/material";
import AccountCircleIcon from '@mui/icons-material/AccountCircle'; import AccountCircleIcon from '@mui/icons-material/AccountCircle';
import { DesktopDatePicker } from '@mui/x-date-pickers/DesktopDatePicker'; import { DesktopDatePicker } from '@mui/x-date-pickers/DesktopDatePicker';
import { useForm } from "react-hook-form"; import { useForm } from "react-hook-form";
@ -16,7 +17,7 @@ import dayjs, { Dayjs } from 'dayjs';
import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
import { getValue } from "@mui/system"; import { getValue } from "@mui/system";
import { CustomerInfo } from "@api/types"; import { CustomerInfo } from "@api/types";
import { getCustomerInfo } from "@api"; import { useGetCustomerInfo } from "src/hooks/useGetCustomerInfo";
@ -43,17 +44,11 @@ const schema = yup
export function Transactions() { export function Transactions() {
const user = useContext(userContext); const user = useContext(userContext);
const [customerInfo, setCustomerInfo] = useState<CustomerInfo>({name: "John Smith", balance: -1}); const { customerInfo, isLoading, getCustomerInfo } = useGetCustomerInfo();
async function fetchData() {
if (!user.token)
return;
const info = await getCustomerInfo(user.token, user.id);
setCustomerInfo(info);
};
useEffect(() => { useEffect(() => {
fetchData(); if (user.token)
getCustomerInfo(user.token, user.id);
}, [user.token]) }, [user.token])
const { const {
@ -120,6 +115,10 @@ export function Transactions() {
helperText: errors?.maxAmount?.message, helperText: errors?.maxAmount?.message,
} }
function handleRefreshButton(event: MouseEvent<HTMLElement>): void {
getCustomerInfo(user.token, user.id);
}
return ( return (
<div id="tablePage"> <div id="tablePage">
<AppBar position="fixed" sx={{ background: "#28282a" }}> <AppBar position="fixed" sx={{ background: "#28282a" }}>
@ -128,9 +127,13 @@ export function Transactions() {
<Typography variant="h3" > <Typography variant="h3" >
Transactions Transactions
</Typography> </Typography>
<Button sx={{marginLeft: 5}} variant="contained" onClick={handleRefreshButton}>
Refresh
</Button>
<Box className="box right"> <Box className="box right">
<Link variant="h6" className="link" href="/"> <Link variant="h6" className="link userName" href="/">
{customerInfo.name} (CHF {customerInfo.balance}) {isLoading ? <LoadingIcon height=".5em"/> : customerInfo.name}
{/* {customerInfo.name} (CHF {customerInfo.balancE}) */}
</Link> </Link>
<AccountCircleIcon className="icon" /> <AccountCircleIcon className="icon" />
</Box> </Box>
@ -141,18 +144,26 @@ export function Transactions() {
<Typography variant="h5"> <Typography variant="h5">
Filters Filters
</Typography> </Typography>
<Box className="box">
<Typography variant="h6"> <Typography variant="h6">
Dates Dates
</Typography> </Typography>
<Box className="inputs-box dates">
<LocalizationProvider dateAdapter={AdapterDayjs}> <LocalizationProvider dateAdapter={AdapterDayjs}>
<DesktopDatePicker {...startDatePickerProps} /> <DesktopDatePicker {...startDatePickerProps} />
<DesktopDatePicker {...endDatePickerProps} /> <DesktopDatePicker {...endDatePickerProps} />
</LocalizationProvider> </LocalizationProvider>
</Box>
</Box>
<Box className="box">
<Typography variant="h6"> <Typography variant="h6">
Transactions Transactions
</Typography> </Typography>
<Box className="inputs-box transactions">
<TextField {...minAmountProps}></TextField> <TextField {...minAmountProps}></TextField>
<TextField {...maxAmountProps}></TextField> <TextField {...maxAmountProps}></TextField>
</Box>
</Box>
</form> </form>
</aside> </aside>
<main> <main>

View File

@ -0,0 +1,17 @@
import { fetchCustomerInfo } from "@api";
import { ApiToken, CustomerInfo } from "@api/types";
import { useState } from "react";
export function useGetCustomerInfo() {
const [customerInfo, setCustomerInfo] = useState<CustomerInfo>({ name: "John Smith", balance: -1 });
const [isLoading, setIsLoading] = useState<boolean>(true); // this should be false, but at least the "Loading..." text appears when the page is loading
const getCustomerInfo = (token: ApiToken, id: number) => {
setIsLoading(true);
fetchCustomerInfo(token, id)
.then(setCustomerInfo)
.then(() => setIsLoading(false));
}
return { isLoading, customerInfo, getCustomerInfo };
}

View File

@ -40,6 +40,7 @@ body.transactions {
align-items: center; align-items: center;
.link { .link {
text-align: right;
color: inherit; color: inherit;
text-decoration: none; text-decoration: none;
margin-right: .5em; margin-right: .5em;
@ -73,7 +74,9 @@ body.transactions {
white-space: nowrap; white-space: nowrap;
// overflow: hidden; // overflow: hidden;
} }
.amount, .total{
.amount,
.total {
min-width: 6em; min-width: 6em;
} }
@ -122,6 +125,7 @@ body.transactions {
header { header {
grid-row: 1; grid-row: 1;
position: sticky; position: sticky;
.box.left { .box.left {
display: none; display: none;
} }
@ -131,6 +135,7 @@ body.transactions {
grid-row: 2; grid-row: 2;
min-width: 0; min-width: 0;
form { form {
flex-direction: row; flex-direction: row;
@ -142,9 +147,11 @@ body.transactions {
text-align: center; text-align: center;
} }
.box {
flex-grow: 1;
.inputs-box { .inputs-box {
// background: red; // background: red;
width: 50vw;
display: flex; display: flex;
flex-direction: row; flex-direction: row;
justify-content: space-evenly; justify-content: space-evenly;
@ -156,6 +163,7 @@ body.transactions {
} }
} }
} }
}
main { main {
grid-row: 3; grid-row: 3;