Proyectos de Subversion LeadersLinked - Antes de SPA

Rev

Rev 870 | Rev 944 | Ir a la última revisión | | Comparar con el anterior | Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 www 1
import React, { useState, useEffect } from "react";
2
import { connect } from "react-redux";
3
import { Button, Modal } from "react-bootstrap";
4
import { useForm } from "react-hook-form";
5
import styled from "styled-components";
6
import FormErrorFeedback from "../../../shared/form-error-feedback/FormErrorFeedback";
7
import Spinner from "../../../shared/loading-spinner/Spinner";
8
import { addNotification } from "../../../redux/notification/notification.actions";
9
import {
10
  closeShareModal,
11
  openShareModal,
12
  setModalType,
13
} from "../../../redux/share-modal/shareModal.actions";
14
import { addFeed } from "../../../redux/feed/feed.actions";
15
import DropzoneComponent from "../../../shared/dropzone/DropzoneComponent";
16
import { shareModalTypes } from "../../../redux/share-modal/shareModal.types";
17
import { feedTypes } from "../../../redux/feed/feed.types";
198 steven 18
import {CKEditor} from "ckeditor4-react";
1 www 19
import {axios} from "../../../utils";
20
import ConfirmModal from "../../../shared/confirm-modal/ConfirmModal";
21
 
22
const StyledSpinnerContainer = styled.div`
23
  position: absolute;
24
  left: 0;
25
  top: 0;
26
  width: 100%;
27
  height: 100%;
28
  background: rgba(255, 255, 255, 0.4);
29
  display: flex;
30
  justify-content: center;
31
  align-items: center;
32
  z-index: 300;
33
`;
34
 
