Proyectos de Subversion LeadersLinked - Backend

Rev

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

Rev Autor Línea Nro. Línea
11166 stevensc 1
import React, { useState, useEffect } from 'react'
2
import axios from 'axios'
16682 stevensc 3
import { Button, Modal } from 'react-bootstrap'
11166 stevensc 4
import { useForm } from 'react-hook-form'
5
import { shareModalTypes } from '../redux/share-modal/shareModal.types'
16671 stevensc 6
import {
7
  closeShareModal,
8
  setModalType
9
} from '../redux/share-modal/shareModal.actions'
11166 stevensc 10
import { useDispatch, useSelector } from 'react-redux'
11
import DropzoneComponent from './Dropzone/DropzoneComponent'
12
import { addFeed, fetchFeeds } from '../redux/feed/feed.actions'
13
import { addNotification } from '../redux/notification/notification.actions'
14
import Spinner from './Spinner'
14864 stevensc 15
import { CKEditor } from 'ckeditor4-react'
16
import { config } from './helpers/ckeditor_config'
7386 stevensc 17
 
7387 stevensc 18
const ShareModal = () => {
16671 stevensc 19
  const {
20
    register,
21
    unregister,
22
    errors,
23
    handleSubmit,
24
    setValue,
25
    getValues,
26
    clearErrors,
27
    reset
16681 stevensc 28
  } = useForm()
29
  const [loading, setLoading] = useState(false)
30
  const { postUrl, isOpen, modalType } = useSelector(
31
    ({ shareModal }) => shareModal
32
  )
33
  const { currentPage, timelineUrl, feedSharedId } = useSelector(
34
    ({ feed }) => feed
35
  )
36
  const dispatch = useDispatch()
7388 stevensc 37
 
16671 stevensc 38
  const recomendationText = {
39
    IMAGE: 'Tamaño recomendado: 720x720',
40
    FILE: 'solo documentos PDF',
41
    VIDEO: 'Video de extensión mp4, mpeg, webm'
42
  }
15353 stevensc 43
 
16681 stevensc 44
  const closeModal = () => {
45
    dispatch(closeShareModal())
46
  }
7386 stevensc 47
 
16681 stevensc 48
  const onUploadedHandler = (files) => {
49
    setValue('file', files)
50
    clearErrors('file')
51
  }
7386 stevensc 52
 
16683 stevensc 53
  const onSubmit = handleSubmit((data) => {
16671 stevensc 54
    setLoading(true)
16683 stevensc 55
    const formData = new FormData()
7390 stevensc 56
 
16683 stevensc 57
    Object.entries(data).map(([entry, value]) => formData.append(entry, value))
7386 stevensc 58
 
16671 stevensc 59
    axios
60
      .post(postUrl, currentFormData)
61
      .then(({ data }) => {
62
        const newFeed = data.data
63
        if (!data.success) {
64
          typeof data.data === 'string'
65
            ? dispatch(
66
                addNotification({
67
                  style: 'danger',
68
                  msg: data.data
69
                })
70
              )
71
            : Object.entries(data.data).map(([key, value]) =>
72
                value.map((err) =>
73
                  dispatch(
74
                    addNotification({
75
                      style: 'danger',
76
                      msg: `${key}: ${err}`
77
                    })
78
                  )
79
                )
80
              )
81
          return
82
        }
83
        reset()
84
        clearErrors()
85
        dispatch(
86
          addNotification({
87
            style: 'success',
88
            msg: 'La publicación ha sido compartida'
89
          })
90
        )
7386 stevensc 91
 
16671 stevensc 92
        if (currentPage && timelineUrl)
93
          dispatch(fetchFeeds(timelineUrl, currentPage))
15215 stevensc 94
 
16671 stevensc 95
        if (feedSharedId) return dispatch(addFeed(newFeed, feedSharedId))
7806 stevensc 96
 
16671 stevensc 97
        return dispatch(addFeed(newFeed))
98
      })
99
      .catch((err) =>
100
        dispatch(addNotification({ style: 'danger', msg: `Error: ${err}` }))
101
      )
102
      .finally(() => {
103
        setLoading(false)
104
        closeModal()
105
      })
16683 stevensc 106
  })
7806 stevensc 107
 
16681 stevensc 108
  useEffect(() => {
109
    clearErrors()
110
  }, [isOpen])
7806 stevensc 111
 
16681 stevensc 112
  useEffect(() => {
113
    register('posted_or_shared')
114
    setValue('posted_or_shared', shareModalTypes.POST)
115
 
116
    if (
117
      [
118
        shareModalTypes.IMAGE,
119
        shareModalTypes.VIDEO,
120
        shareModalTypes.FILE,
121
        shareModalTypes.SHARE,
122
        shareModalTypes.CHAT
123
      ]
124
    ) {
125
      register('file', { required: 'El campo es requerido' })
126
    }
127
 
128
    if (modalType === shareModalTypes.POST) {
129
      register('description', { required: 'El campo es requerido' })
130
    }
131
  }, [modalType])
132
 
16671 stevensc 133
  return (
16681 stevensc 134
    <Modal show={isOpen} onHide={closeModal}>
16679 stevensc 135
      <Modal.Header closeButton>
136
        <Modal.Title>Compartir una publicación</Modal.Title>
137
      </Modal.Header>
138
      <Modal.Body>
16683 stevensc 139
        <form onSubmit={onSubmit} method="post">
16675 stevensc 140
          {!loading ? (
16671 stevensc 141
            <>
16676 stevensc 142
              {modalType === shareModalTypes.SURVEY && (
143
                <SurveyForm register={register} />
144
              )}
16675 stevensc 145
              {modalType !== shareModalTypes.SURVEY && (
146
                <>
147
                  <CKEditor
148
                    onChange={(e) =>
149
                      setValue('description', e.editor.getData())
150
                    }
151
                    config={config}
152
                  />
153
                  {errors.description && <p>{errors.description.message}</p>}
154
                </>
155
              )}
16671 stevensc 156
              {![shareModalTypes.POST, shareModalTypes.SURVEY].includes(
157
                modalType
158
              ) && (
16677 stevensc 159
                <>
160
                  <DropzoneComponent
161
                    modalType={modalType}
162
                    onUploaded={onUploadedHandler}
163
                    settedFile={getValues('file')}
164
                    recomendationText={recomendationText[modalType]}
165
                  />
166
                  {errors.file && <p>{errors.file.message}</p>}
167
                </>
16671 stevensc 168
              )}
169
            </>
16675 stevensc 170
          ) : (
171
            <Spinner />
16671 stevensc 172
          )}
16679 stevensc 173
 
16680 stevensc 174
          <div className="d-inline-flex mt-3 gap-3">
16682 stevensc 175
            <Button size="sm" type="submit" disabled={loading}>
16680 stevensc 176
              Enviar
16682 stevensc 177
            </Button>
178
            <Button
179
              size="sm"
180
              className="btn-secondary"
16680 stevensc 181
              disabled={loading}
16682 stevensc 182
              onClick={closeShareModal}
16680 stevensc 183
            >
184
              Cancelar
16682 stevensc 185
            </Button>
186
            <Button
187
              size="sm"
188
              className="btn-tertiary"
16680 stevensc 189
              disabled={loading}
190
              onClick={() => dispatch(setModalType(shareModalTypes.SURVEY))}
191
            >
192
              Añadir encuesta
16682 stevensc 193
            </Button>
16680 stevensc 194
          </div>
16679 stevensc 195
        </form>
196
      </Modal.Body>
16671 stevensc 197
    </Modal>
198
  )
199
}
7386 stevensc 200
 
