Rev 1261 | Rev 2043 | Ir a la última revisión | Autoría | Comparar con el anterior | Ultima modificación | Ver Log |
import React, { useState, useEffect } from "react";
import { connect } from "react-redux";
import { Button, Modal } from "react-bootstrap";
import { useForm } from "react-hook-form";
import styled from "styled-components";
import FormErrorFeedback from "../../../shared/form-error-feedback/FormErrorFeedback";
import Spinner from "../../../shared/loading-spinner/Spinner";
import { addNotification } from "../../../redux/notification/notification.actions";
import {
closeShareModal,
openShareModal,
setModalType,
} from "../../../redux/share-modal/shareModal.actions";
import { addFeed, fetchFeeds } from "../../../redux/feed/feed.actions";
import DropzoneComponent from "../../../shared/dropzone/DropzoneComponent";
import { shareModalTypes } from "../../../redux/share-modal/shareModal.types";
import { feedTypes } from "../../../redux/feed/feed.types";
import { CKEditor } from "ckeditor4-react";
import { axios } from "../../../utils";
import ConfirmModal from "../../../shared/confirm-modal/ConfirmModal";
const StyledSpinnerContainer = styled.div`
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
background: rgba(255, 255, 255, 0.4);
display: flex;
justify-content: center;
align-items: center;
z-index: 300;
`;
const ShareModal = (props) => {
// Redux State Destructuring
const {
postUrl,
isOpen,
modalType,
lastModalType,
setModalType,
feedType,
fetchFeeds,
currentPage,
timelineUrl,
feedSharedId
} = props;
// Redux dispatch Destructuring
const { closeShareModal, addNotification, addFeed, openShareModal } = props;
// states
const [loading, setLoading] = useState(false);
const [isCKEditorLoading, setIsCKEditorLoading] = useState(true);
const [showConfirmModal, setShowConfirmModal] = useState(false);
const {
register,
unregister,
errors,
handleSubmit,
setValue,
watch,
getValues,
clearErrors,
setError,
} = useForm({
defaultValues: {
description: "",
share_width: "",
},
});
useEffect(() => {
register("description", {
required: { value: "true", message: "El campo es requerido" },
});
register("posted_or_shared");
if (
modalType !== shareModalTypes.POST &&
modalType !== shareModalTypes.SHARE
) {
register("file", {
required: { value: "true", message: "El campo es requerido" },
});
} else {
if (!getValues("file")) unregister("file");
}
}, [modalType]);
const recomendationText = () => {
switch (modalType) {
case shareModalTypes.IMAGE:
return "Tamaño recomendado: 720x720";
case shareModalTypes.FILE:
return "solo documentos PDF";
case shareModalTypes.VIDEO:
return "Video de extensión mp4, mpeg, webm";
default:
return "";
}
};
useEffect(() => {
const postedOrShared = modalType === shareModalTypes.SHARE ? "s" : "p";
setValue("posted_or_shared", postedOrShared);
if (getValues("file") || getValues("description")) {
if (modalType !== lastModalType) {
closeShareModal();
handleShowConfirmModal();
}
}
}, [modalType]);
const hideDuplicatedModal = () => {
setTimeout(() => {
const modals = document.getElementsByClassName('modal');
if (modals.length > 1 && modals[0].style.display !== 'none') {
const currentModal = modals[0];
currentModal.style.display = 'none';
for (let index = 0; index < modals.length; index++) {
const element = modals[index];
element.removeAttribute("tabindex");
}
}
}, 3000);
}
useEffect(() => {
clearErrors();
hideDuplicatedModal();
}, [isOpen]);
const handleShowConfirmModal = () => {
setShowConfirmModal(!showConfirmModal);
};
const handleModalAccept = () => {
setShowConfirmModal(false);
setValue("description", "");
setValue("file", "");
openShareModal(postUrl, modalType, feedType);
clearErrors();
};
const handleModalCancel = () => {
setShowConfirmModal(false);
closeShareModal();
setModalType(lastModalType);
openShareModal(postUrl, lastModalType, feedType);
};
const onSubmit = async (data, e) => {
setLoading(true);
const currentFormData = new FormData();
for (let input in data) {
currentFormData.append(input, data[input]);
(`${input}:${data[input]}`);
}
await axios.post(postUrl, currentFormData).then((response) => {
const data = response.data;
const newFeed = data.data;
(data);
if (data.success) {
closeShareModal();
// reset data
e.target.reset();
setValue("description", "");
setValue("file", "");
clearErrors();
addNotification({
style: "success",
msg: "La publicación ha sido compartida",
});
if (feedSharedId) {
addFeed(newFeed, feedSharedId);
} else {
addFeed(newFeed);
}
if (currentPage && timelineUrl) {
fetchFeeds(timelineUrl, currentPage)
}
} else {
if (data.data.description || data.data.file || data.data.share_width) {
Object.entries(data.data).map(([key, value]) => {
setError(key, { type: "required", message: value });
});
} else {
addNotification({
style: "danger",
msg: "Ha ocurrido un error",
});
}
}
});
setLoading(false);
};
const onUploadedHandler = (files) => {
setValue("file", files);
clearErrors("file");
};
const dropZoneRender = () => {
if (
modalType !== shareModalTypes.POST &&
modalType !== shareModalTypes.SHARE
) {
return (
<DropzoneComponent
modalType={modalType}
onUploaded={onUploadedHandler}
settedFile={getValues("file")}
recomendationText={recomendationText()}
/>
);
}
};
const SharedWithSelectRender = () => {
if (feedType === feedTypes.DASHBOARD) {
return (
<React.Fragment>
<select
// value={formData.shared_with}
name="shared_with"
id="shared_with"
className="form-control"
// onChange={(e) => onInputChangeHandler(e)}
ref={register({
required: "El campo es requerido",
})}
defaultValue="p"
>
<option disabled="disabled" value="" style={{ display: "none" }}>
Compartir con
</option>
<option value="p">Público</option>
<option value="c">Conexiones</option>
</select>
{errors.shared_with && (
<FormErrorFeedback>{errors.shared_with.message}</FormErrorFeedback>
)}
</React.Fragment>
);
}
};
return (
<React.Fragment>
<Modal
show={isOpen}
onHide={closeShareModal}
autoFocus={false}
>
<Modal.Header closeButton>
<Modal.Title>Compartir una publicación</Modal.Title>
</Modal.Header>
<form encType="multipart/form-data" onSubmit={handleSubmit(onSubmit)}>
<Modal.Body>
{SharedWithSelectRender()}
<CKEditor
data={watch("description")}
onChange={(e) => {
const text = e.editor.getData();
setValue("description", text);
if (errors.description && getValues(description)) {
clearErrors("description");
}
}}
config={{
startupFocus: "end",
allowedContent: false,
image_previewText: ' ',
toolbarGroups: [
// { name: 'document', groups: [ 'mode', 'document', 'doctools' ] },
// { name: 'clipboard', groups: [ 'undo' ] },
{ name: 'editing', groups: ['find', 'selection', 'spellchecker'] },
{ name: 'forms' },
{ name: 'basicstyles', groups: ['basicstyles', 'cleanup'] },
{ name: 'paragraph', groups: ['list', 'indent', 'blocks', 'align', 'bidi'] },
{ name: 'links' },
{ name: 'insert' },
{ name: 'styles' },
{ name: 'colors' },
{ name: 'tools' },
{ name: 'others' },
],
removeButtons: 'Anchor',
removePlugins: 'elementspath,Anchor'
}}
name="description"
onBeforeLoad={() => {
setIsCKEditorLoading(false);
("Ready");
("Ready");
}}
/>
{isCKEditorLoading && (
<StyledSpinnerContainer>
<Spinner />
</StyledSpinnerContainer>
)}
{errors.description && (
<FormErrorFeedback>
{errors.description.message}
</FormErrorFeedback>
)}
{dropZoneRender()}
{errors.file && (
<FormErrorFeedback>{errors.file.message}</FormErrorFeedback>
)}
</Modal.Body>
<Modal.Footer>
<Button size="sm" type="submit">Enviar</Button>
<Button color="danger" size="sm" variant="danger" onClick={closeShareModal}>
Cancelar
</Button>
</Modal.Footer>
</form>
{loading ? (
<StyledSpinnerContainer>
<Spinner />
</StyledSpinnerContainer>
) : (
""
)}
</Modal>
<ConfirmModal
show={showConfirmModal}
onClose={handleModalCancel}
onAccept={handleModalAccept}
acceptLabel="Aceptar"
message="No se ha compartido tu publicación , desea descartarlo?"
/>
</React.Fragment>
);
};
const mapStateToProps = (state) => ({
isOpen: state.shareModal.isOpen,
postUrl: state.shareModal.postUrl,
modalType: state.shareModal.modalType,
lastModalType: state.shareModal.lastModalType,
feedType: state.shareModal.feedType,
feedSharedId: state.shareModal.feedSharedId,
});
const mapDispatchToProps = {
addNotification: (notification) => addNotification(notification),
closeShareModal: () => closeShareModal(),
openShareModal: (postUrl, modalType, feedType) => openShareModal(postUrl, modalType, feedType),
setModalType: (modalType) => setModalType(modalType),
addFeed: (feed, feedSharedId) => addFeed(feed, feedSharedId),
fetchFeeds: (url, page) => fetchFeeds(url, page),
};
export default connect(mapStateToProps, mapDispatchToProps)(ShareModal);