diff --git a/package-lock.json b/package-lock.json index 4f2a33b51e0f606aa3bfba9ff05c49106b875b0a..67494d4b1b10e970c32ebf7e13f790d808a31cd5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1293,12 +1293,22 @@ }, "dependencies": { "dom-helpers": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.1.3.tgz", - "integrity": "sha512-nZD1OtwfWGRBWlpANxacBEZrEuLa16o1nh7YopFWeoF68Zt8GGEmzHu6Xv4F3XaFIC+YXtTLrzgqKxFgLEe4jw==", + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.1.4.tgz", + "integrity": "sha512-TjMyeVUvNEnOnhzs6uAn9Ya47GmMo3qq7m+Lr/3ON0Rs5kHvb8I+SQYjLUSYn7qhEm0QjW0yrBkvz9yOrwwz1A==", "requires": { - "@babel/runtime": "^7.6.3", + "@babel/runtime": "^7.8.7", "csstype": "^2.6.7" + }, + "dependencies": { + "@babel/runtime": { + "version": "7.9.2", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.9.2.tgz", + "integrity": "sha512-NE2DtOdufG7R5vnfQUTehdTfNycfUANEtCa9PssN9O/xmTzP4E08UI797ixaei6hBEVL9BI/PsdJS5x7mWoB9Q==", + "requires": { + "regenerator-runtime": "^0.13.4" + } + } } }, "hoist-non-react-statics": { @@ -1319,6 +1329,11 @@ "loose-envify": "^1.4.0", "prop-types": "^15.6.2" } + }, + "regenerator-runtime": { + "version": "0.13.5", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz", + "integrity": "sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA==" } } }, @@ -4097,9 +4112,9 @@ } }, "clsx": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.0.4.tgz", - "integrity": "sha512-1mQ557MIZTrL/140j+JVdRM6e31/OA4vTYxXgqIIZlndyfjHpyawKZia1Im05Vp9BWmImkcNrNtFYQMyFcgJDg==" + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.1.0.tgz", + "integrity": "sha512-3avwM37fSK5oP6M5rQ9CNe99lwxhXDOeSWVPAOYF6OazUTgZCMb0yWlJpmdD74REy1gkEaFiub2ULv4fq9GUhA==" }, "co": { "version": "4.6.0", @@ -15057,4 +15072,4 @@ } } } -} +} \ No newline at end of file diff --git a/package.json b/package.json index 7e622c12bee3695fcec81dc85ab8ad3e473ab53b..215caa168b504f97738455b08f1bf96fa2370f90 100644 --- a/package.json +++ b/package.json @@ -41,4 +41,4 @@ "last 1 safari version" ] } -} +} \ No newline at end of file diff --git a/src/App.js b/src/App.js index a2f07a02b36483aa24bfafd0ae284a0838a46430..a11c029f268fa27b4d93b8ef96872dae8de4b804 100644 --- a/src/App.js +++ b/src/App.js @@ -7,6 +7,7 @@ import Header from "./components/header/header"; import Footer from "./components/footer/footer"; import SignUp from "./pages/SignUp"; import SignIn from "./pages/SignIn"; +import ListForms from "./pages/ListForms"; function App() { return ( @@ -16,6 +17,7 @@ function App() { <Route path="/answer/:id" component={AnswerForm} /> <Route path="/SignUp" component={SignUp} /> <Route path="/SignIn" component={SignIn} /> + <Route path="/list/:id" component={ListForms} /> <Footer /> </HashRouter> ); diff --git a/src/components/fieldsCreateForm/FormFieldSubform.js b/src/components/fieldsCreateForm/FormFieldSubform.js index b99dce2256cbea3e1bbff3f85fc6b9a0273a8c43..e04e839df991de52168c922d74b9323bd3f20b68 100644 --- a/src/components/fieldsCreateForm/FormFieldSubform.js +++ b/src/components/fieldsCreateForm/FormFieldSubform.js @@ -67,7 +67,6 @@ function SubformSelect(props) { const classes = useStyles(); /** Functions that handle the input changes to save it at the father component. */ const handleChange = (event) => { - console.log(event.target); props.setSubformId(event.target.value, props.idq); }; return ( @@ -96,10 +95,10 @@ function SubformSelect(props) { </MenuItem> )) ) : ( - <MenuItem key={0} value={0} disabled> - {"Você não tem formulários para usar aqui"} - </MenuItem> - )} + <MenuItem key={0} value={0} disabled> + {"Você não tem formulários para usar aqui"} + </MenuItem> + )} </Select> </FormControl> ); diff --git a/src/components/fieldsListForms/CardForm.jsx b/src/components/fieldsListForms/CardForm.jsx new file mode 100644 index 0000000000000000000000000000000000000000..40fc1f864a0643ec015b56cdb82b408cde260864 --- /dev/null +++ b/src/components/fieldsListForms/CardForm.jsx @@ -0,0 +1,142 @@ +import React, { useState, useEffect } from "react"; +import Divider from "@material-ui/core/Divider"; +import ExpansionPanel from "@material-ui/core/ExpansionPanel"; +import ExpansionPanelSummary from "@material-ui/core/ExpansionPanelSummary"; +import ExpansionPanelDetails from "@material-ui/core/ExpansionPanelDetails"; +import IconButton from "@material-ui/core/IconButton"; +import Tooltip from "@material-ui/core/Tooltip"; +import Typography from "@material-ui/core/Typography"; +import { makeStyles } from "@material-ui/core/styles"; + +// Icons +import MoreVertOutlinedIcon from "@material-ui/icons/MoreVertOutlined"; +import DeleteButton from "./DeleteButton"; +import EditOutlinedIcon from "@material-ui/icons/EditOutlined"; +import ShareButton from "./ShareButton"; +import VisibilityOutlinedIcon from "@material-ui/icons/VisibilityOutlined"; +import QuestionAnswerOutlinedIcon from "@material-ui/icons/QuestionAnswerOutlined"; + +const useStyles = makeStyles(theme => ({ + title: { + fontSize: 20, + flex: 1, + width: 0, + textAlign: "center", + color: "#667079" + }, + + description: { + alignSelf: "center" + }, + + container: { + display: "flex", + flexWrap: "wrap", + justifyContent: "flex-start", + color: "#667079" + }, + + item: { + margin: "5px" + }, + + expPainelD: { + display: "block" + }, + + date: { + fontSize: 16, + textAlign: "center", + color: "#667079" + }, + + create: { + fontSize: 13, + textAlign: "center", + color: "#667079" + }, + + numberOfAnswers: { + fontSize: 18, + textAlign: "left", + margin: "7px" + } +})); + +function CardForm(props) { + const classes = useStyles(); + + const handleAnswer = () => { + //redirecionar para /answer/props.id + }; + + const handleVisualize = () => { + //redirecionar para /visual/props.id + }; + + const handleEdit = () => { + //redirecionar para /edit/props.id + }; + + function handleDelete(value) { + if (value) { + //deletar o form + } + } + + function manageDate(date) { + if (date === "") { + return ""; + } + + let newDate = new Date(date); + let options = { year: "numeric", month: "2-digit", day: "2-digit" }; + return newDate.toLocaleDateString("pt-BR", options); + } + + return ( + <ExpansionPanel> + <ExpansionPanelSummary expandIcon={<MoreVertOutlinedIcon />}> + <Typography className={classes.title}> + {props.title} + <br /> + <div className={classes.create} noWrap> + {props.description} + </div> + <Divider /> + <div className={classes.numberOfAnswers}> + {props.numberOfAnswers} Respostas + </div> + </Typography> + </ExpansionPanelSummary> + <ExpansionPanelDetails className={classes.expPainelD}> + <Typography className={classes.date}> + {props.date ? "Data de modificação: " + manageDate(props.date) : ""} + </Typography> + <Tooltip title="Editar" arrow> + <IconButton onClick={handleEdit}> + <EditOutlinedIcon /> + </IconButton> + </Tooltip> + + <ShareButton id={props.id} /> + + <Tooltip title="Visualizar" arrow> + <IconButton aria-label="visualize" onClick={handleVisualize}> + <VisibilityOutlinedIcon /> + </IconButton> + </Tooltip> + + <Tooltip title="Respostas" arrow> + <IconButton aria-label="delete" onClick={handleAnswer}> + <QuestionAnswerOutlinedIcon /> + </IconButton> + </Tooltip> + + <DeleteButton handleDelete={handleDelete} /> + </ExpansionPanelDetails> + </ExpansionPanel> + ); +} + +export default CardForm; \ No newline at end of file diff --git a/src/components/fieldsListForms/DeleteButton.jsx b/src/components/fieldsListForms/DeleteButton.jsx new file mode 100644 index 0000000000000000000000000000000000000000..244545bc5d3517a877ef08b9b4bf7632c516d6e3 --- /dev/null +++ b/src/components/fieldsListForms/DeleteButton.jsx @@ -0,0 +1,72 @@ +import React from "react"; +import Button from "@material-ui/core/Button"; +import Dialog from "@material-ui/core/Dialog"; +import DeleteOutlineOutlinedIcon from "@material-ui/icons/DeleteOutlineOutlined"; +import IconButton from "@material-ui/core/IconButton"; +import DialogActions from "@material-ui/core/DialogActions"; +import Tooltip from "@material-ui/core/Tooltip"; +import DialogTitle from "@material-ui/core/DialogTitle"; +import { useTheme } from "@material-ui/core/styles"; + +import { makeStyles } from "@material-ui/core/styles"; +const useStyles = makeStyles(theme => ({ + buttonNo: { + color: "red" + }, + buttonYes: { + color: "blue" + } +})); + +function DeleteButton(props) { + const classes = useStyles(); + const [open, setOpen] = React.useState(false); + const theme = useTheme(); + + const handleClickOpen = () => { + setOpen(true); + }; + + const handleCloseFalse = () => { + setOpen(false); + props.handleDelete(false); + }; + + const handleCloseTrue = () => { + setOpen(false); + props.handleDelete(true); + }; + + const handleClose = () => { + setOpen(false); + }; + + return ( + <> + <Tooltip title="Deletar" arrow> + <IconButton aria-label="delete" onClick={handleClickOpen}> + <DeleteOutlineOutlinedIcon /> + </IconButton> + </Tooltip> + <Dialog + open={open} + onClose={handleClose} + aria-labelledby="responsive-dialog-title" + > + <DialogTitle id="responsive-dialog-title"> + {"Tem certeza que deseja deletar este formulário?"} + </DialogTitle> + <DialogActions> + <Button autoFocus onClick={handleCloseFalse} className={classes.buttonYes} color="primary"> + Não deletar + </Button> + <Button onClick={handleCloseTrue} className={classes.buttonNo} autoFocus> + Deletar + </Button> + </DialogActions> + </Dialog> + </> + ); +} + +export default DeleteButton; \ No newline at end of file diff --git a/src/components/fieldsListForms/SearchBar.jsx b/src/components/fieldsListForms/SearchBar.jsx new file mode 100644 index 0000000000000000000000000000000000000000..a3c03f0620fdb3fb69534f946a74eaf992d29f45 --- /dev/null +++ b/src/components/fieldsListForms/SearchBar.jsx @@ -0,0 +1,53 @@ +import React, { useState, useEffect } from "react"; +import TextField from "@material-ui/core/TextField"; +import Grid from "@material-ui/core/Grid"; +import SearchIcon from "@material-ui/icons/Search"; +import { makeStyles } from "@material-ui/core/styles"; +import InputAdornment from "@material-ui/core/InputAdornment"; + +const useStyles = makeStyles(theme => ({ + container: { + height: "50px", + marginTop: "15px", + marginBottom: "15px", + ["@media (max-width: 446px)"]: { + marginLeft: "60px", + marginBottom: "20px" + }, + ["@media (max-width: 658px)"]: { + marginRight: "20px" + } + }, + Icon: { + height: "30px", + fontSize: "20px" + } +})); + +function SearchBar(props) { + const classes = useStyles(); + + const handleChange = event => { + props.searching(event.target.value); + }; + + return ( + <Grid className={classes.container} container> + <TextField + id="outlined-basic" + label="Busque um formulário" + variant="outlined" + InputProps={{ + startAdornment: ( + <InputAdornment position="start"> + <SearchIcon color="grey" className={classes.Icon} /> + </InputAdornment> + ) + }} + onChange={handleChange} + /> + </Grid> + ); +} + +export default SearchBar; \ No newline at end of file diff --git a/src/components/fieldsListForms/ShareButton.jsx b/src/components/fieldsListForms/ShareButton.jsx new file mode 100644 index 0000000000000000000000000000000000000000..7ef16fcd8561b2cd32f29d8bf93da0acf5a8abc5 --- /dev/null +++ b/src/components/fieldsListForms/ShareButton.jsx @@ -0,0 +1,51 @@ +import React from "react"; +import Dialog from "@material-ui/core/Dialog"; +import ShareOutlinedIcon from "@material-ui/icons/ShareOutlined"; +import IconButton from "@material-ui/core/IconButton"; +import Tooltip from "@material-ui/core/Tooltip"; +import Grid from "@material-ui/core/Grid"; +import DialogContent from "@material-ui/core/DialogContent"; +import DialogContentText from "@material-ui/core/DialogContentText"; +import DialogTitle from "@material-ui/core/DialogTitle"; +import { useTheme } from "@material-ui/core/styles"; + +function ShareButton(props) { + const [open, setOpen] = React.useState(false); + const theme = useTheme(); + + const handleClickOpen = () => { + setOpen(true); + }; + + const handleClose = () => { + setOpen(false); + }; + + return ( + <> + <Tooltip title="Compartilhar" arrow> + <IconButton onClick={handleClickOpen}> + <ShareOutlinedIcon /> + </IconButton> + </Tooltip> + <Dialog + open={open} + onClose={handleClose} + aria-labelledby="responsive-dialog-title" + > + <DialogTitle id="responsive-dialog-title"> + { + "Aqui está a URL do seu formulário, copie-a e envie-a para ser respondida: " + } + </DialogTitle> + <DialogContent> + <DialogContentText id="alert-dialog-description"> + http://localhost:3000/#/answer/{props.id} + </DialogContentText> + </DialogContent> + </Dialog> + </> + ); +} + +export default ShareButton; \ No newline at end of file diff --git a/src/components/fieldsListForms/Tab.jsx b/src/components/fieldsListForms/Tab.jsx new file mode 100644 index 0000000000000000000000000000000000000000..721bf7e45c5f8600b6f6a588a29e54d2dcb94dc5 --- /dev/null +++ b/src/components/fieldsListForms/Tab.jsx @@ -0,0 +1,113 @@ +import React, { useState, useEffect } from "react"; +import Button from "@material-ui/core/Button"; +import FormControl from "@material-ui/core/FormControl"; +import Grid from "@material-ui/core/Grid"; +import InputLabel from "@material-ui/core/InputLabel"; +import MenuItem from "@material-ui/core/MenuItem"; +import Select from "@material-ui/core/Select"; +import FormHelperText from "@material-ui/core/FormHelperText"; +import SearchBar from "./SearchBar.jsx"; + +import { makeStyles } from "@material-ui/core/styles"; +const useStyles = makeStyles(theme => ({ + container: { + flexDirection: "row", + justifyContent: "space-between", + backgroundColor: "white", + marginBottom: "20px" + }, + + formControl: { + margin: theme.spacing(1), + minWidth: 120, + ["@media (max-width: 446px)"]: { + marginLeft: "100px", + marginBottom: "20px" + } + }, + + selectEmpty: { + marginTop: theme.spacing(2) + }, + + button: { + fontSize: 16, + height: "54px", + width: "251px", + backgroundColor: "#6ec46c", + color: "white", + ["@media (max-width: 710px)"]: { + marginBottom: "20px", + marginLeft: "170px", + marginBottom: "20px" + }, + ["@media (max-width: 446px)"]: { + marginLeft: "60px", + marginBottom: "20px" + } + }, + + gridButton: { + display: "flex", + alignItems: "center", + marginRight: "20px", + color: "white" + }, + + gridMenu: { + display: "flex", + alignItems: "center", + marginLeft: "20px" + }, + + searchBar: { + display: "flex", + justifyContent: "center" + } +})); + +function Tab(props) { + const classes = useStyles(); + const [seletectedValue, setseletectedValue] = React.useState(""); + + /** Function to handle event */ + const handleChange = event => { + props.sort(event.target.value); + setseletectedValue(event.target.value); + }; + + return ( + <Grid container className={classes.container}> + <Grid item className={classes.gridMenu}> + <FormControl className={classes.formControl}> + <Select + value={seletectedValue} + onChange={handleChange} + displayEmpty + className={classes.selectEmpty} + inputProps={{ "aria-label": "Without label" }} + > + <MenuItem value=""> + <em>Original</em> + </MenuItem> + <MenuItem value={1}>Alfabética</MenuItem> + <MenuItem value={2}>Mais recente</MenuItem> + <MenuItem value={3}>Relevância</MenuItem> + <MenuItem value={4}>Data de modificação</MenuItem> + </Select> + <FormHelperText>Ordenar</FormHelperText> + </FormControl> + </Grid> + <Grid justify="center" className={classes.searchBar}> + <SearchBar searching={props.searching} /> + </Grid> + <Grid item className={classes.gridButton}> + <Button className={classes.button} variant="contained"> + CRIAR NOVO FORMULÁRIO + </Button> + </Grid> + </Grid> + ); +} + +export default Tab; \ No newline at end of file diff --git a/src/components/footer/footer.js b/src/components/footer/footer.js index 5e01cd89398b7a16ee202f30f0655ffab3a368f4..07c7650130b2cc749f22218fc93cfabcc54421cf 100644 --- a/src/components/footer/footer.js +++ b/src/components/footer/footer.js @@ -4,15 +4,15 @@ import Grid from "@material-ui/core/Grid"; import Typography from "@material-ui/core/Typography"; import Logo from "./c3sl.png"; -const useStyles = makeStyles((theme) => ({ +const useStyles = makeStyles(theme => ({ footer: { background: "#66a6c2", - position: "relative", + position: "fixed", left: 0, bottom: 0, right: 0, width: "100%", - height: "78px", + height: "78px" }, img: { @@ -24,14 +24,14 @@ const useStyles = makeStyles((theme) => ({ marginRight: "auto", ["@media (min-width: 960px)"]: { marginLeft: "5px", - }, + } }, item: { display: "flex", justifyContent: "space-evenly", flexDirection: "column", - alignItems: "center", + alignItems: "center" }, text: { @@ -40,8 +40,8 @@ const useStyles = makeStyles((theme) => ({ textAlign: "center", left: "50%", ["@media (max-width: 960px)"]: { - display: "none", - }, + display: "none" + } }, adress: { @@ -55,9 +55,9 @@ const useStyles = makeStyles((theme) => ({ fontSize: "12px", textAlign: "right", ["@media (max-width: 960px)"]: { - display: "none", - }, - }, + display: "none" + } + } })); function Footer() { @@ -89,6 +89,8 @@ function Footer() { Telefone: 61 2027-6000 </Typography> </Grid> + + </Grid> ); } diff --git a/src/components/footer/footer.js~ b/src/components/footer/footer.js~ deleted file mode 100644 index 3e2ee4e095d3e2de15e1881b49cb87ce0b31828b..0000000000000000000000000000000000000000 --- a/src/components/footer/footer.js~ +++ /dev/null @@ -1,98 +0,0 @@ -import React from "react"; -import { makeStyles } from "@material-ui/core/styles"; -import Grid from "@material-ui/core/Grid"; -import Typography from "@material-ui/core/Typography"; -import Logo from "./c3sl.png"; - -const useStyles = makeStyles(theme => ({ - footer: { - background: "#66a6c2", - position: "fixed", - left: 0, - bottom: 0, - right: 0, - width: "100%", - height: "78px" - }, - - img: { - width: "50px", - display: "block", - marginTop: "auto", - marginBottom: "auto", - marginLeft: "auto", - marginRight: "auto", - ["@media (min-width: 960px)"]: { - marginLeft: "5px", - } - }, - - item: { - display: "flex", - justifyContent: "space-evenly", - flexDirection: "column", - alignItems: "center" - }, - - text: { - color: "#46525d", - fontSize: "15px", - textAlign: "center", - left: "50%", - ["@media (max-width: 960px)"]: { - display: "none" - } - }, - - adress: { - display: "block", - marginTop: "auto", - marginBottom: "auto", - marginLeft: "auto", - paddingRight: "10px", - - color: "#46525d", - fontSize: "12px", - textAlign: "right", - ["@media (max-width: 960px)"]: { - display: "none" - } - } -})); - -function Footer() { - const classes = useStyles(); - return ( - <Grid container className={classes.footer}> - <Grid item xs={12} sm={12} md={3} lg={2} className={classes.item}> - <img src={Logo} className={classes.img}></img> - </Grid> - - <Grid item md={6} lg={8} className={classes.item}> - <Typography className={classes.text}> - Ministério da - <b> - <br /> - Ciência, Tecnologia, - <br /> - Inovações e Comunicações - </b> - </Typography> - </Grid> - - <Grid item md={3} lg={2} className={classes.item}> - <Typography className={classes.adress}> - Esplanada dos Ministérios, Bloco R - <br /> - CEP: 70044-900 – Brasília-DF - <br /> - Telefone: 61 2027-6000 - </Typography> - </Grid> - - - </Grid> - ); -} - -export default Footer; diff --git a/src/global.css b/src/global.css index 879e608cd8cf467d0490956af673f7df84de1dcd..9570e8b82be5bea13375c19ae044ea5bbe577526 100644 --- a/src/global.css +++ b/src/global.css @@ -1,13 +1,5 @@ @import url("https://fonts.googleapis.com/css?family=Roboto:400,700&display=swap"); -* { - margin: 0; - padding: 0; - outline: 0; - box-sizing: border-box; - color: #667079; -} - html, body, #root { diff --git a/src/pages/ListForms.js b/src/pages/ListForms.js new file mode 100644 index 0000000000000000000000000000000000000000..92d90d469fb2812c7dbba239140da0355fa0b35d --- /dev/null +++ b/src/pages/ListForms.js @@ -0,0 +1,104 @@ +import React, { useState, useEffect } from "react"; +import api from "../api"; +import { useParams } from "react-router-dom"; +import Grid from "@material-ui/core/Grid"; +import Container from "@material-ui/core/Container"; +import { makeStyles } from "@material-ui/core/styles"; + +// Components +import CardForm from "../components/fieldsListForms/CardForm.jsx"; +import Tab from "../components/fieldsListForms/Tab.jsx"; + +export default function ListForms() { + + // Get the ID from the URL + const { id } = useParams(); + + // Hooks + const [forms, setForms] = React.useState([]); + const [isLoaded, setisLoaded] = React.useState(false); + const [auxForms, setAuxForms] = React.useState([]); + + /** + * Sorting function to sort the forms by some especified type. + * @param type - the type of the sorting that was selected. + */ + function sort(type) { + setAuxForms([]); + if (type === "") { + const tmp = [...forms].sort((a, b) => a.id > b.id); + setAuxForms(tmp); + } else if (type === 1) { + const tmp = [...forms].sort((a, b) => a.title > b.title); + setAuxForms(tmp); + } else if (type === 2) { + const tmp = [...forms].sort((a, b) => a.id < b.id); + setAuxForms(tmp); + } else if (type === 3) { + const tmp = [...forms].sort((a, b) => a.answersNumber < b.answersNumber); + setAuxForms(tmp); + } else if (type === 4) { + let tmp = [...forms].filter(value => { + return value.date; + }).sort((a, b) => a.date > b.date).concat( + [...forms].filter(value => { + return value.date === ""; + }) + ); + setAuxForms(tmp); + } + } + + /** + * Function to search for a form title. + * @param string - the string value to be searched. + */ + function searching(string) { + setAuxForms( + [...forms].filter(value => { + return value.title.includes(string); + }) + ); + } + + /** + * Async function to get all of the forms from an user. + * @param id - the user's id to have the forms listed. + */ + async function fetchData(id) { + const res = await api.get(`/user/list/${id}`).then(function (res) { + setForms(res.data.sort((a, b) => a.id > b.id)); + setAuxForms(res.data.sort((a, b) => a.id > b.id)); + setisLoaded(true); + }); + } + + useEffect(() => { + fetchData(id); + }, []); + + return isLoaded ? ( + <div> + <Tab sort={sort} searching={searching} /> + <Container> + <Grid container spacing={3}> + {auxForms.map(form => ( + <Grid item xl={4} lg={4} md={4} sm={6} xs={12} zeroMinWidth> + <CardForm + id={form.id} + title={form.title} + description={form.description} + numberOfAnswers={form.answersNumber} + date={form.date} + /> + </Grid> + ))} + </Grid> + </Container> + </div> + ) : ( + <Grid justify="center"> + <p>loading...</p> + </Grid> + ); +} \ No newline at end of file