Proyectos de Subversion LeadersLinked - SPA

Rev

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

Rev Autor Línea Nro. Línea
1231 stevensc 1
import React, { useState, useEffect } from 'react'
2
import { useForm } from 'react-hook-form'
3
import { CKEditor } from 'ckeditor4-react'
4
import { connect, useSelector } from 'react-redux'
5
 
6
import { axios, CKEDITOR_OPTIONS } from '../../utils'
7
import {
8
  closeShareModal,
9
  openShareModal,
10
  setModalType
11
} from '../../redux/share-modal/shareModal.actions'
12
import { addNotification } from '../../redux/notification/notification.actions'
13
import { addFeed, fetchFeeds } from '../../redux/feed/feed.actions'
14
 
15
import { shareModalTypes } from '../../redux/share-modal/shareModal.types'
16
import { feedTypes } from '../../redux/feed/feed.types'
17
 
18
import Spinner from '../UI/Spinner'
19
import ConfirmModal from './ConfirmModal'
20
import FormErrorFeedback from '../UI/FormErrorFeedback'
21
import DropzoneComponent from '../dropzone/DropzoneComponent'
1384 stevensc 22
import Modal from 'components/UI/modal/Modal'
1231 stevensc 23
 
24
const ShareModal = ({
25
  postUrl,
26
  isOpen,
27
  modalType,
28
  lastModalType,
29
  setModalType,
30
  feedType,
31
  fetchFeeds,
32
  currentPage,
33
  timelineUrl,
34
  feedSharedId,
35
  closeShareModal, // Redux action
36
  addNotification, // Redux action
37
  addFeed, // Redux action
38
  openShareModal // Redux action
39
}) => {
40
  const [loading, setLoading] = useState(false)
41
  const [isCKEditorLoading, setIsCKEditorLoading] = useState(true)
42
  const [showConfirmModal, setShowConfirmModal] = useState(false)
43
  const labels = useSelector(({ intl }) => intl.labels)
44
 
45
  const {
46
    register,
47
    unregister,
48
    errors,
49
    handleSubmit,
50
    setValue,
51
    watch,
52
    getValues,
53
    clearErrors,
54
    setError,
55
    reset
56
  } = useForm({
57
    defaultValues: {
58
      description: '',
59
      share_width: 'p'
60
    }
61
  })
62
 
63
  useEffect(() => {
64
    register('description', {
65
      required: { value: 'true', message: 'El campo es requerido' }
66
    })
67
    register('posted_or_shared')
68
    if (
69
      modalType !== shareModalTypes.POST &&
70
      modalType !== shareModalTypes.SHARE
71
    ) {
72
      register('file', {
73
        required: { value: 'true', message: 'El campo es requerido' }
74
      })
75
    } else {
76
      if (!getValues('file')) unregister('file')
77
    }
78
  }, [modalType])
79
 
80
  const recomendationText = () => {
81
    switch (modalType) {
82
      case shareModalTypes.IMAGE:
83
        return 'Tamaño recomendado: 720x720'
84
      case shareModalTypes.FILE:
85
        return 'solo documentos PDF'
86
      case shareModalTypes.VIDEO:
87
        return 'Video de extensión mp4, mpeg, webm, mov'
88
      default:
89
        return ''
90
    }
91
  }
92
  useEffect(() => {
93
    const postedOrShared = modalType === shareModalTypes.SHARE ? 's' : 'p'
94
    setValue('posted_or_shared', postedOrShared)
95
    if (getValues('file') || getValues('description')) {
96
      if (modalType !== lastModalType) {
97
        closeShareModal()
98
        handleShowConfirmModal()
99
      }
100
    }
101
  }, [modalType])
102
 
103
  const hideDuplicatedModal = () => {
104
    setTimeout(() => {
105
      const modals = document.getElementsByClassName('modal')
106
      if (modals.length > 1 && modals[0].style.display !== 'none') {
107
        const currentModal = modals[0]
108
        currentModal.style.display = 'none'
109
        for (let index = 0; index < modals.length; index++) {
110
          const element = modals[index]
111
          element.removeAttribute('tabindex')
112
        }
113
      }
114
    }, 3000)
115
  }
116
 
117
  useEffect(() => {
118
    clearErrors()
119
    hideDuplicatedModal()
120
  }, [isOpen])
121
 
122
  const handleShowConfirmModal = () => {
123
    setShowConfirmModal(!showConfirmModal)
124
  }
125
 
126
  const handleModalAccept = () => {
127
    setShowConfirmModal(false)
128
    setValue('description', '')
129
    setValue('file', '')
130
    openShareModal(postUrl, modalType, feedType)
131
    clearErrors()
132
  }
133
 
134
  const handleModalCancel = () => {
135
    setShowConfirmModal(false)
136
    closeShareModal()
137
    setModalType(lastModalType)
138
    openShareModal(postUrl, lastModalType, feedType)
139
  }
140
 
141
  const onSubmit = (data) => {
142
    setLoading(true)
143
    const currentFormData = new FormData()
144
 
145
    Object.entries(data).forEach(([key, value]) =>
146
      currentFormData.append(key, value)
147
    )
148
 
149
    axios
150
      .post(postUrl, currentFormData)
151
      .then((response) => {
152
        const { data, success } = response.data
153
 
154
        if (!success) {
155
          if (data.description || data.file || data.share_width) {
156
            Object.entries(data).map(([key, value]) =>
157
              setError(key, { type: 'required', message: value })
158
            )
159
          } else {
160
            addNotification({ style: 'danger', msg: data })
161
          }
162
          return
163
        }
164
 
165
        const newFeed = data
166
 
167
        addNotification({
168
          style: 'success',
169
          msg: 'La publicación ha sido compartida'
170
        })
171
        reset()
172
        clearErrors()
173
        closeShareModal()
174
 
175
        if (feedSharedId) {
176
          addFeed(newFeed, feedSharedId)
177
        } else {
178
          addFeed(newFeed)
179
        }
180
 
181
        if (currentPage && timelineUrl) {
182
          fetchFeeds(timelineUrl, currentPage)
183
        }
184
      })
185
      .finally(() => setLoading(false))
186
  }
187
 
188
  const onUploadedHandler = (files) => {
189
    setValue('file', files)
190
    clearErrors('file')
191
  }
192
 
193
  const dropZoneRender = () => {
194
    if (
195
      modalType !== shareModalTypes.POST &&
196
      modalType !== shareModalTypes.SHARE
197
    ) {
198
      return (
199
        <DropzoneComponent
200
          modalType={modalType}
201
          onUploaded={onUploadedHandler}
202
          settedFile={getValues('file')}
203
          recomendationText={recomendationText()}
204
        />
205
      )
206
    }
207
  }
208
 
209
  const SharedWithSelectRender = () => {
210
    if (feedType === feedTypes.DASHBOARD) {
211
      return (
212
        <>
213
          <select
214
            name='shared_with'
215
            className='form-control'
216
            ref={register({ required: 'El campo es requerido' })}
217
          >
218
            <option disabled='disabled' value='' style={{ display: 'none' }}>
219
              {labels.share_with}
220
            </option>
221
            <option value='p'>{labels.public}</option>
222
            <option value='c'>{labels.connections}</option>
223
          </select>
224
          {errors.shared_with && (
225
            <FormErrorFeedback>{errors.shared_with.message}</FormErrorFeedback>
226
          )}
227
        </>
228
      )
229
    }
230
  }
231
 
232
  return (
233
    <>
234
      <Modal
235
        title={labels.share_a_post}
236
        labelAccept={labels.send}
237
        labelReject={labels.cancel}
238
        show={isOpen}
239
        onClose={closeShareModal}
240
        onReject={closeShareModal}
241
        onAccept={handleSubmit(onSubmit)}
242
      >
243
        {SharedWithSelectRender()}
244
 
245
        <CKEditor
246
          data={watch('description')}
247
          onChange={(e) => {
248
            const text = e.editor.getData()
249
            setValue('description', text)
250
          }}
251
          config={CKEDITOR_OPTIONS}
252
          name='description'
253
          onDialogShow={() => {
254
            const modal = document.querySelector('.fade.modal.show')
255
            modal.removeAttribute('tabindex')
256
          }}
257
          onBeforeLoad={() => {
258
            setIsCKEditorLoading(false)
259
          }}
260
        />
261
 
262
        {isCKEditorLoading && <Spinner />}
263
 
264
        {errors.description && (
265
          <FormErrorFeedback>{errors.description.message}</FormErrorFeedback>
266
        )}
267
 
268
        {dropZoneRender()}
269
 
270
        {errors.file && (
271
          <FormErrorFeedback>{errors.file.message}</FormErrorFeedback>
272
        )}
273
 
274
        {loading && <Spinner />}
275
      </Modal>
276
      <ConfirmModal
277
        show={showConfirmModal}
278
        onClose={handleModalCancel}
279
        onAccept={handleModalAccept}
280
        message='¿No se ha compartido tu publicación , desea descartarlo?'
281
      />
282
    </>
283
  )
284
}
285
 
286
const mapStateToProps = (state) => ({
287
  isOpen: state.shareModal.isOpen,
288
  postUrl: state.shareModal.postUrl,
289
  modalType: state.shareModal.modalType,
290
  lastModalType: state.shareModal.lastModalType,
291
  feedType: state.shareModal.feedType,
292
  feedSharedId: state.shareModal.feedSharedId
293
})
294
 
295
const mapDispatchToProps = {
296
  addNotification: (notification) => addNotification(notification),
297
  closeShareModal: () => closeShareModal(),
298
  openShareModal: (postUrl, modalType, feedType) =>
299
    openShareModal(postUrl, modalType, feedType),
300
  setModalType: (modalType) => setModalType(modalType),
301
  addFeed: (feed, feedSharedId) => addFeed(feed, feedSharedId),
302
  fetchFeeds: (url, page) => fetchFeeds(url, page)
303
}
304
 
305
export default connect(mapStateToProps, mapDispatchToProps)(ShareModal)