Proyectos de Subversion LeadersLinked - Antes de SPA

Rev

Rev 3723 | Rev 4987 | Ir a la última revisión | Autoría | Comparar con el anterior | Ultima modificación | Ver Log |

/* eslint-disable react/prop-types */
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, CKEDITOR_OPTIONS } 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: data.data,
          });
        }
      }
    });

    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={CKEDITOR_OPTIONS}
              name="description"
              onBeforeLoad={() => {
                setIsCKEditorLoading(false);
              }}
            />
            {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);