diff --git a/src/Admin/Components/Components/Inputs/CreateAchievements.js b/src/Admin/Components/Components/Inputs/CreateAchievements.js new file mode 100644 index 0000000000000000000000000000000000000000..ee61999e6ce2066e69949fc8b30caf1bd3470dd2 --- /dev/null +++ b/src/Admin/Components/Components/Inputs/CreateAchievements.js @@ -0,0 +1,463 @@ +/*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 } 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 Chip from '@material-ui/core/Chip'; +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 CreateAchievement = () => { + const { state } = useContext(Store) + + const [name, setName] = useState('Criar achievement') + const [description, setDescription] = useState('') + const [rewardXP, setRewardXP] = useState('') + const [rewardPT, setRewardPT] = useState('') + const [itemState, setItemState] = useState('') + const [repeatable, setRepeatable] = useState('') + const [resettable, setResettable] = useState('') + const [requirements, setRequirements] = useState([]) + const [stringReq, setStringReq] = useState("") + const [isLoading, setIsLoading] = useState(false) + + const [errorInName, setErrorInName] = useState({ + error: false, + message: '', + }) + const [errorInDescription, setErrorInDescription] = useState({ + error: false, + message: '', + }) + const [errorInRewardPoints, setErrorInRewardPoints] = useState({ + error: false, + message: '', + }) + const [errorInState, setErrorInState] = useState({ + error: false, + message: '', + }) + const [errorInRepeatable, setErrorInRepeteable] = useState({ + error: false, + message: '', + }) + + const [snackInfo, setSnackInfo] = useState({ + message: '', + icon: '', + open: false, + color: '', + }) + + const stateOptions = [ + { name: "active", value: "Ativo" }, + { name: "inactive", value: "Inativo" }, + { name: "deleted", value: "Removido" }, + ] + + const repeatableOptions = [ + { name: "never", value: "Nunca" }, + { name: "daily", value: "Diariamente" }, + { name: "weekly", value: "Semanalmente" }, + { name: "monthly", value: "Mensalmente" }, + { name: "yearly", value: "Anualmente" }, + ] + const resettableOptions = [ + { name: "true", value: "Sim" }, + { name: "false", value: "Não" }, + + ] + + + 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) => { + setRewardXP(e.target.value) + } + const repeatableHandler = (e) => { + setRepeatable(e.target.value) + } + const rewardPTHandler = (e) => { + if (errorInRewardPoints.error) + setErrorInDescription({ + error: false, + message: '' + }) + setRewardPT(e.target.value) + } + const itemStateHandler = (e) => { + setItemState(e.target.value) + } + const resettableHandler = (e) => { + setResettable(e.target.value) + } + const stringReqHandler = (e) => { + setStringReq(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 = "/achievements" + const body = { + "achievement": { + "name": name, + "description": description, + "reward_experience": rewardXP ? parseInt(rewardXP) : 0, + "reward_points": parseInt(rewardPT), + "state": itemState, + "repeatable": repeatable, + "resettable": resettable, + "requirements": requirements + } + } + 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_points) { + let reward_pointsError = "" + data.reward_points.map((msg) => ( + reward_pointsError = reward_pointsError + msg + " e " + )) + setErrorInRewardPoints({ + error: true, + message: reward_pointsError + }) + } + if (data.state) { + let stateError = "" + data.state.map((msg) => ( + stateError = stateError + msg + " e " + )) + setErrorInState({ + error: true, + message: stateError + }) + } + if (data.repeatable) { + let repeatableError = "" + data.repeatable.map((msg) => ( + repeatableError = repeatableError + msg + " e " + )) + setErrorInRepeteable({ + error: true, + message: repeatableError + }) + } + } + setIsLoading(false) + }, + (error) => { + HandleSnack('Ocorreu algum erro', true, 'warning', '#FA8072') + setIsLoading(false) + } + ) + } + + const HandleDelete = (i) => { + const copyReq = [...requirements]; + copyReq.splice(i, 1); + setRequirements(copyReq); + }; + + const OnKeyPressHandler = (key) => { + if (key === 13) { + const copyReq = [...requirements]; + copyReq.push(parseInt(stringReq)); + setRequirements(copyReq); + setStringReq(""); + } + }; + + // 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, + required: false, + onChange: (event) => rewardXPHandler(event) + }, + { + select: false, + label: 'Points ganhos', + value: rewardPT, + error: errorInRewardPoints.error, + errorMessage: errorInRewardPoints.message, + required: false, + onChange: (event) => rewardPTHandler(event) + }, + { + select: true, + label: 'Estado', + value: itemState, + options: [...stateOptions], + error: errorInState.error, + errorMessage: errorInState.message, + required: false, + onChange: (event) => itemStateHandler(event) + }, + { + select: true, + label: 'Repetível', + value: repeatable, + error: errorInRepeatable.error, + errorMessage: errorInRepeatable.message, + required: false, + options: [...repeatableOptions], + onChange: (event) => repeatableHandler(event) + }, + { + select: true, + label: 'Reajustável', + value: resettable, + required: false, + options: [...resettableOptions], + onChange: (event) => resettableHandler(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/achievements'}> + <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} + /> + ))} + <> + <div + style={{ + display: "flex", + flexDirection: "row", + flexWrap: "wrap", + marginBottom: "1em" + }} + > + {requirements.map((req, index) => ( + <li key={req.id} style={{ listStyleType: "none", marginBottom: "0.5em", marginRight: "0.5em" }}> + <Chip + label={req} + onDelete={() => HandleDelete(index)} + /> + </li> + ))} + </div> + + <TextField + id="outlined-input" + label="Requisitos" + rows={1} + value={stringReq} + onKeyPress={(key) => OnKeyPressHandler(key.which)} + onChange={stringReqHandler} + // onBlur={ShowEmails} + helperText="Digite o ID do requisito, um por vez, e pressione Enter" + style={{ marginBottom: "1em", width: '250px' }} + /> + </> + </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 CreateAchievement \ No newline at end of file