How to make a kind of synoptic table - reactjs

Excuse me for having to ask, but the following topic is costing me a lot.
I want to make a table with connections, but I can't find the formula to do it, and I couldn't find any example, I tried to find an example and copy its code but it doesn't convince me either. This is what I want to do:
enter image description here
The idea is that, this is how I currently have it:
`
import React from "react";
import { useState, useEffect } from "react";
import { makeStyles } from "#material-ui/core/styles";
import Card from "#material-ui/core/Card";
import CardActions from "#material-ui/core/CardActions";
import CardContent from "#material-ui/core/CardContent";
import Button from "#material-ui/core/Button";
import Typography from "#material-ui/core/Typography";
import Grid from "#material-ui/core/Grid";
import Paper from "#material-ui/core/Paper";
import MundialButtons from "../../componentes/mundial-buttons";
const useStyles = makeStyles((theme) => ({
root: {
minWidth: 100,
maxWidth: 250,
flexGrow: 1
},
bullet: {
display: "inline-block",
margin: "0 2px",
transform: "scale(0.8)"
},
title: {
fontSize: 14
},
pos: {
marginBottom: 12
},
paper: {
padding: theme.spacing(2),
textAlign: "center",
color: theme.palette.text.primary
},
logo: {
float: "left"
}
}));
export default function Two() {
const url =
"https://adad1EUmIOwosuGTI7L2DD6S02RjOG7vbxU3FjVVD1u-iYiw/a!A1:Z1000";
const [todos, setTodos] = useState();
const fetchApi = async () => {
const response = await fetch(url);
const responseJSON = await response.json();
setTodos(responseJSON);
};
useEffect(() => {
fetchApi();
}, []);
const classes = useStyles();
const styleRed2 = [
{ marginTop: "90px" },
{ marginTop: "180px" },
{ marginTop: "270px" }
];
return (
<div id="all">
<MundialButtons />
<div className={classes.root}>
<Grid container spacing={3}>
<Grid item xs={12}>
<Paper className={classes.paper}>
<Typography>asd</Typography>
</Paper>
</Grid>
</Grid>
</div>
<div id="all">
{!todos
? "Cargando..."
: todos.map((todo, index) => {
return (
<Grid item xs={6}>
<div className={classes.root} id="octavos">
{todo.Local === undefined ||
todo.Local === "" ||
todo.Visitante === undefined ||
todo.Visitante === "" ? (
<div></div>
) : (
<Card className={classes.root} variant="outlined">
<CardContent>
<Typography
className={classes.title}
color="textSecondary"
gutterBottom
>
Octavos:
</Typography>
<Typography variant="h5" component="h2">
test
</Typography>
<Typography variant="h5" component="h2">
test
</Typography>
{/*<Typography
className={classes.pos}
color="textSecondary"
>
hora
</Typography>*/}
</CardContent>
</Card>
)}
<p></p>
</div>
</Grid>
);
})}
</div>
</div>
);
}
`
A box with connections between them

It's probably best to lean on open-source libraries for this, no need to reinvent the wheel. As it happens, what you require kind of already exists: https://www.npmjs.com/package/#g-loot/react-tournament-brackets. Demo.

Related

Use Refs In Material UI