16675 stevensc 201
const SurveyForm = ({ register }) => {
16671 stevensc 202
  const [optionsNumber, setOptionsNumber] = useState(2)
7386 stevensc 203
 
16671 stevensc 204
  const options = [
205
    { placeholder: 'Por ejemplo: transporte público' },
206
    { placeholder: 'Por ejemplo: coche propio' },
207
    { placeholder: 'Por ejemplo: coche compartido' },
208
    { placeholder: 'Por ejemplo: bicicleta' },
209
    { placeholder: 'Por ejemplo: otro' }
210
  ]
211
 
212
  const addOption = () => {
16674 stevensc 213
    setOptionsNumber(optionsNumber + 1)
16671 stevensc 214
  }
215
 
216
  const removeOption = () => {
16674 stevensc 217
    setOptionsNumber(optionsNumber - 1)
16671 stevensc 218
  }
219
 
220
  return (
221
    <>
222
      <div className="form-group">
223
        <label htmlFor="question">Tu pregunta*</label>
224
        <input
225
          type="text"
226
          className="form-control"
227
          placeholder="Por ejemplo: ¿cómo te desplazas al trabajo?"
228
          maxLength={140}
229
          id="question"
230
          name="question"
231
          ref={register({ required: true })}
232
        />
233
      </div>
234
      {options.slice(0, optionsNumber).map((option, index) => (
235
        <div className="form-group" key={index}>
236
          <label htmlFor={`option-${index + 1}`}>Opción {index + 1}*</label>
237
          {index > 1 && (
238
            <button className="btn" onClick={removeOption}>
239
              Eliminar
240
            </button>
241
          )}
242
          <input
243
            type="text"
244
            className="form-control"
245
            placeholder={option.placeholder}
246
            maxLength={30}
247
            id={`option-${index + 1}`}
248
            name={`option-${index + 1}`}
249
            ref={register({ required: true })}
250
          />
251
        </div>
252
      ))}
16675 stevensc 253
      {optionsNumber < options.length && (
254
        <button className="btn btn-outline-primary rounded" onClick={addOption}>
255
          Añadir opción
256
        </button>
257
      )}
16671 stevensc 258
    </>
259
  )
11166 stevensc 260
}
7386 stevensc 261
 
16671 stevensc 262
export default ShareModal