Proyectos de Subversion LeadersLinked - SPA

Rev

Rev 3694 | | Comparar con el anterior | Ultima modificación | Ver Log |

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