I'm trying to use Refs in Material UI to change Image src but it gives me an 'Undefined' error. It looks like the link is getting created but not being applied as the Images src, I feel like the problem lies in line 10 .
CodeSandBox - https://codesandbox.io/s/complexgrid-material-demo-forked-h6zfqh?file=/demo.tsx
const [loading] = useState(true);
const imageRef = React.useRef();
let txt = "IGO";
useEffect(() => {
imageRef.current.src = `https://flightaware.com/images/airline_logos/90p/${txt}.png`;
console.log(imageRef.current.src);
},
[loading, imageRef]);
<ButtonBase sx={{ width: 128, height: 128 }}>
<Img alt="complex" ref={imageRef} />
</ButtonBase>
You can use a list of references an change the image like you was doing.
I let you a functional code that it works like I think you want :)
import * as React from "react";
import { styled } from "#mui/material/styles";
import Grid from "#mui/material/Grid";
import D34, { useEffect, useState } from "react";
import Paper from "#mui/material/Paper";
import Typography from "#mui/material/Typography";
import ButtonBase from "#mui/material/ButtonBase";
import Data from "./abc.json";
const Img = styled("img")({
margin: "auto",
display: "block",
maxWidth: "100%",
maxHeight: "100%"
});
export default function ComplexGrid() {
const [loading] = useState(true);
const imagesRef = [];
let txt = "IGO";
useEffect(() => {
imagesRef.forEach((refImg) => {
refImg.src = `https://flightaware.com/images/airline_logos/90p/${txt}.png`;
});
/*imageRef.current.src = `https://flightaware.com/images/airline_logos/90p/${txt}.png`;
console.log(imageRef.current.src);*/
}, [loading]);
return (
<div className="hello">
{Data.response.map((post, posPost) => {
return (
<Paper
sx={{
pt: 1,
border: 1,
boxShadow: 0,
mt: 1,
maxWidth: 900,
flexGrow: 1,
backgroundColor: (theme) =>
theme.palette.mode === "dark" ? "#1A2027" : "#fff"
}}
>
<Grid container spacing={2}>
<Grid item>
<ButtonBase sx={{ width: 128, height: 128 }}>
<Img alt="complex" ref={(imageRef) => {
if (!imagesRef[posPost]) {
imagesRef.push(imageRef);
}
}} />
</ButtonBase>
</Grid>
<Grid item xs={12} sm container>
<Grid item xs container direction="column" spacing={2}>
<Grid item xs>
<Typography
gutterBottom
variant="subtitle1"
component="div"
>
Standard license
</Typography>
<Typography variant="body2" gutterBottom>
Full resolution 1920x1080 • JPEG
</Typography>
<Typography variant="body2" color="text.secondary">
ID: 1030114
</Typography>
</Grid>
<Grid item></Grid>
</Grid>
<Grid item>
<Typography
variant="subtitle1"
component="div"
sx={{ px: 2, p: 2 }}
>
$19.00
</Typography>
</Grid>
</Grid>
</Grid>
</Paper>
);
})}
</div>
);
}
you can use useState to change the src
const [img, setImg] = useState()
let txt = "IGO";
useEffect(() => {
setImg(`https://flightaware.com/images/airline_logos/90p/${txt}.png`)
}, [loading]);
{img && <Img alt="complex" src={img} />}
The main problem is the way to use ref.
At the moment, you are using same ref for same image component.
In order to manage the image tags well, you should use different ref for each image tab.
Please refer this code.
import * as React from "react";
import { styled } from "#mui/material/styles";
import Grid from "#mui/material/Grid";
import D34, { useEffect, useState } from "react";
import Paper from "#mui/material/Paper";
import RootRef from "#material-ui/core/RootRef";
import Typography from "#mui/material/Typography";
import ButtonBase from "#mui/material/ButtonBase";
import Data from "./abc.json";
import { red } from "#mui/material/colors";
const Img = styled("img")({
margin: "auto",
display: "block",
maxWidth: "100%",
maxHeight: "100%"
});
export default function ComplexGrid() {
const [loading] = useState(true);
const imageRef = React.useRef();
let txt = "IGO";
useEffect(() => {
console.log(imageRef.current.src);
if (imageRef.current.src === "")
imageRef.current.src = `https://flightaware.com/images/airline_logos/90p/${txt}.png`;
}, [loading, imageRef]);
return (
<div className="hello">
<Img alt="complex" ref={imageRef} />
{Data.response.map((post) => {
return (
<Paper
sx={{
pt: 1,
border: 1,
boxShadow: 0,
mt: 1,
maxWidth: 900,
flexGrow: 1,
backgroundColor: (theme) =>
theme.palette.mode === "dark" ? "#1A2027" : "#fff"
}}
>
<Grid container spacing={2}>
<Grid item>
<ButtonBase sx={{ width: 128, height: 128 }}>
{/* <Img alt="complex" ref={imageRef} /> */}
</ButtonBase>
</Grid>
<Grid item xs={12} sm container>
<Grid item xs container direction="column" spacing={2}>
<Grid item xs>
<Typography
gutterBottom
variant="subtitle1"
component="div"
>
Standard license
</Typography>
<Typography variant="body2" gutterBottom>
Full resolution 1920x1080 • JPEG
</Typography>
<Typography variant="body2" color="text.secondary">
ID: 1030114
</Typography>
</Grid>
<Grid item></Grid>
</Grid>
<Grid item>
<Typography
variant="subtitle1"
component="div"
sx={{ px: 2, p: 2 }}
>
$19.00
</Typography>
</Grid>
</Grid>
</Grid>
</Paper>
);
})}
</div>
);
}
Hope it would be helpful for you.
Thanks

