UNPKG

@eureca/eureca-ui

Version:

UI component library of Eureca's user and admin apps

133 lines (121 loc) 4.2 kB
import React, { useState } from 'react'; import PropTypes from 'prop-types'; import { normalize } from 'normalizr'; import { celiSchema } from './celi.schema'; import { Box, RadioGroup, Typography } from '@material-ui/core'; import { EvaluationScore } from './evaluation-score'; import { Radio } from '../Radio'; import { Accordion } from '../Accordion'; import { Flex } from '../Flex'; import { shadows } from '../../theme'; import { colors } from '../../theme/colors'; /** * @kkfuri: values mean score points and must be numbers in string so EvaluationScore translates it to number and radio can still read a value without falsy values like 0 */ const radios = [ { name: 'radio-question-no', label: 'Não', value: '0' }, { name: 'radio-question-parcially', label: 'Parcialmente', value: '1' }, { name: 'radio-question-yes', label: 'Sim', value: '2' }, ]; const scoreReducer = (o, v, a) => (Number(a[v]) ? o + Number(a[v]) : o); const styles = { outerContainer: { overflow: 'hidden', borderRadius: 4, boxShadow: shadows.cardShadow, }, horizontalRule: { borderColor: colors.gray5, borderStyle: 'outset', borderBottom: 0, }, }; function AccordionWithCeliEvaluation({ title, questions, handleChange, scores = {} }) { const currentScore = questions.reduce((acc, q) => scoreReducer(acc, q.id, scores), 0); return ( <Accordion title={`Critério de ${title}`}> {questions.map((question, index) => ( <Box px={2} mb={3} key={question.id}> <Typography variant="subtitle2">{`${index + 1}. ${question.text}`}</Typography> <RadioGroup value={scores[question.id]} onChange={e => handleChange(question.id, e.target.value)} > <Flex directionRow justifySpaceBetween> {radios.map(data => ( <Radio key={data.value} {...data} /> ))} </Flex> </RadioGroup> </Box> ))} <hr style={styles.horizontalRule} /> <EvaluationScore title={title} score={currentScore} /> </Accordion> ); } AccordionWithCeliEvaluation.propTypes = { title: PropTypes.string.isRequired, questions: PropTypes.arrayOf( PropTypes.shape({ text: PropTypes.string.isRequired, id: PropTypes.number.isRequired, }) ), handleChange: PropTypes.func.isRequired, scores: PropTypes.object, }; function CeliEvaluation({ onChange, questions }) { const { entities } = normalize(questions, celiSchema); const { questions: normalizedQuestions } = entities; // TODO: @tcp We should plug the data from the backend here const [scores, setScores] = useState(() => { let s = {}; Object.keys(normalizedQuestions).forEach(key => (s[key] = 0)); return s; }); const handleChange = (questionId, value) => setScores(scores => { const updatedScores = { ...scores }; updatedScores[questionId] = value; return updatedScores; }); const totalScore = Object.keys(scores).reduce((o, v) => scoreReducer(o, v, scores), 0); const evaluationTitle = 'Avaliação por competências - CELI'; if (typeof onChange === 'function') onChange(scores, questions); return ( <> <Box px={2} mb={2}> <Typography variant="h6">{evaluationTitle}</Typography> </Box> <div style={styles.outerContainer}> {questions.map(set => ( <AccordionWithCeliEvaluation key={set.id} title={set.type} questions={set.questions} handleChange={handleChange} scores={scores} /> ))} <EvaluationScore final score={totalScore} /> </div> </> ); } CeliEvaluation.propTypes = { onChange: PropTypes.func.isRequired, questions: PropTypes.arrayOf( PropTypes.shape({ id: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired, type: PropTypes.string.isRequired, questions: PropTypes.arrayOf( PropTypes.shape({ id: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired, text: PropTypes.string.isRequired, }) ).isRequired, }) ).isRequired, }; export { CeliEvaluation };