Proyectos de Subversion LeadersLinked - SPA

Rev

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

Rev Autor Línea Nro. Línea
1607 stevensc 1
import React, { useEffect, useState } from 'react'
1231 stevensc 2
import { useForm } from 'react-hook-form'
1607 stevensc 3
import { connect, useSelector } from 'react-redux'
1231 stevensc 4
import { CKEditor } from 'ckeditor4-react'
5
 
1607 stevensc 6
import { axios, CKEDITOR_OPTIONS } from '@app/utils'
7
import { addNotification } from '@app/redux/notification/notification.actions'
1231 stevensc 8
import {
9
  closeShareModal,
10
  openShareModal,
11
  setModalType
1607 stevensc 12
} from '@app/redux/share-modal/shareModal.actions'
13
import { addFeed, fetchFeeds } from '@app/redux/feed/feed.actions'
1231 stevensc 14
 
1607 stevensc 15
import { shareModalTypes } from '@app/redux/share-modal/shareModal.types'
16
import { feedTypes } from '@app/redux/feed/feed.types'
1231 stevensc 17
 
1402 stevensc 18
import DropzoneComponent from '../dropzone/DropzoneComponent'
1437 stevensc 19
import FormErrorFeedback from '../UI/form/FormErrorFeedback'
1607 stevensc 20
import Modal from '../UI/modal/Modal'
1402 stevensc 21
import Spinner from '../UI/Spinner'
1607 stevensc 22
import ConfirmModal from './ConfirmModal'
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
    getValues,
52
    clearErrors,
53
    setError,
54
    reset
55
  } = useForm({
56
    defaultValues: {
57
      description: '',
58
      share_width: 'p'
59
    }
60
  })
61
 
