add async data fetching & rendering to example page

This commit is contained in:
nikek
2020-03-03 17:17:10 +01:00
parent f08fcbec30
commit 46f24e9739
4 changed files with 127 additions and 16 deletions
@@ -1,7 +1,7 @@
import React, { FC } from 'react';
import { Typography, makeStyles, Theme } from '@material-ui/core';
import { Typography, Grid, makeStyles, Theme } from '@material-ui/core';
import { InfoCard, Header, Page, theme } from '@spotify-backstage/core';
import ExampleFetchComponent from '../ExampleFetchComponent';
const useStyles = makeStyles<Theme>(theme => ({
mainContentArea: {
@@ -18,23 +18,33 @@ const useStyles = makeStyles<Theme>(theme => ({
const ExampleComponent: FC<{}> = () => {
const classes = useStyles();
return (
<Page theme={theme.home}>
<div className={classes.mainContentArea}>
<Header
title="Welcome to {{ id }}!"
subtitle="Optional subtitle"
></Header>
<div className={classes.pageBody}>
<Typography variant="h3" className={classes.title}>
Plugin page title
</Typography>
<InfoCard title="Information card" maxWidth>
<Typography variant="body1">
All content should be wrapped in a card like this.
</Typography>
</InfoCard>
</div>
<Header title="Welcome to {{ id }}!" subtitle="Optional subtitle"></Header>
<Grid
container
spacing={3}
direction={'column'}
className={classes.pageBody}
>
<Grid item>
<Typography variant="h3">Plugin page title</Typography>
</Grid>
<Grid item>
<InfoCard title="Information card" maxWidth>
<Typography variant="body1">
All content should be wrapped in a card like this.
</Typography>
</InfoCard>
</Grid>
<Grid item>
<InfoCard title="Example User List (fetching data from randomuser.me)">
<ExampleFetchComponent />
</InfoCard>
</Grid>
</Grid>
</div>
</Page>
);
@@ -0,0 +1,10 @@
import React from 'react';
import { render } from '@testing-library/react';
import ExampleFetchComponent from './ExampleFetchComponent';
describe('ExampleFetchComponent', () => {
it('should render', () => {
const rendered = render(<ExampleFetchComponent />);
expect(rendered.getByTestId('progress')).toBeInTheDocument();
});
});
@@ -0,0 +1,90 @@
import React, { FC } from 'react';
import { makeStyles } from '@material-ui/core/styles';
import Table from '@material-ui/core/Table';
import TableBody from '@material-ui/core/TableBody';
import TableCell from '@material-ui/core/TableCell';
import TableContainer from '@material-ui/core/TableContainer';
import TableHead from '@material-ui/core/TableHead';
import TableRow from '@material-ui/core/TableRow';
import LinearProgress from '@material-ui/core/LinearProgress';
import Alert from '@material-ui/lab/Alert';
import { useAsync } from 'react-use';
const useStyles = makeStyles({
table: {
minWidth: 650,
},
});
type User = {
gender: string; // "male"
name: {
title: string; //"Mr",
first: string; // "Duane",
last: string; //"Reed"
};
location: object; // {street: {number: 5060, name: "Hickory Creek Dr"}, city: "Albany", state: "New South Wales",…}
email: string; // "duane.reed@example.com"
login: object; // {uuid: "4b785022-9a23-4ab9-8a23-cb3fb43969a9", username: "blackdog796", password: "patch",…}
dob: object; // {date: "1983-06-22T12:30:23.016Z", age: 37}
registered: object; // {date: "2006-06-13T18:48:28.037Z", age: 14}
phone: string; //"07-2154-5651"
cell: string; // "0405-592-879"
id: {
name: string; // "TFN",
value: string; // "796260432"
};
picture: object; //{large: "https://randomuser.me/api/portraits/men/95.jpg",…}
nat: string; // "AU"
};
type DenseTableProps = {
users: User[];
};
export const DenseTable: FC<DenseTableProps> = ({ users }) => {
const classes = useStyles();
return (
<TableContainer>
<Table className={classes.table} size="small" aria-label="a dense table">
<TableHead>
<TableRow>
<TableCell>Name</TableCell>
<TableCell>Email</TableCell>
<TableCell>Nationality</TableCell>
</TableRow>
</TableHead>
<TableBody>
{users.map(user => (
<TableRow key={user.id.value}>
<TableCell>
{user.name.first} {user.name.last}
</TableCell>
<TableCell>{user.email}</TableCell>
<TableCell>{user.nat}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
);
};
const ExampleFetchComponent: FC<{}> = () => {
const { value, loading, error } = useAsync(async (): Promise<User[]> => {
const response = await fetch('https://randomuser.me/api/?results=100');
const data = await response.json();
return data.results;
}, []);
if (loading) {
return <LinearProgress data-testid="progress" />;
} else if (error) {
return <Alert severity="error">{error.message}</Alert>;
} else {
return <DenseTable users={value || []} />;
}
};
export default ExampleFetchComponent;
@@ -0,0 +1 @@
export { default } from './ExampleFetchComponent';