Proyectos de Subversion LeadersLinked - Antes de SPA

Rev

Rev 6753 | | Comparar con el anterior | Ultima modificación | Ver Log |

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