Create card on button click - reactjs

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;*/`

Related

How to make a kind of synoptic table

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.

My react Material UI buttons aren't rendering

I've written the same code everywhere but it doesn't render my buttons. It does render but is not visible. The button are present between the logo and the search input.
There aren't any errors nor build fail to debug the problem.
I tried copying and pasting the code from the second too!
import React from "react";
import { Link } from "react-router-dom";
import { Box, Container, ThemeProvider, Input, useScrollTrigger, Slide, AppBar, Toolbar } from '#mui/material'
import { Button } from "#mui/material";
import customTheme from "./Theme"
function HideOnScroll(props) {
const { children, window } = props;
const trigger = useScrollTrigger({
target: window ? window() : undefined,
});
return (
<Slide appear={false} direction="down" in={!trigger}>
{children}
</Slide>
);
}
const ariaLabel = { 'aria-label': 'description' };
function Navigation(props) {
return (
<Container>
<ThemeProvider theme={ customTheme }>
<HideOnScroll>
<AppBar color={"primary"}>
<Toolbar>
<Box m={1} p={1}>
<Link to=""><img src="/static/brand-logo.svg" alt="brand-logo" /></Link>
</Box>
<Box m={1} p={1}>
<Button variant="outlined" style={{ borderRadius: 20 }} href="/">Home</Button>
<Button variant="outlined" style={{ borderRadius: 20 }} href="/blog">Blogs</Button>
<Button variant="outlined" style={{ borderRadius: 20 }} href="/create-blog">Create</Button>
</Box>
<Box m={1} p={1}>
<Input color={"secondary"} placeholder="Can't search :)" inputProps={ariaLabel} />
</Box>
</Toolbar>
</AppBar>
</HideOnScroll>
<Toolbar />
</ThemeProvider>
</Container>
);
}
export default Navigation;
Another button code which works
import React from "react";
import { Grid, Divider, Typography, Button } from "#mui/material";
import InstagramIcon from '#mui/icons-material/Instagram';
import LinkedInIcon from '#mui/icons-material/LinkedIn';
import GitHubIcon from '#mui/icons-material/GitHub';
export default function Home(props) {
return(
<Grid container spacing={4} justifyContent="center" alignItems="center" color={"primary"}>
<Grid item xs={12} sm={6} lg={4}>
<Typography variant="h1" component="div" gutterBottom>A painting of my life.</Typography>
<Button size="large" variant="outlined" style={{ borderRadius: 50, fontSize: 40 }} href="/blog">Peek My Diary</Button>
</Grid>
</Grid>
);
}

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;

Custom renderInput in material-ui autocomplete

How can I render my Account component in renderInput? I want to render the Account component on both rederInput and renderOptions.
demo.js
/* eslint-disable no-use-before-define */
import React from "react";
import Autocomplete from "#material-ui/lab/Autocomplete";
import { Card, CardContent, Typography, Grid } from "#material-ui/core";
const accounts = [
{
accountNo: "000223187413",
accountName: "Sample1",
money: 1231.32
},
{
accountNo: "000123187412",
accounttName: "Sample2",
money: 10000.0
}
];
function Account({ account }) {
return (
<Card style={{ width: "100%" }}>
<CardContent>
<Typography>{account.accountName}</Typography>
<Typography variant="h6" component="h2">
{account.accountNo}
</Typography>
<Grid container justify="flex-end">
<Typography variant="body1" align="right">
₱{" "}
{new Intl.NumberFormat("en-US", {
minimumFractionDigits: 2
}).format(account.money)}
</Typography>
</Grid>
</CardContent>
</Card>
);
}
export default function ComboBox() {
return (
<Autocomplete
id="combo-box-demo"
options={accounts}
getOptionLabel={(option) => option.accountNo}
style={{ width: 300 }}
renderInput={(account) => <Account account={account} />}
renderOption={(account) => <Account account={account} />}
/>
);
}
CodeSandBox:
https://codesandbox.io/s/material-demo-v3sul?file=/demo.js
You Need not to use the account component in renderInput.
Try this Sandbox link.

Error: Invalid hook call. function using hooks been called inside a list in class

I'm using MaterialUI. I have my Dashboard that has a list of Cards. My Dash is a class that extends React.Component. My Cards are a function that is using Hooks useState. My dash is using .map() to build the list of cards. My cards have a function to "show data".
Dashboard.js
import React from 'react';
import { withStyles } from '#material-ui/core/styles';
import Container from '#material-ui/core/Container';
import Grid from '#material-ui/core/Grid';
import Service from '../app/Service';
import Copyright from '../components/Copyright'
import CardContact from '../components/CardContact'
const styles = theme => ({
root: {
display: 'flex',
paddingTop: '80px'
},
appBarSpacer: theme.mixins.toolbar,
content: {
flexGrow: 1,
height: '100vh',
overflow: 'auto',
},
container: {
paddingTop: theme.spacing(4),
paddingBottom: theme.spacing(4),
},
});
class Dashboard extends React.Component {
state ={
}
componentDidMount() {
this.contactsFormatted();
}
contactsFormatted = async () => {
try {
const res = await Service.get('/all-contacts');
const contacts = res.data;
this.setState({
Contacts: contacts.map((contact, i) => (
CardContact(contact, i)
))
})
} catch(err){
console.log(err)
}
}
render(){
const { classes } = this.props;
return (
<div className={classes.root}>
<Container maxWidth="lg" className={classes.container}>
<Grid container spacing={3}>
{this.state.Contacts}
</Grid>
<Copyright />
</Container>
</div>
);
}
}
export default withStyles(styles)(Dashboard);
My CardContact.js
import React from 'react'
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 Collapse from '#material-ui/core/Collapse';
const CardContact = ({name, office, occupation_area, tel, email}, i) => {
const [expanded, setExpanded] = React.useState(false);
const handleExpandClick = () => {
setExpanded(!expanded);
}
return (
<Grid xs={12} style={{ paddingBottom: 32 }} key={i} item={true}>
<Card >
<CardContent>
<Typography variant="h5" component="h2">
Nome: {name}
</Typography>
<Typography color="textSecondary" gutterBottom>
Cargo: {office}
</Typography>
<Typography color="textSecondary" gutterBottom>
Área de atuação: {occupation_area}
</Typography>
</CardContent>
<CardActions style={{justifyContent: 'flex-end'}} >
<Button size="small"
onClick={handleExpandClick}
aria-expanded={expanded}>Revelar</Button>
</CardActions>
<Collapse in={expanded} timeout="auto" unmountOnExit>
<CardContent>
<Typography color="textSecondary" gutterBottom>
Telefone: {tel}
</Typography>
<Typography color="textSecondary" gutterBottom>
E-mail: {email}
</Typography>
</CardContent>
</Collapse>
</Card>
</Grid>
)
}
export default CardContact;
what's wrong with the Hooks usage?
You are calling CardContact inside contactsFormatted method. Hence React is throwing the error as contactsFormatted is not a valid React component. React components with hooks should only be invoked/rendered from a valid render function of a React component (class or functional).
Try this :
contactsFormatted = async () => {
try {
const res = await Service.get('/all-contacts');
const contacts = res.data;
this.setState({contacts})
} catch(err){
console.log(err)
}
}
And in render :
render(){
const { classes } = this.props;
return (
<div className={classes.root}>
<Container maxWidth="lg" className={classes.container}>
<Grid container spacing={3}>
{this.state.contacts.map((contact, i) => (
<CardContact contact={contact} index={i} />
)}
</Grid>
<Copyright />
</Container>
</div>
);
}
Now the full data will be available in CardContact component as contact prop
As mentioned by an earlier answer, this is not the right approach, to render cards. Instead of storing the components in the Contacts state, you should store the objects corresponding to the cards in the Contacts state, like this:
contactsFormatted = async () => {
try {
const res = await Service.get('/all-contacts');
const contacts = res.data;
this.setState({
Contacts: [...Contacts].concat(contacts),
})
} catch(err){
console.log(err)
}
}
Further, you should render the cards as below:
return (
<div className={classes.root}>
<Container maxWidth="lg" className={classes.container}>
<Grid container spacing={3}>
{(this.state.Contacts || []).map((contact, i) => <CardContact contact={contact} i={i} />)}
</Grid>
<Copyright />
</Container>
</div>
);

Resources