Putting gradient background using makeStyles

For some reason, it doesn't respect background: 'linear-gradient(to right, blue.200, blue.700)' under makeStyles. Why is that? All I need to do is put a gradient background on the entire space. <Container className={classes.root}> should probably be a div, what do you think?
import { useState, useEffect } from 'react';
import type { NextPage } from 'next';
import Container from '#mui/material/Container';
import Box from '#mui/material/Box';
import { DataGrid, GridColDef } from '#mui/x-data-grid';
import { createStyles, Grid, Paper, Theme, Typography } from '#mui/material';
import { makeStyles } from '#mui/styles';
import Skeleton from '#mui/material/Skeleton';
import FormOne from './../src/FormOne';
const LoadingSkeleton = () => (
<Box
sx={{
height: 'max-content',
}}
>
{[...Array(10)].map((_, index) => (
<Skeleton variant="rectangular" sx={{ my: 4, mx: 1 }} key={index} />
))}
</Box>
);
const columns: GridColDef[] = [
{ field: 'id', headerName: 'ID' },
{ field: 'title', headerName: 'Title', width: 300 },
{ field: 'body', headerName: 'Body', width: 600 },
];
const useStyles = makeStyles((theme: Theme) =>
createStyles({
root: {
height: '100vh',
overflow: 'auto',
background: `linear-gradient(to right, blue.200, blue.700)`,
},
})
);
const Home: NextPage = () => {
const classes = useStyles();
const [posts, setPosts] = useState([]);
const [loading, setLoading] = useState(true);
// fetch data from fake API
useEffect(() => {
setInterval(
() =>
fetch('https://jsonplaceholder.typicode.com/posts')
.then((response) => response.json())
.then((data) => {
setPosts(data);
setLoading(false);
}),
3000
);
}, []);
return (
<Container
maxWidth={false}
// sx={{
// height: '100vh',
// overflow: 'auto',
// background: `linear-gradient(to right, ${blue[200]}, ${blue[700]})`,
// }}
className={classes.root}
>
<Container component="main" maxWidth="lg" sx={{ mt: 3, mb: 3 }}>
<Grid container spacing={{ xs: 2, md: 3 }}>
<Grid item xs={6}>
<Paper sx={{ padding: 3 }}>
<Typography component="h1" variant="h4" align="center">
GUI #1
</Typography>
<FormOne />
</Paper>
</Grid>
<Grid item xs={6}>
<Paper sx={{ padding: 3 }}>
<Typography component="h1" variant="h4" align="center">
GUI #2
</Typography>
<FormOne />
</Paper>
</Grid>
<Grid item xs={12}>
<Paper sx={{ padding: 3 }}>
<DataGrid
sx={{ height: '650px' }} // either autoHeight or this
rows={posts}
columns={columns}
pageSize={10}
// autoHeight
rowsPerPageOptions={[10]}
disableSelectionOnClick
disableColumnMenu
disableColumnSelector
components={{
LoadingOverlay: LoadingSkeleton,
}}
loading={loading}
/>
</Paper>
</Grid>
</Grid>
</Container>
</Container>
);
};
export default Home;
I think its because you pass it as a string and it simply doesnt recognice what blue.200 is etc.
try:
background: `linear-gradient(to right, ${blue[200]}, ${blue[700])}`,
#Edit
You actualy need to import color that you want to use from #mui/color
import { blue } from "#mui/material/colors";
and then use it as I mentioned before
here is codesandbox preview and here is codesandbox code
hope this is what we want to achieve
Instead of using background use backgroundImage. This should fix the problem.
The code should be
backgroundImage: `linear-gradient(to right, blue[200], blue[700])`,

