Proyectos de Subversion LeadersLinked - SPA

Rev

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

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