Proyectos de Subversion LeadersLinked - Backend

Rev

Rev 15354 | Rev 16672 | Ir a la última revisión | Mostrar el archivo completo | | | Autoría | Ultima modificación | Ver Log |

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