62
  useEffect(() => {
63
    register('description', {
64
      required: { value: 'true', message: 'El campo es requerido' }
65
    })
1608 stevensc 66
 
1231 stevensc 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()
1608 stevensc 98
        toggleConfirmModal()
1231 stevensc 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
 
1608 stevensc 122
  const toggleConfirmModal = () => setShowConfirmModal(!showConfirmModal)
1231 stevensc 123
 
124
  const handleModalAccept = () => {
125
    setShowConfirmModal(false)
126
    setValue('description', '')
127
    setValue('file', '')
128
    openShareModal(postUrl, modalType, feedType)
129
    clearErrors()
130
  }
131
 
132
  const handleModalCancel = () => {
133
    setShowConfirmModal(false)
134
    closeShareModal()
135
    setModalType(lastModalType)
136
    openShareModal(postUrl, lastModalType, feedType)
137
  }
138
 
139
  const onSubmit = (data) => {
140
    setLoading(true)
141
    const currentFormData = new FormData()
142
 
143
    Object.entries(data).forEach(([key, value]) =>
144
      currentFormData.append(key, value)
145
    )
146
 
147
    axios
148
      .post(postUrl, currentFormData)
149
      .then((response) => {
150
        const { data, success } = response.data
151
 
152
        if (!success) {
153
          if (data.description || data.file || data.share_width) {
154
            Object.entries(data).map(([key, value]) =>
155
              setError(key, { type: 'required', message: value })
156
            )
157
          } else {
158
            addNotification({ style: 'danger', msg: data })
159
          }
160
          return
161
        }
162
 
163
        const newFeed = data
164
 
165
        addNotification({
166
          style: 'success',
167
          msg: 'La publicación ha sido compartida'
168
        })
169
        reset()
170
        clearErrors()
171
        closeShareModal()
172
 
173
        if (feedSharedId) {
174
          addFeed(newFeed, feedSharedId)
175
        } else {
176
          addFeed(newFeed)
177
        }
178
 
179
        if (currentPage && timelineUrl) {
180
          fetchFeeds(timelineUrl, currentPage)
181
        }
182
      })
183
      .finally(() => setLoading(false))
184
  }
185
 
186
  const onUploadedHandler = (files) => {
187
    setValue('file', files)
188
    clearErrors('file')
189
  }
190
 
191
  const dropZoneRender = () => {
192
    if (
193
      modalType !== shareModalTypes.POST &&
194
      modalType !== shareModalTypes.SHARE
195
    ) {
196
      return (
197
        <DropzoneComponent
198
          modalType={modalType}
199
          onUploaded={onUploadedHandler}
200
          settedFile={getValues('file')}
201
          recomendationText={recomendationText()}
202
        />
203
      )
204
    }
205
  }
206
 
207
  const SharedWithSelectRender = () => {
208
    if (feedType === feedTypes.DASHBOARD) {
209
      return (
210
        <>
211
          <select
212
            name='shared_with'
213
            className='form-control'
214
            ref={register({ required: 'El campo es requerido' })}
215
          >
216
            <option disabled='disabled' value='' style={{ display: 'none' }}>
217
              {labels.share_with}
218
            </option>
219
            <option value='p'>{labels.public}</option>
220
            <option value='c'>{labels.connections}</option>
221
          </select>
222
          {errors.shared_with && (
223
            <FormErrorFeedback>{errors.shared_with.message}</FormErrorFeedback>
224
          )}
225
        </>
226
      )
227
    }
228
  }
229
 
230
  return (
231
    <>
232
      <Modal
1402 stevensc 233
        show={isOpen}
1231 stevensc 234
        title={labels.share_a_post}
235
        labelAccept={labels.send}
236
        labelReject={labels.cancel}
237
        onClose={closeShareModal}
238
        onAccept={handleSubmit(onSubmit)}
239
      >
240
        {SharedWithSelectRender()}
241
 
242
        <CKEditor
1608 stevensc 243
          data={getValues('description')}
1231 stevensc 244
          config={CKEDITOR_OPTIONS}
1608 stevensc 245
          onChange={({ editor }) => setValue('description', editor.getData())}
1231 stevensc 246
          onDialogShow={() => {
247
            const modal = document.querySelector('.fade.modal.show')
248
            modal.removeAttribute('tabindex')
249
          }}
1608 stevensc 250
          onBeforeLoad={() => setIsCKEditorLoading(false)}
1231 stevensc 251
        />
252
 
253
        {isCKEditorLoading && <Spinner />}
254
 
255
        {errors.description && (
256
          <FormErrorFeedback>{errors.description.message}</FormErrorFeedback>
257
        )}
258
 
259
        {dropZoneRender()}
260
 
261
        {errors.file && (
262
          <FormErrorFeedback>{errors.file.message}</FormErrorFeedback>
263
        )}
264
 
265
        {loading && <Spinner />}
266
      </Modal>
267
      <ConfirmModal
268
        show={showConfirmModal}
269
        onClose={handleModalCancel}
270
        onAccept={handleModalAccept}
271
        message='¿No se ha compartido tu publicación , desea descartarlo?'
272
      />
273
    </>
274
  )
275
}
276
 
277
const mapStateToProps = (state) => ({
278
  isOpen: state.shareModal.isOpen,
279
  postUrl: state.shareModal.postUrl,
280
  modalType: state.shareModal.modalType,
281
  lastModalType: state.shareModal.lastModalType,
282
  feedType: state.shareModal.feedType,
283
  feedSharedId: state.shareModal.feedSharedId
284
})
285
 
286
const mapDispatchToProps = {
287
  addNotification: (notification) => addNotification(notification),
288
  closeShareModal: () => closeShareModal(),
289
  openShareModal: (postUrl, modalType, feedType) =>
290
    openShareModal(postUrl, modalType, feedType),
291
  setModalType: (modalType) => setModalType(modalType),
292
  addFeed: (feed, feedSharedId) => addFeed(feed, feedSharedId),
293
  fetchFeeds: (url, page) => fetchFeeds(url, page)
294
}
295
 
296
export default connect(mapStateToProps, mapDispatchToProps)(ShareModal)