Proyectos de Subversion LeadersLinked - Backend

Rev

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