35
const ShareModal = (props) => {
36
  // Redux State Destructuring
37
  const {
38
    postUrl,
39
    isOpen,
40
    modalType,
41
    lastModalType,
42
    setModalType,
43
    feedType,
44
  } = props;
45
  // Redux dispatch Destructuring
46
  const { closeShareModal, addNotification, addFeed, openShareModal } = props;
47
  // states
48
  const [loading, setLoading] = useState(false);
49
  const [isCKEditorLoading, setIsCKEditorLoading] = useState(true);
50
  const [showConfirmModal, setShowConfirmModal] = useState(false);
51
 
52
  const {
53
    register,
54
    unregister,
55
    errors,
56
    handleSubmit,
57
    setValue,
58
    watch,
59
    getValues,
60
    clearErrors,
61
    setError,
62
  } = useForm({
63
    defaultValues: {
64
      description: "",
65
      share_width: "",
66
    },
67
  });
68
 
69
  useEffect(() => {
70
    register("description", {
71
      required: { value: "true", message: "El campo es requerido" },
72
    });
73
    register("posted_or_shared");
74
    if (
75
      modalType !== shareModalTypes.POST &&
76
      modalType !== shareModalTypes.SHARE
77
    ) {
78
      register("file", {
79
        required: { value: "true", message: "El campo es requerido" },
80
      });
81
    } else {
82
      if (!getValues("file")) unregister("file");
83
    }
84
  }, [modalType]);
85
 
86
  const recomendationText = () => {
87
    switch (modalType) {
88
      case shareModalTypes.IMAGE:
89
        return "Tamaño recomendado: 720x720";
90
      case shareModalTypes.FILE:
91
        return "solo documentos PDF";
92
      case shareModalTypes.VIDEO:
93
        return "Video de extensión mp4, mpeg, webm";
94
      default:
95
        return "";
96
    }
97
  };
98
 
99
  useEffect(() => {
100
    const postedOrShared = modalType === shareModalTypes.SHARE ? "s" : "p";
101
    setValue("posted_or_shared", postedOrShared);
102
    if (getValues("file") || getValues("description")) {
103
      if (modalType !== lastModalType) {
104
        closeShareModal();
105
        handleShowConfirmModal();
106
      }
107
    }
108
  }, [modalType]);
868 steven 109
  const hideDuplicatedModal = () => {
110
    setTimeout(() => {
111
      const modals = document.getElementsByClassName('modal');
943 steven 112
      console.log('>>: modals > ', modals)
870 steven 113
      if(modals.length > 0 && modals[0].style.display !== 'none'){
114
        const currentModal = modals[0];
115
        currentModal.style.display = 'none';
116
      }
868 steven 117
    }, 3000);
118
  }
1 www 119
  useEffect(() => {
120
    clearErrors();
868 steven 121
    hideDuplicatedModal();
1 www 122
  }, [isOpen]);
123
 
124
  const handleShowConfirmModal = () => {
125
    setShowConfirmModal(!showConfirmModal);
126
  };
127
 
128
  const handleModalAccept = () => {
129
    setShowConfirmModal(false);
130
    setValue("description", "");
131
    setValue("file", "");
132
    openShareModal(postUrl, modalType, feedType);
133
    clearErrors();
134
  };
135
 
136
  const handleModalCancel = () => {
137
    setShowConfirmModal(false);
138
    closeShareModal();
139
    setModalType(lastModalType);
140
    openShareModal(postUrl, lastModalType, feedType);
141
  };
142
 
143
  const onSubmit = async (data, e) => {
144
    setLoading(true);
145
    const currentFormData = new FormData();
146
    for (let input in data) {
147
      currentFormData.append(input, data[input]);
148
       (`${input}:${data[input]}`);
149
    }
150
    await axios.post(postUrl, currentFormData).then((response) => {
151
      const data = response.data;
152
      const newFeed = data.data;
153
       (data);
154
      if (data.success) {
155
        closeShareModal();
156
        // reset data
157
        e.target.reset();
158
        setValue("description", "");
159
        setValue("file", "");
160
        clearErrors();
161
        addNotification({
162
          style: "success",
163
          msg: "La publicación ha sido compartida",
164
        });
165
        // if (modalType !== shareModalTypes.SHARE) {
166
          addFeed(newFeed);
167
        // }
168
      } else {
169
        if (data.data.description || data.data.file || data.data.share_width) {
170
          Object.entries(data.data).map(([key, value]) => {
171
            setError(key, { type: "required", message: value });
172
          });
173
        } else {
174
          addNotification({
175
            style: "danger",
176
            msg: "Ha ocurrido un error",
177
          });
178
        }
179
      }
180
    });
181
 
182
    setLoading(false);
183
  };
184
 
185
  const onUploadedHandler = (files) => {
186
    setValue("file", files);
187
    clearErrors("file");
188
  };
189
 
190
  const dropZoneRender = () => {
191
    if (
192
      modalType !== shareModalTypes.POST &&
193
      modalType !== shareModalTypes.SHARE
194
    ) {
195
      return (
196
        <DropzoneComponent
197
          modalType={modalType}
198
          onUploaded={onUploadedHandler}
199
          settedFile={getValues("file")}
200
          recomendationText={recomendationText()}
201
        />
202
      );
203
    }
204
  };
205
 
206
  const SharedWithSelectRender = () => {
207
    if (feedType === feedTypes.DASHBOARD) {
208
      return (
209
        <React.Fragment>
210
          <select
211
            // value={formData.shared_with}
212
            name="shared_with"
213
            id="shared_with"
214
            className="form-control"
215
            // onChange={(e) => onInputChangeHandler(e)}
216
            ref={register({
217
              required: "El campo es requerido",
218
            })}
219
            defaultValue="p"
220
          >
221
            <option disabled="disabled" value="" style={{ display: "none" }}>
222
              Compartir con
223
            </option>
224
            <option value="p">Público</option>
225
            <option value="c">Conexiones</option>
226
          </select>
227
          {errors.shared_with && (
228
            <FormErrorFeedback>{errors.shared_with.message}</FormErrorFeedback>
229
          )}
230
        </React.Fragment>
231
      );
232
    }
233
  };
234
 
235
  return (
236
    <React.Fragment>
237
      <Modal
238
        show={isOpen}
239
        onHide={closeShareModal}
943 steven 240
        autoFocus={false}
1 www 241
      >
242
        <Modal.Header closeButton>
243
          <Modal.Title>Compartir una publicación</Modal.Title>
244
        </Modal.Header>
245
        <form encType="multipart/form-data" onSubmit={handleSubmit(onSubmit)}>
246
          <Modal.Body>
247
            {SharedWithSelectRender()}
248
            <CKEditor
249
              data={watch("description")}
250
              onChange={(e) => {
251
                const text = e.editor.getData();
252
                setValue("description", text);
253
                if (errors.description && getValues(description)) {
254
                  clearErrors("description");
255
                }
256
              }}
257
              config={{
258
                startupFocus: "end",
766 steven 259
                allowedContent: false,
771 steven 260
                toolbarGroups: [
774 steven 261
                  // { name: 'document',	   groups: [ 'mode', 'document', 'doctools' ] },
775 steven 262
                  // { name: 'clipboard',   groups: [ 'undo' ] },
773 steven 263
                  { name: 'editing',     groups: [ 'find', 'selection', 'spellchecker' ] },
264
                  { name: 'forms' },
265
                  { name: 'basicstyles', groups: [ 'basicstyles', 'cleanup' ] },
266
                  { name: 'paragraph',   groups: [ 'list', 'indent', 'blocks', 'align', 'bidi' ] },
267
                  { name: 'links' },
268
                  { name: 'insert' },
771 steven 269
                  { name: 'styles' },
270
                  { name: 'colors' },
271
                  { name: 'tools' },
272
                  { name: 'others' },
273
                ]
274
                // removeButtons: 'Clipboard,Paste',
275
                // removePlugins: 'Clipboard,Paste'
1 www 276
              }}
277
              name="description"
278
              onBeforeLoad={() => {
279
                setIsCKEditorLoading(false);
280
                 ("Ready");
281
              }}
282
            />
283
            {isCKEditorLoading && (
284
              <StyledSpinnerContainer>
285
                <Spinner />
286
              </StyledSpinnerContainer>
287
            )}
288
            {errors.description && (
289
              <FormErrorFeedback>
290
                {errors.description.message}
291
              </FormErrorFeedback>
292
            )}
293
 
294
            {dropZoneRender()}
295
            {errors.file && (
296
              <FormErrorFeedback>{errors.file.message}</FormErrorFeedback>
297
            )}
298
          </Modal.Body>
299
          <Modal.Footer>
300
            <Button size="sm" type="submit">Enviar</Button>
301
            <Button color="danger" size="sm" variant="danger" onClick={closeShareModal}>
302
              Cancelar
303
            </Button>
304
          </Modal.Footer>
305
        </form>
306
        {loading ? (
307
          <StyledSpinnerContainer>
308
            <Spinner />
309
          </StyledSpinnerContainer>
310
        ) : (
311
          ""
312
        )}
313
      </Modal>
314
      <ConfirmModal
315
        show={showConfirmModal}
316
        onClose={handleModalCancel}
317
        onAccept={handleModalAccept}
318
        acceptLabel="Aceptar"
319
        message="No se ha compartido tu publicación , desea descartarlo?"
320
      />
321
    </React.Fragment>
322
  );
323
};
324
 
325
const mapStateToProps = (state) => ({
326
  isOpen: state.shareModal.isOpen,
327
  postUrl: state.shareModal.postUrl,
328
  modalType: state.shareModal.modalType,
329
  lastModalType: state.shareModal.lastModalType,
330
  feedType: state.shareModal.feedType,
331
});
332
 
333
const mapDispatchToProps = {
334
  addNotification: (notification) => addNotification(notification),
335
  closeShareModal: () => closeShareModal(),
336
  openShareModal: (postUrl, modalType, feedType) =>
337
    openShareModal(postUrl, modalType, feedType),
338
  setModalType: (modalType) => setModalType(modalType),
339
  addFeed: (feed) => addFeed(feed),
340
};
341
 
342
export default connect(mapStateToProps, mapDispatchToProps)(ShareModal);