Rev 16746 | Autoría | Comparar con el anterior | Ultima modificación | Ver Log |
import React, { useState, useEffect } from 'react'import axios from 'axios'import { config } from './helpers/ckeditor_config'import { useForm } from 'react-hook-form'import { connect } from 'react-redux'import { Button, Modal } from 'react-bootstrap'import { CKEditor } from 'ckeditor4-react'import Datetime from 'react-datetime'import 'react-datetime/css/react-datetime.css'import {closeShareModal,setModalType} from '../redux/share-modal/shareModal.actions'import { addFeed, fetchFeeds } from '../redux/feed/feed.actions'import { addNotification } from '../redux/notification/notification.actions'import { shareModalTypes } from '../redux/share-modal/shareModal.types'import Spinner from './Spinner'import DropzoneComponent from './Dropzone/DropzoneComponent'const ShareModal = (props) => {const { addNotification, closeShareModal, setModalType, addFeed } = props // Redux actionsconst { postUrl, isOpen, modalType, currentPage, timelineUrl, feedSharedId } =props // Redux statesconst [loading, setLoading] = useState(false)const {register,errors,handleSubmit,setValue,getValues,clearErrors,unregister,reset} = useForm()const recomendationText = {IMAGE: 'Tamaño recomendado: 720x720',FILE: 'solo documentos PDF',VIDEO: 'Video de extensión mp4, mpeg, webm'}const closeModal = () => {closeShareModal()}const onUploadedHandler = (files) => {setValue('file', files)clearErrors('file')}const onSubmit = handleSubmit((data) => {setLoading(true)const formData = new FormData()Object.entries(data).map(([entry, value]) => formData.append(entry, value))if (modalType === shareModalTypes.SURVEY) {for (let i = 1; i <= 5; i++) {!data[`answer${i}`] && formData.append(`answer${i}`, '')}const numberOfAnswers = Object.entries(data).filter((entry) =>entry[0].includes('answer')).lengthformData.append('feed_content_type', 'fast-survey')formData.append('number_of_answers', numberOfAnswers)}axios.post(postUrl, formData).then(({ data: response }) => {const { success, data } = responseif (!success) {typeof data !== 'string'? Object.entries(data).map(([key, value]) =>addNotification({ style: 'danger', msg: `${key}: ${value[0]}` })): addNotification({ style: 'danger', msg: data })return}if (currentPage && timelineUrl) {fetchFeeds(timelineUrl, currentPage)}if (feedSharedId) {addFeed(data, feedSharedId)return}addFeed(data)addNotification({style: 'success',msg: 'La publicación ha sido compartida'})reset()clearErrors()closeModal()}).catch((err) => {addNotification({ style: 'danger', msg: `Error: ${err}` })throw new Error(err)}).finally(() => setLoading(false))})useEffect(() => {clearErrors()}, [isOpen])useEffect(() => {register('posted_or_shared')setValue('posted_or_shared', shareModalTypes.POST)if ([shareModalTypes.IMAGE,shareModalTypes.VIDEO,shareModalTypes.FILE,shareModalTypes.SHARE,shareModalTypes.CHAT].includes(modalType)) {register('file', { required: 'El campo es requerido' })}if ([shareModalTypes.IMAGE,shareModalTypes.VIDEO,shareModalTypes.FILE,shareModalTypes.SHARE,shareModalTypes.CHAT].includes(modalType)) {register('description', { required: 'El campo es requerido' })}if (modalType === shareModalTypes.SURVEY) {unregister('description')register('duration_days')register('duration_hours')register('duration_minutes')}}, [modalType])return (<Modal show={isOpen} onHide={closeModal}><form onSubmit={onSubmit} method="post"><Modal.Header closeButton><Modal.Title>Compartir una publicación</Modal.Title></Modal.Header><Modal.Body>{!loading ? (<>{modalType === shareModalTypes.SURVEY && (<SurveyForm register={register} setValue={setValue} />)}{modalType !== shareModalTypes.SURVEY && (<><CKEditoronChange={(e) => {setValue('description', e.editor.getData())}}config={config}/>{errors.description && <p>{errors.description.message}</p>}</>)}{![shareModalTypes.POST, shareModalTypes.SURVEY].includes(modalType) && (<><DropzoneComponentmodalType={modalType}onUploaded={onUploadedHandler}settedFile={getValues('file')}recomendationText={recomendationText[modalType]}/>{errors.file && <p>{errors.file.message}</p>}</>)}</>) : (<Spinner />)}</Modal.Body><Modal.Footer><Button size="sm" type="submit" disabled={loading}>Enviar</Button><Buttonvariant="light"size="sm"disabled={loading}onClick={closeShareModal}>Cancelar</Button></Modal.Footer></form></Modal>)}const SurveyForm = ({ register, setValue }) => {const [selectedDate, setSelectedDate] = useState(null)const [daysDifference, setDaysDifference] = useState({days: null,hours: null,minutes: null})const [optionsNumber, setOptionsNumber] = useState(2)const options = [{ placeholder: 'Por ejemplo: transporte público' },{ placeholder: 'Por ejemplo: coche propio' },{ placeholder: 'Por ejemplo: coche compartido' },{ placeholder: 'Por ejemplo: bicicleta' },{ placeholder: 'Por ejemplo: otro' }]const calculateMaxDate = () => {const today = new Date()const maxDate = today.setDate(today.getDate() + 29)return new Date(maxDate)}const calculateMinDate = () => {return new Date()}const handleChange = (selected) => {setSelectedDate(selected)if (selected) {const currentDate = new Date()const selectedDt = new Date(selected.format('YYYY-MM-DD HH:mm'))const timeDiff = selectedDt.getTime() - currentDate.getTime()const daysDiff = Math.floor(timeDiff / (1000 * 60 * 60 * 24))const hoursDiff = Math.floor((timeDiff / (1000 * 60 * 60)) % 24)const minutesDiff = Math.floor((timeDiff / (1000 * 60)) % 60)setDaysDifference({days: daysDiff,hours: hoursDiff,minutes: minutesDiff})} else {setDaysDifference(null)}}const addOption = () => {setOptionsNumber(optionsNumber + 1)}const removeOption = () => {setOptionsNumber(optionsNumber - 1)}useEffect(() => {setValue('duration_days', daysDifference.days)setValue('duration_hours', daysDifference.hours)setValue('duration_minutes', daysDifference.minutes)}, [daysDifference])return (<><div className="form-row"><div className="form-group col"><label htmlFor="privacy">Privacidad</label><selectclassName="form-control"name="privacy"id="privacy"ref={register}><option value="c">Compañía</option><option value="p">Público</option></select></div><div className="form-group col"><label htmlFor="result_type">Resultado</label><selectclassName="form-control"name="result_type"id="result_type"ref={register}><option value="pr">Privado</option><option value="pu">Público</option></select></div></div><div className="form-group"><label htmlFor="question">Tu pregunta*</label><inputtype="text"className="form-control"placeholder="Por ejemplo: ¿cómo te desplazas al trabajo?"maxLength={1024}id="question"name="question"ref={register({ required: true })}/></div>{options.slice(0, optionsNumber).map((option, index) => (<div className="form-group" key={index}><label htmlFor={`answer${index + 1}`}>Opción {index + 1}*</label>{index > 1 && (<button className="btn" onClick={removeOption}>Eliminar</button>)}<inputtype="text"className="form-control"placeholder={option.placeholder}maxLength={100}id={`answer${index + 1}`}name={`answer${index + 1}`}ref={register({ required: true })}/></div>))}{optionsNumber < options.length && (<button className="btn btn-outline-primary rounded" onClick={addOption}>Añadir opción</button>)}<div className="form-group"><label htmlFor="question">Duración</label><DatetimedateFormat="DD/MM/YYYY"onChange={handleChange}isValidDate={(current) =>current.isBefore(calculateMaxDate()) &¤t.isAfter(calculateMinDate())} // Se valida que la fecha esté entre la fecha mínima y la fecha máximavalue={selectedDate}/></div></>)}const mapStateToProps = (state) => ({isOpen: state.shareModal.isOpen,postUrl: state.shareModal.postUrl,modalType: state.shareModal.modalType,feedSharedId: state.shareModal.feedSharedId,currentPage: state.feed.currentPage,timelineUrl: state.feed.timelineUrl})const mapDispatchToProps = {addNotification: (notification) => addNotification(notification),closeShareModal: () => closeShareModal(),setModalType: (modalType) => setModalType(modalType),addFeed: (feed, feedSharedId) => addFeed(feed, feedSharedId)}export default connect(mapStateToProps, mapDispatchToProps)(ShareModal)