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-final-form": "^6.5.9",
"react-hook-form": "^7.38.0",
"react-loading-icons": "^1.1.0",
"react-router-dom": "^6.4.2",
"sass": "^1.55.0",
"sass-loader": "^13.1.0",

View File

@ -2,7 +2,7 @@ import axios from "axios";
export const axiosInstance = axios.create({
baseURL: "http://localhost:5276",
timeout: 1000,
timeout: 5000,
params : {
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 "./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 { ThreeDots as LoadingIcon } from "react-loading-icons";
import Table from "@components/Transactions/Table"
import userContext from "@ts/userContext"
import AppBar from "@theme/modules/components/AppBar";
import Toolbar from "@theme/modules/components/Toolbar";
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 { DesktopDatePicker } from '@mui/x-date-pickers/DesktopDatePicker';
import { useForm } from "react-hook-form";
@ -16,7 +17,7 @@ import dayjs, { Dayjs } from 'dayjs';
import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
import { getValue } from "@mui/system";
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() {
const user = useContext(userContext);
const [customerInfo, setCustomerInfo] = useState<CustomerInfo>({name: "John Smith", balance: -1});
async function fetchData() {
if (!user.token)
return;
const info = await getCustomerInfo(user.token, user.id);
setCustomerInfo(info);
};
const { customerInfo, isLoading, getCustomerInfo } = useGetCustomerInfo();
useEffect(() => {
fetchData();
if (user.token)
getCustomerInfo(user.token, user.id);
}, [user.token])
const {
@ -120,6 +115,10 @@ export function Transactions() {
helperText: errors?.maxAmount?.message,
}
function handleRefreshButton(event: MouseEvent<HTMLElement>): void {
getCustomerInfo(user.token, user.id);
}
return (
<div id="tablePage">
<AppBar position="fixed" sx={{ background: "#28282a" }}>
@ -128,9 +127,13 @@ export function Transactions() {
<Typography variant="h3" >
Transactions
</Typography>
<Button sx={{marginLeft: 5}} variant="contained" onClick={handleRefreshButton}>
Refresh
</Button>
<Box className="box right">
<Link variant="h6" className="link" href="/">
{customerInfo.name} (CHF {customerInfo.balance})
<Link variant="h6" className="link userName" href="/">
{isLoading ? <LoadingIcon height=".5em"/> : customerInfo.name}
{/* {customerInfo.name} (CHF {customerInfo.balancE}) */}
</Link>
<AccountCircleIcon className="icon" />
</Box>
@ -141,18 +144,26 @@ export function Transactions() {
<Typography variant="h5">
Filters
</Typography>
<Typography variant="h6">
Dates
</Typography>
<LocalizationProvider dateAdapter={AdapterDayjs}>
<DesktopDatePicker {...startDatePickerProps} />
<DesktopDatePicker {...endDatePickerProps} />
</LocalizationProvider>
<Typography variant="h6">
Transactions
</Typography>
<TextField {...minAmountProps}></TextField>
<TextField {...maxAmountProps}></TextField>
<Box className="box">
<Typography variant="h6">
Dates
</Typography>
<Box className="inputs-box dates">
<LocalizationProvider dateAdapter={AdapterDayjs}>
<DesktopDatePicker {...startDatePickerProps} />
<DesktopDatePicker {...endDatePickerProps} />
</LocalizationProvider>
</Box>
</Box>
<Box className="box">
<Typography variant="h6">
Transactions
</Typography>
<Box className="inputs-box transactions">
<TextField {...minAmountProps}></TextField>
<TextField {...maxAmountProps}></TextField>
</Box>
</Box>
</form>
</aside>
<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;
.link {
text-align: right;
color: inherit;
text-decoration: none;
margin-right: .5em;
@ -73,7 +74,9 @@ body.transactions {
white-space: nowrap;
// overflow: hidden;
}
.amount, .total{
.amount,
.total {
min-width: 6em;
}
@ -122,6 +125,7 @@ body.transactions {
header {
grid-row: 1;
position: sticky;
.box.left {
display: none;
}
@ -131,6 +135,7 @@ body.transactions {
grid-row: 2;
min-width: 0;
form {
flex-direction: row;
@ -142,16 +147,19 @@ body.transactions {
text-align: center;
}
.inputs-box {
// background: red;
width: 50vw;
display: flex;
flex-direction: row;
justify-content: space-evenly;
.box {
flex-grow: 1;
.input {
// background: blue;
width: 10em;
.inputs-box {
// background: red;
display: flex;
flex-direction: row;
justify-content: space-evenly;
.input {
// background: blue;
width: 10em;
}
}
}
}