Proyectos de Subversion LeadersLinked - SPA

Rev

Rev 3081 | Rev 3654 | Ir a la última revisión | Mostrar el archivo completo | | | Autoría | Ultima modificación | Ver Log |

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