import * as React from 'react';
import Card from '#mui/material/Card';
import CardActions from '#mui/material/CardActions';
import CardContent from '#mui/material/CardContent';
import CardMedia from '#mui/material/CardMedia';
import Button from '#mui/material/Button';
import Typography from '#mui/material/Typography';
export default function MediaCard() {
return (
<Card sx={{ maxWidth: 345 }}>
{data.map((item) =>(
<CardMedia component="img" height="140" image={`${data.img}`} alt="home image looding......"/>
<CardContent>
<Typography gutterBottom variant="h5" component="div">{data.name}</Typography>
<Typography variant="body2" color="text.secondary">{data.description}</Typography>
</CardContent>
))}
<CardActions>
<Button size="small">Share</Button>
<Button size="small">Learn More</Button>
</CardActions>
</Card>
);
}
let data =[
{
name:'Property for sale',
img: '/home1.jpg',
description: 'This House is 5.5 cent with square feet area of 2000 and 3 km from palakkad city ;100 meters from main road.',
},
{
name:'Property for Rent',
img: '/home2.jpg',
title: 'Burger',
},
{
name:'Property for sale',
img: '/home3.jpg',
title: 'Camera',
},
{
name:'Property for Rent',
img: '/home4.jpg',
title: 'Coffee',
},
{
name:'Property for sale',
img: '/home5.jpg',
title: 'Hats',
},
{
name:'Property for Rent',
img: '/home7.jpg',
title: 'Honey',
},
];
I can't get the details of mapped items in the card. While doing this I had found an error
"ERROR in src\Components\Card\Card.js
Line 17:6: Parsing error: Adjacent JSX elements must be wrapped in an enclosing tag. Did you want a JSX fragment <>...</>? (17:6)."
I had used material UI and I don't understand whether the mistake had happened.
It should be wrapped in a parent element. e.g
export default function MediaCard() {
return (
<div>
<Card sx={{ maxWidth: 345 }}>
{data.map((item) =>(
<CardMedia component="img" height="140" image={`${data.img}`} alt="home image looding......"/>
<CardContent>
<Typography gutterBottom variant="h5" component="div">{data.name}</Typography>
<Typography variant="body2" color="text.secondary">{data.description}</Typography>
</CardContent>
))}
<CardActions>
<Button size="small">Share</Button>
<Button size="small">Learn More</Button>
</CardActions>
</Card>
</div>
);
}
Change this
{data.map((item) =>(
<CardMedia component="img" height="140" image={`${data.img}`} alt="home image looding......"/>
<CardContent>
<Typography gutterBottom variant="h5" component="div">{data.name}</Typography>
<Typography variant="body2" color="text.secondary">{data.description}</Typography>
</CardContent>
))}
to this
{data.map((item) =>(
<>
<CardMedia component="img" height="140" image={`${data.img}`} alt="home image looding......"/>
<CardContent>
<Typography gutterBottom variant="h5" component="div">{data.name}</Typography>
<Typography variant="body2" color="text.secondary">{data.description}</Typography>
</CardContent>
</>
))}
You should have wrapped the inner element of the map in an empty Tag and also wrap the whole component in an <> </> this empty tag
Related
I am pretty new to Material Ui and ReactJs. i am trying to display cards horizontally and each row has 3 cards. but now its currently displaying only 1 column.
this is a file that calls the cards
import * as React from 'react';
import Jobs from './Jobs'
const jobs1=[{
company:"razer",
jobtitle:"Data engineer",
},{
company:"Huawei",
jobtitle:"Data Engineer"
},{
company:"Huawei",
jobtitle:"Data Engineer"
}]
export default function Header() {
return (
jobs1.map((jobs1)=>(
<Jobs jobs1={jobs1}/>
)))
}
this is the cards file
import React from 'react';
import Card from '#mui/material/Card';
import CardContent from '#mui/material/CardContent';
import CardMedia from '#mui/material/CardMedia';
import img from './image/Razer.png'
import Typography from '#mui/material/Typography';
import {Grid,Box } from '#mui/material'
const Jobs = ({jobs1: {company, jobtitle}})=>{
return (
<Card sx={{ maxWidth: 300 }}>
<CardMedia
component="img"
height="100"
sx={{ width: 100}}
image={img}
alt="razer"
/>
<CardContent>
<Typography style={{color: '#bdbdbd'}}gutterBottom variant="h9" component="div">
{company}
</Typography>
<Typography component="div">
<Box sx={{ fontWeight: 'bold' }}>
{jobtitle}
</Box>
</Typography>
<Grid container direction="row" alignItems="center" gap={14}>
<Typography sx={{fontStyle: 'italic'}} style={{color: '#bdbdbd'}}inline variant="body1" align="left">
1 minute ago
</Typography>
<Typography inline variant="body1" >
<Box sx={{ borderRadius: '12px', p: 1,opacity:"0.5", border: '0.5px solid',color: "#64dd17",bgcolor:"#ccff90" }}>Data</Box>
</Typography>
</Grid>
<Typography style={{color: '#bdbdbd'}}>____________________________</Typography>
</CardContent>
{/* <CardActions>
<Button size="small">Share</Button>
<Button size="small">Learn More</Button>
</CardActions> */}
</Card>
);
}
export default Jobs;
i tried to do use the and flexbox instead of printing out the items everything they delete all the items in the webpage instead.
Try wrapping your parent component in Grid
import * as React from 'react';
import Jobs from './Jobs'
import { Grid } from '#mui/material';
const jobs1=[{
company:"razer",
jobtitle:"Data engineer",
},{
company:"Huawei",
jobtitle:"Data Engineer"
},{
company:"Huawei",
jobtitle:"Data Engineer"
}]
export default function Header() {
return (
<Grid container mt={2} spacing={2}>
jobs1.map((jobs1)=>(
<Jobs jobs1={jobs1}/>
))
</Grid>
)
}
Next: Wrapping you child in Grid
import React from 'react';
import Card from '#mui/material/Card';
import CardContent from '#mui/material/CardContent';
import CardMedia from '#mui/material/CardMedia';
import img from './image/Razer.png'
import Typography from '#mui/material/Typography';
import {Grid,Box } from '#mui/material'
const Jobs = ({jobs1: {company, jobtitle}})=>{
return (
<Grid item xs={4}>
<Card sx={{ maxWidth: 300 }}>
<CardMedia
component="img"
height="100"
sx={{ width: 100}}
image={img}
alt="razer"
/>
<CardContent>
<Typography style={{color: '#bdbdbd'}}gutterBottom variant="h9" component="div">
{company}
</Typography>
<Typography component="div">
<Box sx={{ fontWeight: 'bold' }}>
{jobtitle}
</Box>
</Typography>
<Grid container direction="row" alignItems="center" gap={14}>
<Typography sx={{fontStyle: 'italic'}} style={{color: '#bdbdbd'}}inline variant="body1" align="left">
1 minute ago
</Typography>
<Typography inline variant="body1" >
<Box sx={{ borderRadius: '12px', p: 1,opacity:"0.5", border: '0.5px solid',color: "#64dd17",bgcolor:"#ccff90" }}>Data</Box>
</Typography>
</Grid>
<Typography style={{color: '#bdbdbd'}}>____________________________</Typography>
</CardContent>
{/* <CardActions>
<Button size="small">Share</Button>
<Button size="small">Learn More</Button>
</CardActions> */}
</Card>
</Grid>
);
}
export default Jobs;
For more information you can check the Grid System of MUI
I'm trying to access data from commerceJS API fetched on a different module and passed down as a prop, the code only breaks when I call a nested product object with this error Uncaught TypeError: Cannot read properties of undefined (reading 'source').
Here is my code
//Product.jsx
import React from 'react';
import { Card, CardMedia, CardContent, CardActions, Typography, IconButton } from '#material-ui/core';
import { AddShoppingCart } from '#material-ui/icons';
import useStyles from './styles';
const Product = ({ product, onAddToCart }) => {
const classes = useStyles();
const handleAddToCart = () => onAddToCart(product.id, 1);
return (
<Card className={classes.root}>
<CardMedia
className={classes.media}
image={product.media.source}
component="img"
title={product.name}
/>
<CardContent>
<div className={classes.cardContent}>
<Typography gutterBottom variant="h5" component="h2">
{product.name}
</Typography>
<Typography gutterBottom variant="h5" component="h2">
${product.price.formatted}
</Typography>
</div>
<Typography
dangerouslySetInnerHTML={{ __html: product.description }}
variant="body2"
color="textSecondary"
component="p"
/>
</CardContent>
<CardActions disableSpacing className={classes.cardActions}>
<IconButton aria-label="Add to Cart" onClick={handleAddToCart}>
<AddShoppingCart />
</IconButton>
</CardActions>
</Card>
);
};
export default Product;
import React from 'react';
import { Card, CardMedia, CardContent, CardActions, Typography, IconButton } from '#material-ui/core';
import { AddShoppingCart } from '#material-ui/icons';
import useStyles from './styles';
const Product = ({ product, onAddToCart }) => {
const classes = useStyles();
const handleAddToCart = () => onAddToCart(product.id, 1);
return (
<Card className={classes.root}>
<CardMedia
className={classes.media}
image={product.media.source}
component="img"
title={product.name}
/>
<CardContent>
<div className={classes.cardContent}>
<Typography gutterBottom variant="h5" component="h2">
{product?.name}
</Typography>
<Typography gutterBottom variant="h5" component="h2">
${product?.price?.formatted}
</Typography>
</div>
<Typography
dangerouslySetInnerHTML={{ __html: product.description }}
variant="body2"
color="textSecondary"
component="p"
/>
</CardContent>
<CardActions disableSpacing className={classes.cardActions}>
<IconButton aria-label="Add to Cart" onClick={handleAddToCart}>
<AddShoppingCart />
</IconButton>
</CardActions>
</Card>
);
};
export default Product;
try this code:
import React from 'react';
import { Card, CardMedia, CardContent, CardActions, Typography, IconButton } from '#material-ui/core';
import { AddShoppingCart } from '#material-ui/icons';
import useStyles from './styles';
const Product = ({ product, onAddToCart }) => {
const classes = useStyles();
const handleAddToCart = () => onAddToCart(product.id, 1);
return (
<Card className={classes.root}>
<CardMedia
className={classes.media}
image={product?.media?.source}
component="img"
title={product?.name}
/>
<CardContent>
<div className={classes.cardContent}>
<Typography gutterBottom variant="h5" component="h2">
{product?.name}
</Typography>
<Typography gutterBottom variant="h5" component="h2">
${product?.price?.formatted}
</Typography>
</div>
<Typography
dangerouslySetInnerHTML={{ __html: product?.description }}
variant="body2"
color="textSecondary"
component="p"
/>
</CardContent>
<CardActions disableSpacing className={classes.cardActions}>
<IconButton aria-label="Add to Cart" onClick={handleAddToCart}>
<AddShoppingCart />
</IconButton>
</CardActions>
</Card>
);
};
export default Product;
It'll display the image if I delete the className property and access to my object key
Code here:
<CardMedia
className={classes.media}
image={product.image.url}
component="img"
title={product?.name}
/>
I have used an image as an object with a http link and also and image from the project source folder but it is not showing in the project.
Card and everything is loading up but image is not loading.
image location is public/assests/image
App.js
import React from 'react';
import Products from './components/Products/Products';
function App(props) {
return (
<div>
<Products />
</div>
);
}
export default App;
Products.jsx
import React from 'react';
import { Grid } from '#material-ui/core';
import Product from './Product/Product';
const products = [
{ id: 1, name: 'Shoes', description: 'Running shoes.', price: '$100', image: 'assests/image/run-asics-running-shoes-1636736175.jpeg' },
{ id: 2, name: 'Macbook', description: 'Apple Macbook', price: '$120', image: 'https://images.app.goo.gl/b8T9vFGUzQeHvRmM9' },
]
const Products = () => {
return (
<main>
<Grid container justify="center" spacing={4}>
{products.map((product) => (
<Grid item key={product.id} xs={12} sm={6} md={4} lg={3}>
<Product product={product} />
</Grid>
))}
</Grid>
</main>
)
}
export default Products;
Product component holding all the products
Product.jsx
import React from 'react';
import { Card, CardMedia, CardContent, CardActions, Typography, IconButton } from '#material-ui/core';
import { AddShoppingCart } from '#material-ui/icons';
import useStyles from './styles';
const Product = ({ product }) => {
const classes = useStyles();
return (
<div>
<Card className={classes.root}>
<CardMedia className={classes.media} image='product.image' title={product.name} />
<CardContent>
<div className={classes.cardContent}>
<Typography variant="h5" gutterBottom>
{product.name}
</Typography>
<Typography variant="h5" >
{product.price}
</Typography>
</div>
<Typography variant="body2" color="textSecondary">
{product.description}
</Typography>
</CardContent>
<CardActions disableSpacing className={classes.cardActions}>
<IconButton aria-label="Add to Cart">
<AddShoppingCart />
</IconButton>
</CardActions>
</Card>
</div>
);
}
export default Product;
You're setting image='product.image', which sets it to the literal string "product.image". Perhaps you meant image={product.image}?
<CardMedia
className={classes.media}
image={product.image}
title={product.name}
/>
In products array image with id:1 is ok
but image with id:2 does not contain correct image with HTTP link it should change to correct image link (in google image, right-click:copy image address)
Inside Product.js file, change image property of CardMedia to image={product.image} and it's style={{minHeight:300}}
Products:
const products = [
{ id: 1, name: 'Shoes', description: 'Running shoes.', price: '$100', image: 'assets/image/run.jpeg' },
{ id: 2, name: 'Macbook', description: 'Apple Macbook', price: '$120', image: 'data:image/jpeg;base64,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' },
]
Product
<CardMedia image={product.image} alt={product.name} style={{minHeight:300}}/>
Just replace the image='product.image' with image={product.image} and your problem solved
<CardMedia className={classes.media} image={product.image} title={product.name} />
<CardContent>
<div className={classes.cardContent}>
<Typography variant="h5" gutterBottom>
{product.name}
</Typography>
<Typography variant="h5" >
{product.price}
</Typography>
</div>
<Typography variant="body2" color="textSecondary">
{product.description}
</Typography>
</CardContent>
This is the api I am using https://covid19.mathdro.id/api
I need to take the {recovered.value} and divide it by {confirmed.value} and then multiply the result by 100 to get the recovery percentage.
But these values are coming as string and not number//
this is the file
import React from "react";
import { Card, CardContent, Typography, Grid } from "#material-ui/core";
import CountUp from "react-countup";
import cx from "classnames";
import styles from "./Cards.module.css";
const Info = ({ data: { confirmed, recovered, deaths, lastUpdate } }) => {
if (!confirmed) {
return "Loading...";
}
return (
<div className={styles.container}>
<Grid container spacing={3} justify="center">
<Grid
item
xs={12}
md={3}
component={Card}
className={cx(styles.card, styles.infected)}
>
<CardContent>
<Typography color="textSecondary" gutterBottom>
Infected
</Typography>
<Typography variant="h5" component="h2">
<CountUp
start={0}
end={confirmed.value}
duration={2.75}
separator=","
/>
<div>
{recovered.value}/{confirmed.value}
</div>
</Typography>
<Typography color="textSecondary">
{new Date(lastUpdate).toDateString()}
</Typography>
<Typography variant="body2" component="p">
Number of active cases of COVID-19.
</Typography>
</CardContent>
</Grid>
<Grid
item
xs={12}
md={3}
component={Card}
className={cx(styles.card, styles.recovered)}
>
<CardContent>
<Typography color="textSecondary" gutterBottom>
Recovered
</Typography>
<Typography variant="h5" component="h2">
<CountUp
start={0}
end={recovered.value}
duration={2.75}
separator=","
/>
</Typography>
<Typography color="textSecondary">
{new Date(lastUpdate).toDateString()}
</Typography>
<Typography variant="body2" component="p">
Number of recoveries from COVID-19.
</Typography>
</CardContent>
</Grid>
<Grid
item
xs={12}
md={3}
component={Card}
className={cx(styles.card, styles.deaths)}
>
<CardContent>
<Typography color="textSecondary" gutterBottom>
Deaths
</Typography>
<Typography variant="h5" component="h2">
<CountUp
start={0}
end={deaths.value}
duration={2.75}
separator=","
/>
</Typography>
<Typography color="textSecondary">
{new Date(lastUpdate).toDateString()}
</Typography>
<Typography variant="body2" component="p">
Number of deaths caused by COVID-19.
</Typography>
</CardContent>
</Grid>
</Grid>
</div>
);
};
export default Info;
and I have tried parseInt, in this part of code,for confirmed, but it does not woke
const Info = ({ data: { parseInt(confirmed), recovered, deaths,
lastUpdate } }) => {
if (!confirmed) {
return "Loading...";
}
....
this is my app.js
import React from "react";
import { Cards, CountryPicker, Chart } from "./components";
import { fetchData } from "./api/";
import styles from "./App.module.css";
class App extends React.Component {
state = {
data: {},
country: "",
};
componentWillUpdate() {
console.log("hello");
}
async componentDidMount() {
const data = await fetchData();
this.setState({ data });
console.log("data");
}
handleCountryChange = async (country) => {
const data = await fetchData(country);
this.setState({ data, country: country });
console.log("data");
};
render() {
const { data, country } = this.state;
return (
<div className={styles.container}>
<Cards data={data} />
<CountryPicker handleCountryChange={this.handleCountryChange} />
<Chart data={data} country={country} />
</div>
);
}
}
export default App;
You have bug on your code. I tried to fixed it and able to run it. Please check the update code here:
import React from "react";
import {Card, CardContent, Typography, Grid} from "#material-ui/core";
import CountUp from "react-countup";
import cx from "classnames";
import {makeStyles, useTheme} from '#material-ui/core/styles';
const useStyles = makeStyles(theme => ({
container: {},
infected: {},
recovered: {},
deaths: {}
}));
const Info = ({data: {confirmed, recovered, deaths, lastUpdate}}) => {
const styles = useStyles();
return (
<div className={styles.container}>
<Grid container spacing={3} justify="center">
<Grid
item
xs={12}
md={3}
component={Card}
className={cx(styles.card, styles.infected)}
>
<CardContent>
<Typography color="textSecondary" gutterBottom>
Infected
</Typography>
<Typography variant="h5" component="h2">
<CountUp
start={0}
end={confirmed.value}
duration={2.75}
separator=","
/>
<div>
{recovered.value}/{confirmed.value}
</div>
</Typography>
<Typography color="textSecondary">
{new Date(lastUpdate).toDateString()}
</Typography>
<Typography variant="body2" component="p">
Number of active cases of COVID-19.
</Typography>
</CardContent>
</Grid>
<Grid
item
xs={12}
md={3}
component={Card}
className={cx(styles.card, styles.recovered)}
>
<CardContent>
<Typography color="textSecondary" gutterBottom>
Recovered
</Typography>
<Typography variant="h5" component="h2">
<CountUp
start={0}
end={recovered.value}
duration={2.75}
separator=","
/>
</Typography>
<Typography color="textSecondary">
{new Date(lastUpdate).toDateString()}
</Typography>
<Typography variant="body2" component="p">
Number of recoveries from COVID-19.
</Typography>
</CardContent>
</Grid>
<Grid
item
xs={12}
md={3}
component={Card}
className={cx(styles.card, styles.deaths)}
>
<CardContent>
<Typography color="textSecondary" gutterBottom>
Deaths
</Typography>
<Typography variant="h5" component="h2">
<CountUp
start={0}
end={deaths.value}
duration={2.75}
separator=","
/>
</Typography>
<Typography color="textSecondary">
{new Date(lastUpdate).toDateString()}
</Typography>
<Typography variant="body2" component="p">
Number of deaths caused by COVID-19.
</Typography>
</CardContent>
</Grid>
</Grid>
</div>
);
};
export default Info;
You should should use Info Component in your app component like below:
import React from 'react';
import Info from "./Info";
class App extends React.Component {
render() {
let data = {
confirmed: {value: 245550},
recovered: {value: 4555},
deaths: {value: 4534},
lastUpdate: Date.now()
};
return (
<Info data={data}/>
)
}
}
export default App;
I am using material ui album template for my react app
I want to put different image and different text for each cards for this when I remove this array it create the problems in responsiveness of the cards
I tried to put separte grid for each cards but thats some how solve the issue but that responsiveness of the template does not remain same
here is my demo code
https://codesandbox.io/s/material-demo-pz8df
Make sure you're updating the right cards array. Use an array of objects as well, where each object has a key for an image-link and one for the description. In the .map() we'll use these values to render the content. Here's a working sandbox: https://codesandbox.io/s/material-demo-3v44c
The responsiveness will work like expected.
Working code:
import React from "react";
import AppBar from "#material-ui/core/AppBar";
import Button from "#material-ui/core/Button";
import CameraIcon from "#material-ui/icons/PhotoCamera";
import Card from "#material-ui/core/Card";
import CardActions from "#material-ui/core/CardActions";
import CardContent from "#material-ui/core/CardContent";
import CardMedia from "#material-ui/core/CardMedia";
import CssBaseline from "#material-ui/core/CssBaseline";
import Grid from "#material-ui/core/Grid";
import Toolbar from "#material-ui/core/Toolbar";
import Typography from "#material-ui/core/Typography";
import { makeStyles } from "#material-ui/core/styles";
import Container from "#material-ui/core/Container";
import Link from "#material-ui/core/Link";
function MadeWithLove() {
return (
<Typography variant="body2" color="textSecondary" align="center">
{"Built with love by the "}
<Link color="inherit" href="https://material-ui.com/">
Material-UI
</Link>
{" team."}
</Typography>
);
}
const useStyles = makeStyles(theme => ({
icon: {
marginRight: theme.spacing(2)
},
heroContent: {
backgroundColor: theme.palette.background.paper,
padding: theme.spacing(8, 0, 6)
},
heroButtons: {
marginTop: theme.spacing(4)
},
cardGrid: {
paddingTop: theme.spacing(8),
paddingBottom: theme.spacing(8)
},
card: {
height: "100%",
display: "flex",
flexDirection: "column"
},
cardMedia: {
paddingTop: "56.25%" // 16:9
},
cardContent: {
flexGrow: 1
},
footer: {
backgroundColor: theme.palette.background.paper,
padding: theme.spacing(6)
}
}));
const cards = [
{
img:
"https://images.unsplash.com/photo-1564135624576-c5c88640f235?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=3300&q=80",
desc: "Campsite"
},
{
img:
"https://images.unsplash.com/photo-1564198879220-63f2734f7cec?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2072&q=80",
desc: "Space"
}
];
export default function Album() {
const classes = useStyles();
return (
<React.Fragment>
<CssBaseline />
<AppBar position="relative">
<Toolbar>
<CameraIcon className={classes.icon} />
<Typography variant="h6" color="inherit" noWrap>
Album layout
</Typography>
</Toolbar>
</AppBar>
<main>
{/* Hero unit */}
<div className={classes.heroContent}>
<Container maxWidth="sm">
<Typography
component="h1"
variant="h2"
align="center"
color="textPrimary"
gutterBottom
>
Album layout
</Typography>
<Typography
variant="h5"
align="center"
color="textSecondary"
paragraph
>
Something short and leading about the collection below—its
contents, the creator, etc. Make it short and sweet, but not too
short so folks don't simply skip over it entirely.
</Typography>
<div className={classes.heroButtons}>
<Grid container spacing={2} justify="center">
<Grid item>
<Button variant="contained" color="primary">
Main call to action
</Button>
</Grid>
<Grid item>
<Button variant="outlined" color="primary">
Secondary action
</Button>
</Grid>
</Grid>
</div>
</Container>
</div>
<Container className={classes.cardGrid} maxWidth="md">
{/* End hero unit */}
<Grid container spacing={4}>
{cards.map(card => (
<Grid item key={card} xs={12} sm={6} md={4}>
<Card className={classes.card}>
<CardMedia
className={classes.cardMedia}
image={card.img}
title="Image title"
/>
<CardContent className={classes.cardContent}>
<Typography gutterBottom variant="h5" component="h2">
Heading
</Typography>
<Typography>{card.desc}</Typography>
</CardContent>
<CardActions>
<Button size="small" color="primary">
View
</Button>
<Button size="small" color="primary">
Edit
</Button>
</CardActions>
</Card>
</Grid>
))}
</Grid>
</Container>
</main>
{/* Footer */}
<footer className={classes.footer}>
<Typography variant="h6" align="center" gutterBottom>
Footer
</Typography>
<Typography
variant="subtitle1"
align="center"
color="textSecondary"
component="p"
>
Something here to give the footer a purpose!
</Typography>
<MadeWithLove />
</footer>
{/* End footer */}
</React.Fragment>
);
}