Skip to content
Snippets Groups Projects
Commit 0b418fea authored by lfr20's avatar lfr20
Browse files

Finish Actions Page

parent 8e1eec9b
No related branches found
No related tags found
1 merge request!46Gamefication admin
/*Copyright (C) 2019 Centro de Computacao Cientifica e Software Livre
Departamento de Informatica - Universidade Federal do Parana
This file is part of Plataforma Integrada MEC.
Plataforma Integrada MEC is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Plataforma Integrada MEC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/
import React, { useState, useEffect } from "react";
import moment from "moment";
// Maerial ui components
import Card from "@material-ui/core/Card";
import CardContent from "@material-ui/core/CardContent";
import Typography from "@material-ui/core/Typography";
import Button from "@material-ui/core/Button";
import ListRoundedIcon from "@material-ui/icons/ListRounded";
import { useStyles } from "../../Styles/DataCard";
import Grid from "@material-ui/core/Grid";
import DeleteRoundedIcon from '@material-ui/icons/DeleteRounded';
// Icons
import EditRoundedIcon from "@material-ui/icons/EditRounded";
//imports from local files
import { GetAData, DeleteFilter } from "../../../Filters";
import { Link, useHistory } from "react-router-dom";
import LoadingSpinner from "../../../../Components/LoadingSpinner";
import SnackBar from "../../../../Components/SnackbarComponent";
import {
getRequest,
deleteRequest,
} from "../../../../Components/HelperFunctions/getAxiosConfig";
import styled from 'styled-components'
import { GrAction } from 'react-icons/gr'
const AchievementCard = ({ match }) => {
let history = useHistory();
const classes = useStyles();
const WINDOW_WIDTH = window.innerWidth
const [error, setError] = useState(false) //Necessary to consult the API, catch errors
const [isLoaded, setIsLoaded] = useState(false) //Necessary to consult the API, wait until complete
const [item, setItem] = useState()
const [reloadPage, setReloadPage] = useState(false);
const [snackInfo, setSnackInfo] = useState({
message: "",
icon: "",
open: false,
color: "",
});
const DisplayDate = (date) => {
const convertedData = moment.utc(date);
return moment(convertedData)
.format("LLL")
.toString();
};
const HandleSnack = (message, state, icon, color) => {
setSnackInfo({
message: message,
icon: icon,
open: state,
color: color,
});
};
const deleteHandler = () => {
deleteRequest(
DeleteFilter("actions", item.id),
(data) => {
if (data.errors)
HandleSnack("Ocorreu algum erro", true, "warning", "#FA8072");
else {
HandleSnack(
"O item foi deletada com sucesso",
true,
"success",
"#228B22"
);
}
history.goBack()
},
(error) => {
HandleSnack("Ocorreu algum erro", true, "warning", "#FA8072");
}
)
}
useEffect(() => {
setIsLoaded(false)
getRequest(
GetAData("actions", match.params.id),
(data, header) => {
setItem(data);
setIsLoaded(true);
setError(false);
},
(error) => {
setIsLoaded(true);
setError(true);
}
);
}, [reloadPage]);
if (error) {
return <div>Houve um erro</div>;
} else if (!isLoaded) {
return <LoadingSpinner text="Carregando..." />;
} else {
return (
<>
<SnackBar
severity={snackInfo.icon}
text={snackInfo.message}
snackbarOpen={snackInfo.open}
color={snackInfo.color}
handleClose={() =>
setSnackInfo({
message: "",
icon: "",
open: false,
color: "",
})
}
/>
<Grid container direction="row" spacing={1}>
<Grid item xs={12}>
<Card>
<CardContent>
<Grid
xs={12}
justify="space-between"
alignItems="center"
container
>
<Grid item>
<Typography
className={classes.title}
color="inherit"
gutterBottom
>
Informações da ação
</Typography>
</Grid>
<Grid item>
<Link
style={{ textDecoration: "none" }}
to={`/admin/actions`}
>
<Button
startIcon={<ListRoundedIcon />}
color="primary"
variant="outlined"
>
Listar
</Button>
</Link>
<Link
to={`/admin/EditAction/${match.params.id}`}
style={{ textDecoration: "none" }}
>
<Button
startIcon={<EditRoundedIcon />}
color="primary"
variant="outlined"
>
Editar
</Button>
</Link>
<Button
startIcon={<DeleteRoundedIcon />}
color="secondary"
variant="outlined"
onClick={deleteHandler}
>
Deletar
</Button>
</Grid>
</Grid>
<div style={{ height: "1em" }} />
<Grid container direction="row" spacing={3}>
<Grid item sm={5} xs={12} style={WINDOW_WIDTH >= 600 ? {
borderRight: "solid #d4d4d4 1px"
} : {
borderBottom: "solid #d4d4d4 1px"
}}>
<ImgDiv>
<GrAction size={200} color="#00bcd4" />
</ImgDiv>
</Grid>
<Grid item sm={7} xs={12}>
<Grid container direction="column" spacing={1}>
<Grid item>
<Typography
color="initial"
className={classes.subTitle}
>
Nome
</Typography>
<Typography color="textSecondary">
{item.name}
</Typography>
</Grid>
<Grid item>
<Typography
color="initial"
className={classes.subTitle}
>
Criado em
</Typography>
<Typography color="textSecondary">
{DisplayDate(item.created_at)}
</Typography>
</Grid>
<Grid item>
<Typography
color="initial"
className={classes.subTitle}
>
Atualizado em
</Typography>
<Typography color="textSecondary">
{DisplayDate(item.updated_at)}
</Typography>
</Grid>
<Grid item>
<Typography color="initial" className={classes.subTitle}>
Descrição
</Typography>
<Typography color="textSecondary">
{item.description}
</Typography>
</Grid>
</Grid>
</Grid>
</Grid>
{
item.requirements.length >= 1 ?
<Grid container direction="column" spacing={1}>
<Grid item>
<Typography color="initial" className={classes.subTitle}>
Requisitos que dependem dessa ação
</Typography>
<Typography color="textSecondary">
<ul>
{
item.requirements.map((require) => {
return (
<li key={require.created_at}>
<Link to={`/admin/requirement/${require.id}`}>
<a style={{ textDecoration: 'none', color: "#00bcd4" }}>
{require.description}
</a>
</Link>
</li>
)
})
}
</ul>
</Typography>
</Grid>
</Grid> : null
}
</CardContent>
</Card>
</Grid>
</Grid>
</>
);
}
};
export default AchievementCard;
const ImgDiv = styled.div`
display: flex;
justify-content: center;
align-items: center;
height: 100%;
width: 100%;
`
/*Copyright (C) 2019 Centro de Computacao Cientifica e Software Livre
Departamento de Informatica - Universidade Federal do Parana
This file is part of Plataforma Integrada MEC.
Plataforma Integrada MEC is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Plataforma Integrada MEC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/
import React, { useState, useContext, useEffect } from 'react'
//imports material ui componets
import Card from "@material-ui/core/Card"
import CardContent from "@material-ui/core/CardContent"
import CardAction from '@material-ui/core/CardActions'
import { Typography, TextField, Button, Grid } from '@material-ui/core'
import CircularProgress from '@material-ui/core/CircularProgress'
import AddRoundedIcon from '@material-ui/icons/AddRounded'
import ListRoundedIcon from '@material-ui/icons/ListRounded'
import MenuItem from "@material-ui/core/MenuItem"
//imports local files
import SnackBar from '../../../../Components/SnackbarComponent'
import { Store } from '../../../../Store'
import Unauthorized from '../Unauthorized'
import { postRequest } from "../../../../Components/HelperFunctions/getAxiosConfig"
//router
import { Link } from 'react-router-dom'
const CreateAction = () => {
const { state } = useContext(Store)
const [name, setName] = useState('Criar Item')
const [description, setDescription] = useState('')
const [rewardXP, setRewardXP] = useState('')
const [isLoading, setIsLoading] = useState(false)
const [errorInName, setErrorInName] = useState({
error: false,
message: '',
})
const [errorInDescription, setErrorInDescription] = useState({
error: false,
message: '',
})
const [errorInRewardXP, setErrorInRewardXP] = useState({
error: false,
message: '',
})
const [snackInfo, setSnackInfo] = useState({
message: '',
icon: '',
open: false,
color: '',
})
const NameHandler = (e) => {
if (errorInName.error) {
setErrorInName({
error: false,
message: ''
})
}
setName(e.target.value)
}
const DescriptionHandler = (e) => {
if (errorInDescription.error)
setErrorInDescription({
error: false,
message: ''
})
setDescription(e.target.value)
}
const rewardXPHandler = (e) => {
if (errorInRewardXP.error)
setErrorInRewardXP({
error: false,
message: ''
})
setRewardXP(e.target.value)
}
// Handle snack infos
const HandleSnack = (message, state, icon, color) => {
setSnackInfo({
message: message,
icon: icon,
open: state,
color: color
})
}
const CheckUserPermission = () => {
let canUserEdit = false
if (state.userIsLoggedIn) {
const roles = [...state.currentUser.roles]
for (let i = 0; i < roles.length; i++)
if (roles[i].name === 'admin' || roles[i].name === 'editor')
canUserEdit = true
}
else {
canUserEdit = false
}
return canUserEdit
}
//Handle submit
async function onSubmit() {
setIsLoading(true)
const api = `/actions`
const body = {
"action_params": {
"name": name,
"description": description,
"reward_experience": rewardXP ? parseInt(rewardXP) : 0,
}
}
postRequest(
api,
body,
(data) => {
if (data.id)
HandleSnack('O item foi alterado com sucesso!', true, 'success', '#228B22')
else {
if (data.errors) {
HandleSnack(`${data.errors[0]}`, true, 'warning', '#FA8072')
}
if (data.name) {
let nameError = ""
data.name.map((msg) => (
nameError = nameError + msg + " e "
))
setErrorInName({
error: true,
message: nameError
})
}
if (data.description) {
let descriptionError = ""
data.description.map((msg) => (
descriptionError = descriptionError + msg + " e "
))
setErrorInDescription({
error: true,
message: descriptionError
})
}
if (data.reward_experience) {
let reward_experienceError = ""
data.reward_experience.map((msg) => (
reward_experienceError = reward_experienceError + msg + " e "
))
setErrorInRewardXP({
error: true,
message: reward_experienceError
})
}
}
setIsLoading(false)
},
(error) => {
HandleSnack('Ocorreu algum erro', true, 'warning', '#FA8072')
setIsLoading(false)
}
)
}
// Fields
const fields = [
{
select: false,
label: 'Nome',
value: name,
required: true,
error: errorInName.error,
errorMessage: errorInName.message,
onChange: (event) => NameHandler(event)
},
{
select: false,
label: 'Descrição',
value: description,
required: false,
error: errorInDescription.error,
errorMessage: errorInDescription.message,
onChange: (event) => DescriptionHandler(event)
},
{
select: false,
label: 'Experiência ganha',
value: rewardXP,
error: errorInRewardXP.error,
errorMessage: errorInRewardXP.message,
required: false,
onChange: (event) => rewardXPHandler(event)
},
]
if (CheckUserPermission()) {
return (
<Card>
<SnackBar
severity={snackInfo.icon}
text={snackInfo.message}
snackbarOpen={snackInfo.open}
color={snackInfo.color}
handleClose={() => setSnackInfo({
message: '',
icon: '',
open: false,
color: ''
})}
/>
<CardContent>
<Grid container direction='row' justify='space-between' alignContent="center" alignItems="center" xs={12}>
<Grid item>
<Typography variant='h4'>
{name}
</Typography>
</Grid>
<Grid item>
<Link style={{ textDecoration: 'none' }} to={'/admin/actions'}>
<Button
// onClick={props.BackToList}
startIcon={<ListRoundedIcon />}
variant='outlined'
color='primary'
>
Listar
</Button>
</Link>
</Grid>
</Grid>
<div style={{ height: '1em' }}></div>
<form style={{ display: 'flex', flexDirection: 'column' }}>
{fields.map((field, index) => (
field.select ?
<TextField
select
key={index}
required={field.required}
error={field.error}
helperText={field.error ? field.errorMessage : ''}
style={{ width: '250px', marginBottom: '1em' }}
label={field.label}
value={field.value}
onChange={field.onChange}
type="search"
multiline={true}
>
{field.options.map((option, index) => (
<MenuItem
key={option.value}
value={option.name}
name={option.value}
>
{option.value}
</MenuItem>
))}
</TextField>
:
<TextField
key={index}
required={field.required}
error={field.error}
helperText={field.error ? field.errorMessage : ''}
style={{ width: '250px', marginBottom: '1em' }}
label={field.label}
value={field.value}
onChange={field.onChange}
type="search"
multiline={true}
/>
))}
</form>
</CardContent>
<CardAction>
<Button
onClick={onSubmit}
variant="contained"
color="primary"
disabled={isLoading}
startIcon={isLoading ? null : <AddRoundedIcon />}
>
{
isLoading ? <CircularProgress size={24} /> : 'Editar'
}
</Button>
</CardAction>
</Card>
)
} else return <Unauthorized />
}
export default CreateAction
\ No newline at end of file
/*Copyright (C) 2019 Centro de Computacao Cientifica e Software Livre
Departamento de Informatica - Universidade Federal do Parana
This file is part of Plataforma Integrada MEC.
Plataforma Integrada MEC is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Plataforma Integrada MEC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/
import React, { useState, useContext, useEffect } from 'react'
//imports material ui componets
import Card from "@material-ui/core/Card"
import CardContent from "@material-ui/core/CardContent"
import CardAction from '@material-ui/core/CardActions'
import { Typography, TextField, Button, Grid } from '@material-ui/core'
import CircularProgress from '@material-ui/core/CircularProgress'
import AddRoundedIcon from '@material-ui/icons/AddRounded'
import ListRoundedIcon from '@material-ui/icons/ListRounded'
import MenuItem from "@material-ui/core/MenuItem"
//imports local files
import SnackBar from '../../../../Components/SnackbarComponent'
import { Store } from '../../../../Store'
import Unauthorized from '../Unauthorized'
import { getRequest, putRequest } from "../../../../Components/HelperFunctions/getAxiosConfig"
import LoadingSpinner from '../../../../Components/LoadingSpinner'
import { GetAData } from '../../../Filters'
//router
import { Link } from 'react-router-dom'
const EditAction = ({ match }) => {
const { state } = useContext(Store)
const [name, setName] = useState('Editar Item')
const [description, setDescription] = useState('')
const [rewardXP, setRewardXP] = useState('')
const [isLoading, setIsLoading] = useState(false)
const [isLoaded, setIsLoaded] = useState(false)
const [error, setError] = useState(false)
const [errorInName, setErrorInName] = useState({
error: false,
message: '',
})
const [errorInDescription, setErrorInDescription] = useState({
error: false,
message: '',
})
const [errorInRewardXP, setErrorInRewardXP] = useState({
error: false,
message: '',
})
const [snackInfo, setSnackInfo] = useState({
message: '',
icon: '',
open: false,
color: '',
})
const NameHandler = (e) => {
if (errorInName.error) {
setErrorInName({
error: false,
message: ''
})
}
setName(e.target.value)
}
const DescriptionHandler = (e) => {
if (errorInDescription.error)
setErrorInDescription({
error: false,
message: ''
})
setDescription(e.target.value)
}
const rewardXPHandler = (e) => {
if (errorInRewardXP.error)
setErrorInRewardXP({
error: false,
message: ''
})
setRewardXP(e.target.value)
}
// Handle snack infos
const HandleSnack = (message, state, icon, color) => {
setSnackInfo({
message: message,
icon: icon,
open: state,
color: color
})
}
const CheckUserPermission = () => {
let canUserEdit = false
if (state.userIsLoggedIn) {
const roles = [...state.currentUser.roles]
for (let i = 0; i < roles.length; i++)
if (roles[i].name === 'admin' || roles[i].name === 'editor')
canUserEdit = true
}
else {
canUserEdit = false
}
return canUserEdit
}
//Handle submit
async function onSubmit() {
setIsLoading(true)
const api = `/actions/${match.params.id}`
const body = {
"action_params": {
"name": name,
"description": description,
"reward_experience": rewardXP ? parseInt(rewardXP) : 0,
}
}
putRequest(
api,
body,
(data) => {
if (data.id)
HandleSnack('O item foi alterado com sucesso!', true, 'success', '#228B22')
else {
if (data.errors) {
HandleSnack(`${data.errors[0]}`, true, 'warning', '#FA8072')
}
if (data.name) {
let nameError = ""
data.name.map((msg) => (
nameError = nameError + msg + " e "
))
setErrorInName({
error: true,
message: nameError
})
}
if (data.description) {
let descriptionError = ""
data.description.map((msg) => (
descriptionError = descriptionError + msg + " e "
))
setErrorInDescription({
error: true,
message: descriptionError
})
}
if (data.reward_experience) {
let reward_experienceError = ""
data.reward_experience.map((msg) => (
reward_experienceError = reward_experienceError + msg + " e "
))
setErrorInRewardXP({
error: true,
message: reward_experienceError
})
}
}
setIsLoading(false)
},
(error) => {
HandleSnack('Ocorreu algum erro', true, 'warning', '#FA8072')
setIsLoading(false)
}
)
}
// Fields
const fields = [
{
select: false,
label: 'Nome',
value: name,
required: true,
error: errorInName.error,
errorMessage: errorInName.message,
onChange: (event) => NameHandler(event)
},
{
select: false,
label: 'Descrição',
value: description,
required: false,
error: errorInDescription.error,
errorMessage: errorInDescription.message,
onChange: (event) => DescriptionHandler(event)
},
{
select: false,
label: 'Experiência ganha',
value: rewardXP,
error: errorInRewardXP.error,
errorMessage: errorInRewardXP.message,
required: false,
onChange: (event) => rewardXPHandler(event)
},
]
useEffect(() => {
getRequest(
GetAData("actions", match.params.id),
(data, header) => {
setName(data.name)
setDescription(data.description)
setIsLoaded(true)
setError(false)
},
(error) => {
setIsLoaded(true)
setError(true)
}
)
}, [])
if (error) {
return <div> Error... </div>
} else if (!isLoaded) {
return <LoadingSpinner text="Carregando..." />
} else if (CheckUserPermission()) {
return (
<Card>
<SnackBar
severity={snackInfo.icon}
text={snackInfo.message}
snackbarOpen={snackInfo.open}
color={snackInfo.color}
handleClose={() => setSnackInfo({
message: '',
icon: '',
open: false,
color: ''
})}
/>
<CardContent>
<Grid container direction='row' justify='space-between' alignContent="center" alignItems="center" xs={12}>
<Grid item>
<Typography variant='h4'>
{name}
</Typography>
</Grid>
<Grid item>
<Link style={{ textDecoration: 'none' }} to={'/admin/actions'}>
<Button
// onClick={props.BackToList}
startIcon={<ListRoundedIcon />}
variant='outlined'
color='primary'
>
Listar
</Button>
</Link>
</Grid>
</Grid>
<div style={{ height: '1em' }}></div>
<form style={{ display: 'flex', flexDirection: 'column' }}>
{fields.map((field, index) => (
field.select ?
<TextField
select
key={index}
required={field.required}
error={field.error}
helperText={field.error ? field.errorMessage : ''}
style={{ width: '250px', marginBottom: '1em' }}
label={field.label}
value={field.value}
onChange={field.onChange}
type="search"
multiline={true}
>
{field.options.map((option, index) => (
<MenuItem
key={option.value}
value={option.name}
name={option.value}
>
{option.value}
</MenuItem>
))}
</TextField>
:
<TextField
key={index}
required={field.required}
error={field.error}
helperText={field.error ? field.errorMessage : ''}
style={{ width: '250px', marginBottom: '1em' }}
label={field.label}
value={field.value}
onChange={field.onChange}
type="search"
multiline={true}
/>
))}
</form>
</CardContent>
<CardAction>
<Button
onClick={onSubmit}
variant="contained"
color="primary"
disabled={isLoading}
startIcon={isLoading ? null : <AddRoundedIcon />}
>
{
isLoading ? <CircularProgress size={24} /> : 'Editar'
}
</Button>
</CardAction>
</Card>
)
} else return <Unauthorized />
}
export default EditAction
\ No newline at end of file
This diff is collapsed.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment