Proyectos de Subversion LeadersLinked - SPA

Rev

Rev 3079 | Rev 3432 | Ir a la última revisión | | Comparar con el anterior | Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
3019 stevensc 1
import React, { useMemo } from 'react'
3081 stevensc 2
import { Controller, useForm } from 'react-hook-form'
3076 stevensc 3
import {
4
  FormControlLabel,
5
  Radio,
6
  RadioGroup,
7
  styled,
8
  Typography
9
} from '@mui/material'
2970 stevensc 10
import { Public, LockClock } from '@mui/icons-material'
5 stevensc 11
 
2969 stevensc 12
import { axios } from '@utils'
3021 stevensc 13
import { getTimeDiff } from '@utils/dates'
2970 stevensc 14
import { updateFeed } from '@store/feed/feed.actions'
2969 stevensc 15
import { addNotification } from '@store/notification/notification.actions'
5 stevensc 16
 
3017 stevensc 17
import Widget from '@components/UI/Widget'
3081 stevensc 18
import FormErrorFeedback from '@components/UI/form/FormErrorFeedback'
2970 stevensc 19
 
3018 stevensc 20
const AnswerContainer = styled('div')`
5 stevensc 21
  display: flex;
22
  align-items: center;
23
  gap: 0.5rem;
24
  padding: 0.5rem 1rem;
25
  border: 2px solid var(--border-primary);
26
  border-radius: 50px;
27
  cursor: pointer;
28
  transition: all 200ms ease;
29
  position: relative;
30
  overflow: hidden;
31
  margin-bottom: 0.5rem;
32
  &:hover {
33
    border-color: var(--font-color);
34
    text-shadow: 0 0 1px var(--font-color);
35
  }
813 stevensc 36
`
5 stevensc 37
 
3017 stevensc 38
const SurveyForm = ({
39
  active = false,
40
  question = '¿Cómo consideras el ambiente laboral?',
41
  answers = [],
42
  votes = [],
43
  time = 0,
44
  voteUrl = '/feed/vote/d454717c-ba6f-485c-b94c-4fbb5f5bed94',
45
  resultType = 'pu'
46
}) => {
3019 stevensc 47
  const totalVotes = useMemo(
48
    () =>
49
      votes.reduce((acc, cur) => {
50
        if (!cur) return acc
51
        return acc + cur
52
      }, 0),
53
    [votes]
54
  )
3021 stevensc 55
  const timeRemaining = useMemo(() => getTimeDiff(time), [time])
3019 stevensc 56
 
3018 stevensc 57
  const { control, handleSubmit } = useForm()
5 stevensc 58
 
3014 stevensc 59
  const sendVote = handleSubmit(({ vote }) => {
60
    const formData = new FormData()
61
    formData.append('vote', vote)
62
 
63
    axios
64
      .post(voteUrl, formData)
65
      .then(({ data: response }) => {
66
        const { success, data } = response
67
 
68
        if (!success) {
69
          const errorMessage =
70
            typeof data === 'string'
71
              ? data
72
              : 'Error interno, por favor intente mas tarde.'
73
          throw new Error(errorMessage)
74
        }
75
 
76
        updateFeed({ feed: data, uuid: data.feed_uuid })
77
        addNotification({ style: 'success', msg: 'Voto emitido con exito' })
78
      })
79
      .catch((err) => {
80
        addNotification({ style: 'danger', msg: err.message })
81
      })
82
  })
83
 
3019 stevensc 84
  function getPorcentage(n, total) {
85
    return (n / total) * 100
86
  }
87
 
3017 stevensc 88
  return (
89
    <Widget>
90
      <Widget.Body>
91
        <Typography variant='h3'>{question}</Typography>
3014 stevensc 92
 
3017 stevensc 93
        {resultType === 'pu' ? (
94
          <Typography
95
            variant='overline'
96
            title='El número de votos es visible para todos los usuarios'
3019 stevensc 97
            sx={{ paddingBottom: (theme) => theme.spacing(0.5) }}
3017 stevensc 98
          >
3021 stevensc 99
            <Public sx={{ fontSize: '1.3rem' }} /> Público
3017 stevensc 100
          </Typography>
101
        ) : (
102
          <Typography
103
            variant='overline'
104
            title='Los resultados de la votación son privados'
3019 stevensc 105
            sx={{ paddingBottom: (theme) => theme.spacing(0.5) }}
3017 stevensc 106
          >
3021 stevensc 107
            <LockClock sx={{ fontSize: '1.3rem' }} /> Privado
3017 stevensc 108
          </Typography>
109
        )}
3014 stevensc 110
 
3020 stevensc 111
        <form onChange={sendVote}>
3081 stevensc 112
          <Controller
113
            name='vote'
114
            control={control}
115
            rules={{ required: 'Por favor seleccione una opción' }}
116
            defaultValue=''
117
            disabled={!active}
118
            render={({ field, fieldState: { error } }) => (
119
              <>
120
                <RadioGroup {...field}>
121
                  {answers.map((answer, index) => {
122
                    if (answer === null) return null
3014 stevensc 123
 
3081 stevensc 124
                    return (
125
                      <AnswerContainer
126
                        key={answer}
127
                        sx={{
128
                          '::before': {
129
                            content: '',
130
                            position: 'absolute',
131
                            left: 0,
132
                            top: 0,
133
                            height: '100%',
134
                            backgroundColor: '#0002',
135
                            zIndex: 4,
136
                            width: totalVotes
137
                              ? `${getPorcentage(votes[index], totalVotes)}%`
138
                              : 0
139
                          }
140
                        }}
141
                      >
142
                        <FormControlLabel
143
                          value={index + 1}
144
                          control={<Radio sx={{ padding: 0 }} />}
145
                          label={answer}
146
                          sx={{ margin: 0, gap: 1 }}
147
                          disabled={field.disabled}
148
                        />
3018 stevensc 149
 
3081 stevensc 150
                        {totalVotes ? (
151
                          <Typography variant='overline'>
152
                            {getPorcentage(votes[index], totalVotes)}%
153
                          </Typography>
154
                        ) : null}
155
                      </AnswerContainer>
156
                    )
157
                  })}
158
                </RadioGroup>
159
                {error && (
160
                  <FormErrorFeedback>{error.message}</FormErrorFeedback>
161
                )}
162
              </>
163
            )}
164
          />
3018 stevensc 165
 
3021 stevensc 166
          <Typography variant='overline'>
167
            Tiempo restante: {timeRemaining}
168
          </Typography>
3018 stevensc 169
 
170
          {!active && (
171
            <Typography variant='overline'>
172
              El formulario ya ha finalizado
173
            </Typography>
174
          )}
3017 stevensc 175
        </form>
176
      </Widget.Body>
177
    </Widget>
813 stevensc 178
  )
179
}
5 stevensc 180
 
2969 stevensc 181
export default SurveyForm