Create card on button click

so I've made a calendar with some text fields underneath that you can fill in.
How can I make it so that when you fill in everything here and click on the button, that it automatically creates a card with the stuff filled in above?
Firebase works without problems and everything you fill in also arrives in the database
It should look like this if you click on the button
And here my code:
import React, { useState } from "react";
import { makeStyles } from "#material-ui/core/styles";
import TextField from "#material-ui/core/TextField";
import Card from "#material-ui/core/Card";
import CardActions from "#material-ui/core/CardActions";
import CardContent from "#material-ui/core/CardContent";
import Button from "#material-ui/core/Button";
import Typography from "#material-ui/core/Typography";
import Paper from "#material-ui/core/Paper";
import { Checkbox, Container, Slide } from "#material-ui/core";
import Icon from "#material-ui/core/Icon";
import { StyleSheet } from "react-native";
import firebase from "firebase/app";
import "firebase/firestore";
import { db } from "../../firebase";
import { ScrollView } from "react-native-gesture-handler";
export default function DateAndTimePickers() {
const classes = useStyles();
const [ort, setOrt] = useState("");
const [notiz, setNotiz] = useState("");
const [hinweis, setHinweis] = useState("");
const [eintragen, setEintragen] = useState([]);
const [dateandtime, setDateandtime] = useState([]);
function handelDateandTime(e) {
setDateandtime(e.target.value);
}
function handelOrt(e) {
setOrt(e.target.value);
}
function handelNotiz(e) {
setNotiz(e.target.value);
}
function handelHinweis(e) {
setHinweis(e.target.value);
}
function KalenderEintrag() {
db.collection("Eintrag")
.doc()
.set({
ort,
notiz,
hinweis,
dateandtime,
})
.then(() => {
//If you wish to push the written data to your local state, you can do it here
setEintragen([...eintragen, { ort, notiz, hinweis, dateandtime }]);
console.log("Documents saved succesfully");
})
.catch((err) => {
console.log(err);
});
}
return (
<ScrollView style={styles.root}>
<Container>
<TextField
id="datetime-local"
label="Neues Ereigniss"
type="datetime-local"
defaultValue="2021-09-16T10:30"
className={classes.root}
InputLabelProps={{
shrink: true,
}}
onChange={(value) => {
handelDateandTime(value);
}}
/>
</Container>
{/* ORT */}
<Container className={classes.ortContainer}>
<TextField
id="standard-helperText"
label="Ort"
defaultValue="Text"
onChange={(value) => {
handelOrt(value);
}}
/>
</Container>
{/* Hinweis */}
<Container className={classes.ortContainer}>
<TextField
id="standard-helperText"
label="Hinweis"
defaultValue="Text"
onChange={(value) => {
handelHinweis(value);
}}
/>
</Container>
{/* Notizen */}
<Container className={classes.ortContainer}>
<TextField
id="standard-helperText"
label="Notizen"
defaultValue="Text"
onChange={(value) => {
handelNotiz(value);
}}
/>
</Container>
<Container>
<Button onClick={() => KalenderEintrag()} className={classes.btn} variant="outlined">Absenden</Button>
</Container>
{/* Kalender einträge */}
<Card className={classes.card}>
<CardContent>
<Typography
className={classes.title}
color="textSecondary"
gutterBottom
>
AUSFLUG
</Typography>
<Typography variant="h5" component="h2">
Wilheminenberg
</Typography>
<Typography className={classes.pos} color="textSecondary">
Jause wird mitgegeben
</Typography>
<Typography variant="body2" component="p">
Am 13.9.21 von 09:00 - 13:00
<br />
{"Abholung erfolgt im KG"}
</Typography>
</CardContent>
<CardActions>
<Button size="small" variant="outlined">
Zur Kenntniss genommen
</Button>
</CardActions>
</Card>
</ScrollView>
);
}
//material UI style
const useStyles = makeStyles({
root: {
marginTop: 30,
marginLeft: 16,
},
card: {
marginTop: 30,
marginLeft: 15,
marginRight: 15,
},
bullet: {
display: "inline-block",
margin: "0 2px",
transform: "scale(0.8)",
},
title: {
fontSize: 14,
},
pos: {
marginBottom: 12,
},
table: {
marginTop: 30,
},
ortContainer: {
marginTop: 30,
marginLeft: 15,
marginRight: 15,
},
btn:{
marginTop: 20,
marginLeft: 15,
}
});
//React native style
const styles = StyleSheet.create({
root: {
backgroundColor: "white",
},
});
Just like that https://codesandbox.io/s/peaceful-hugle-ufkso
{/* Kalender einträge */}
{eintragen.map((item) => {
return (
<Card className={classes.card}>
<CardContent>
<Typography
className={classes.title}
color="textSecondary"
gutterBottom
>
{item.ort}
</Typography>
<Typography variant="h5" component="h2">
{item.notiz}
</Typography>
<Typography className={classes.pos} color="textSecondary">
{item.hinweis}
</Typography>
<Typography variant="body2" component="p">
{item.dateandtime}
<br />
{"Abholung erfolgt im KG"}
</Typography>
</CardContent>
<CardActions>
<Button size="small" variant="outlined">
Zur Kenntniss genommen
</Button>
</CardActions>
</Card>
)
})}
You can reference variables within your JSX code with curly brackets (this has already been done to apply styles for example at {classes.ortContainer}). Replacing text by variables works the same way, so for example replace "Wilheminenberg" by {ort} to have your website display the respective value.
import the card on react-bootstrab or material ui ,the use this method
**const [open ,setOpen] = useState(false);
enter code here
import React,{useState} from 'react';
import {Card} from '#material-ui/core'
function CreateCardButtonOnClick(){
const [open, setOpen] =useState(false);
const OpenCard=()=>{
setOpen(true);
};
const closeCard =()=>{
setOpen(false);
};
return(
<div>
<span>click to open Card viwe</span>
<button onClick={openCard}>openCard</button>
<Card>
<h1 onClick={openCard}>close</h1>
</Card>
</div>
)
export defult CreateCardButtonOnClick;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.6/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/0.14.6/react-dom.min.js"></script>
`/* import React,{useState} from 'react';
import {Card} from '#material-ui/core'
function CreateCardButtonOnClick(){
const [open, setOpen] =useState(false);
const OpenCard=()=>{
setOpen(true);
};
const closeCard =()=>{
setOpen(false);
};
return(
<div>
<span>click to open Card viwe</span>
<button onClick={openCard}>openCard</button>
<Card>
<h1 onClick={openCard}>close</h1>
</Card>
</div>
)
export defult CreateCardButtonOnClick;*/`

How can I reuse code wrapping Material-UI's Grid while varying the number of columns?

I would like the second grid block under the title "Other Projects of Note" to be mapped through as a 3 column grid. How can I do this without creating a new component? Material-UI controls it's columns with the grid item xs={12} sm={6} and on the 3 column grid I'd need it to read as grid item xs={12} sm={6} lg={4}.
It seems like I'd be copying and pasting the <Card /> component and renaming it to achieve this. I'd like to avoid that. Demo below:
codesandbox
Here's the code for my current Card component:
import React from 'react';
import Grid from '#material-ui/core/Grid';
import Card from '#material-ui/core/Card';
import CardActionArea from '#material-ui/core/CardActionArea';
import CardActions from '#material-ui/core/CardActions';
import { makeStyles } from '#material-ui/core/styles';
import { loadCSS } from 'fg-loadcss';
import CardContent from '#material-ui/core/CardContent';
import CardMedia from '#material-ui/core/CardMedia';
import Button from '#material-ui/core/Button';
import Typography from '#material-ui/core/Typography';
import Box from '#material-ui/core/Box';
import Icon from '#material-ui/core/Icon';
import GitHubIcon from '#material-ui/icons/GitHub';
import Tooltip from '#material-ui/core/Tooltip';
import Zoom from '#material-ui/core/Zoom';
import Link from '#material-ui/core/Link';
const useStyles = makeStyles((theme) => ({
root: {
maxWidth: '100%',
flexGrow: 1,
},
cardGrid: {
paddingTop: theme.spacing(2),
},
media: {
height: 340,
},
button: {
margin: theme.spacing(1),
},
arrow: {
color: theme.palette.common.black,
},
tooltip: {
backgroundColor: theme.palette.common.black,
},
icons: {
'& > .fab': {
marginRight: theme.spacing(4),
},
margin: '1rem 0',
},
}));
function TwoCard(props) {
const classes = useStyles();
React.useEffect(() => {
const node = loadCSS(
'https://use.fontawesome.com/releases/v5.12.0/css/all.css',
document.querySelector('#font-awesome-css')
);
return () => {
node.parentNode.removeChild(node);
};
}, []);
return (
<>
<Grid item xs={12} sm={6}>
<Card>
<CardActionArea>
<CardMedia
className={classes.media}
image={props.card.image}
title='Contemplative Reptile'
/>
<CardContent className={classes.content}>
<Typography gutterBottom variant='h5' component='h2'>
{props.card.project}
</Typography>
<Typography variant='subtitle1' gutterBottom>
{props.card.framework}
</Typography>
<Typography gutterBottom variant='body2' component='p'>
{props.card.description}
</Typography>
<Box className={classes.icons}>
<Typography gutterBottom variant='subtitle2'>
TOOLS USED
</Typography>
<Tooltip
TransitionComponent={Zoom}
arrow
title='REACT'
aria-label='react'
>
<Icon className='fab fa-react fa-3x' color='primary' />
</Tooltip>
<Tooltip
TransitionComponent={Zoom}
arrow
title='HTML5'
aria-label='add'
>
<Icon className='fab fa-html5 fa-3x' color='primary' />
</Tooltip>
<Tooltip
TransitionComponent={Zoom}
arrow
title='CSS3'
aria-label='add'
>
<Icon className='fab fa-css3 fa-3x' color='primary' />
</Tooltip>
</Box>
</CardContent>
</CardActionArea>
<CardActions>
<Button variant='outlined' size='small' color='primary'>
<Link
href={props.card.projectUrl}
target='_blank'
rel='noopener noreferrer'
className={classes.links}
underline='none'
color='inherit'
>
View Project
</Link>
</Button>
<Button
variant='outlined'
size='small'
color='primary'
className={classes.button}
endIcon={<GitHubIcon />}
>
<Link
href={props.card.githubUrl}
target='_blank'
rel='noopener noreferrer'
underline='none'
color='inherit'
>
Code
</Link>
</Button>
</CardActions>
</Card>
</Grid>
</>
);
}
export default TwoCard;
and here's the code that uses that Card component:
import React from "react";
import Grid from "#material-ui/core/Grid";
import Card from "./Card.js";
import { Typography } from "#material-ui/core";
import { makeStyles } from "#material-ui/core/styles";
const useStyles = makeStyles((theme) => ({
headings: {
padding: "20px 0"
}
}));
function Projects(props) {
const classes = useStyles();
let cards = props.data.map((card, i) => {
return <Card card={card} key={i} />;
});
return (
<>
<Typography variant="h4" gutterBottom>
Featured Projects
</Typography>
<Grid container spacing={2}>
{cards}
</Grid>
<Typography variant="h4" className={classes.headings}>
Other Projects of note
</Typography>
<Grid container spacing={2}>
{cards}
</Grid>
</>
);
}
export default Projects;
You can pass a prop to your Card component to control whether it is two-column or three-column. For instance, you can pass a maxColumns prop and use it in the following manner:
<Grid item xs={12} sm={6} lg={maxColumns > 2 ? 4 : undefined}>
Then your Projects component can pass the prop (in my example, I'm defaulting maxColumns to 2, so it doesn't need to be specified in that case):
import React from "react";
import Grid from "#material-ui/core/Grid";
import Card from "./Card.js";
import { Typography } from "#material-ui/core";
import { makeStyles } from "#material-ui/core/styles";
const useStyles = makeStyles((theme) => ({
headings: {
padding: "20px 0"
}
}));
function Projects(props) {
const classes = useStyles();
let twoColumnCards = props.data.map((card, i) => {
return <Card card={card} key={i} />;
});
let threeColumnCards = props.data.map((card, i) => {
return <Card maxColumns={3} card={card} key={i} />;
});
return (
<>
<Typography variant="h4" gutterBottom>
Featured Projects
</Typography>
<Grid container spacing={2}>
{twoColumnCards}
</Grid>
<Typography variant="h4" className={classes.headings}>
Other Projects of note
</Typography>
<Grid container spacing={2}>
{threeColumnCards}
</Grid>
</>
);
}
export default Projects;

Material UI Grid keeps displaying as a column

I have been working with Material UI grid and I am trying to display data in a grid of cards that show in rows as opposed to a single column. My grid currently displays like this stacked in a column(please ignore the size of the cards this is just a zoomed in screenshot):
I would like the grid to display like this in rows as opposed to a single column:
I feel like I'm missing something simple but I'm just not sure why it keeps stacking in a single column. The code is as follows:
import React, { useState, useEffect } from "react"
// components
import Grid from "#material-ui/core/Grid"
import { makeStyles } from "#material-ui/core/styles"
import axios from "axios"
import RepoCard from "../components/RepoCard"
import Container from "#material-ui/core/Container"
// context
const Profile = () => {
const [data, setData] = useState(null)
const fetchGit = () => {
axios
.get(`https://api.github.com/users/rterrell25/repos?`)
.then((res) => {
setData(res.data)
console.log(res.data)
})
.catch((err) => console.log(err))
}
useEffect(() => {
fetchGit()
}, [])
return (
<div style={{ marginTop: 85 }}>
{!data ? (
<h1>Loading...</h1>
) : (
data.map((user) => (
<Container>
<Grid container spacing={4}>
<RepoCard name={user.name} />
</Grid>
</Container>
))
)}
</div>
)
}
export default Profile
the Repo Card Component code:
import React from "react"
import { Link } from "react-router-dom"
// MUI stuff
import Button from "#material-ui/core/Button"
import { makeStyles } from "#material-ui/core/styles"
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 Grid from "#material-ui/core/Grid"
import Typography from "#material-ui/core/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 MovieCard = ({ name }) => {
const classes = useStyles()
return (
<Grid item xs={12} sm={6} md={4}>
<Card className={classes.card}>
<CardMedia
className={classes.cardMedia}
image={"#"}
title='Movie nane'
/>
<CardContent className={classes.cardContent}>
<Typography gutterBottom variant='h5' component='h2'>
"Movie name"
</Typography>
<Typography>Genre: Comedy</Typography>
<Typography noWrap>"Movie Summary"</Typography>
</CardContent>
<CardActions>
<Link to={""}>
<Button size='small' color='primary'>
Details
</Button>
</Link>
</CardActions>
</Card>
</Grid>
)
}
export default MovieCard
Change the xs={12} to xs={4}
The grid creates visual consistency between layouts while allowing flexibility across a wide variety of designs. Material Design’s responsive UI is based on a 12-column grid layout.
Refer: document of Material-UI Grid

Resources