Proyectos de Subversion LeadersLinked - Antes de SPA

Rev

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

Rev Autor Línea Nro. Línea
1025 stevensc 1
import React, { useEffect, useState } from "react";
1 www 2
import { connect } from "react-redux";
3
import { useForm } from "react-hook-form";
4
import FormErrorFeedback from "../../../shared/form-error-feedback/FormErrorFeedback";
5
import FeedCommentTemplate from "./feed-comment/FeedCommentTemplate";
6
import { openShareModal as OpenShareModalAction } from "../../../redux/share-modal/shareModal.actions";
7
import { addNotification } from "../../../redux/notification/notification.actions";
8
import { deleteFeed } from "../../../redux/feed/feed.actions";
9
import { shareModalTypes } from "../../../redux/share-modal/shareModal.types";
10
import parse from "html-react-parser";
1021 stevensc 11
import { axios } from "../../../utils";
1 www 12
import ConfirmModal from "../../../shared/confirm-modal/ConfirmModal";
57 steven 13
import { Modal } from "react-bootstrap";
1 www 14
import styles from "./feedTemplate.module.scss";
15
import { feedTypes } from "../../../redux/feed/feed.types";
16
 
17
const FeedTemplate = (props) => {
18
  // Destructuring feed data
1031 stevensc 19
 
1 www 20
  const {
21
    feed_unique,
22
    feed_id_encrypted,
23
    owner_name,
24
    owner_url,
25
    owner_image,
26
    owner_comments,
27
    owner_shared,
28
    owner_time_elapse,
29
    owner_description,
30
    owner_file_image,
31
    owner_file_video,
32
    owner_file_document,
33
    owner_file_image_preview,
34
    shared_name,
35
    shared_image,
36
    shared_time_elapse,
37
    shared_description,
38
    shared_file_video,
39
    shared_file_image_preview,
40
    shared_file_image,
41
    shared_file_document,
42
    feed_like_url,
43
    feed_unlike_url,
44
    feed_is_liked,
45
    feed_share_url,
46
    feed_delete_url,
47
    comments,
48
    comment_add_url,
1032 stevensc 49
  } = props.feed;
1 www 50
 
722 steven 51
  const [totalComments, setTotalComments] = useState(owner_comments || 0);
52
 
1 www 53
  // Destructuring redux
1033 stevensc 54
  /* const { feedType } = props; */
1 www 55
  const { deleteFeed, addNotification, openShareModal } = props;
56
 
57
  const [feedIsLiked, setFeedIsLiked] = useState(feed_is_liked);
58
 
59
  // react hook form
60
  const { register, handleSubmit, errors } = useForm();
61
 
62
  const [commentsState, setCommentsState] = useState(comments);
1023 stevensc 63
  const [ownerShared, setOwnerShared] = useState(owner_shared);
1 www 64
 
65
  const [isReadMoreActive, setIsReadMoreActive] = useState(false);
66
  const [showConfirmModal, setShowConfirmModal] = useState(false);
56 steven 67
  const [show, setShow] = useState(false);
1 www 68
 
1031 stevensc 69
  useEffect(() => {
70
    setOwnerShared(owner_shared)
1032 stevensc 71
  }, [owner_shared]);
1030 stevensc 72
 
1033 stevensc 73
  useEffect(() => {
74
    console.log(props)
75
  }, []);
76
 
56 steven 77
  const handleClose = () => setShow(false);
78
  const handleShow = () => setShow(true);
1 www 79
  const deleteFeedHandler = () => {
80
    axios.post(feed_delete_url).then((res) => {
81
      const data = res.data;
82
      if (data.success) {
83
        deleteFeed(feed_unique);
84
        addNotification({
85
          style: "success",
86
          msg: data.data,
87
        });
88
      } else {
89
        addNotification({
90
          style: "danger",
91
          msg: data.data,
92
        });
93
      }
94
    });
95
  };
96
 
97
  const handleShowConfirmModal = () => {
98
    setShowConfirmModal(!showConfirmModal);
99
  };
100
 
101
  const handleModalAccept = () => {
102
    deleteFeedHandler();
103
  };
104
 
105
  const likeHandler = (event, likeUrl) => {
106
    event.preventDefault();
107
    setFeedIsLiked(!feedIsLiked);
108
    axios.post(likeUrl).then((res) => {
109
      const resData = res.data;
110
      const { success, data } = resData;
111
      if (!success) {
112
        setFeedIsLiked((previousState) => !previousState);
113
        addNotification({
114
          style: "danger",
115
          msg: data,
116
        });
117
      }
118
    });
119
  };
120
 
121
  const submitCommentHandler = (data, e) => {
122
    const currentFormData = new FormData();
123
    for (let input in data) {
124
      currentFormData.append(input, data[input]);
125
    }
126
    axios.post(comment_add_url, currentFormData).then((res) => {
127
      const resData = res.data;
128
      const { data, success, total_comments } = resData;
129
      if (success) {
130
        const newComment = data;
722 steven 131
        setTotalComments(total_comments);
1 www 132
        setCommentsState([...commentsState, newComment]);
133
        e.target.reset();
134
      } else {
135
        addNotification({
136
          style: "danger",
137
          msg: data,
138
        });
139
      }
140
    });
141
  };
142
 
143
  const deleteCommentHandler = (commentUnique, deleteCommentUrl) => {
144
    axios
145
      .post(deleteCommentUrl)
146
      .then((res) => {
975 steven 147
        const { success, data, total_comments } = res.data;
1 www 148
        if (success) {
149
          const newCommentsState = commentsState.filter(
150
            (comment) => comment.unique !== commentUnique
151
          );
152
          setCommentsState(newCommentsState);
975 steven 153
          setTotalComments(total_comments);
1 www 154
        } else {
155
          addNotification({
156
            style: "danger",
157
            msg: data,
158
          });
159
        }
160
      })
161
      .catch((error) => {
162
        addNotification({
163
          style: "danger",
164
          msg: error.message,
165
        });
166
      });
167
  };
168
 
169
  const btnShareHandler = (event) => {
170
    event.preventDefault();
1018 stevensc 171
    openShareModal(feed_share_url, shareModalTypes.SHARE, feedTypes.DASHBOARD, feed_unique);
1 www 172
  };
173
 
174
  let commentsRender = null;
175
  if (commentsState.length) {
176
    commentsRender = (
177
      <div className={styles.commentSection}>
178
        <div className={`comment-sec comment-sec-${feed_unique}`}>
179
          <ul>
180
            {[...commentsState].reverse().map((commentData) => {
181
              const { unique } = commentData;
182
              return (
183
                <FeedCommentTemplate
184
                  commentData={commentData}
185
                  onDeleteHandler={deleteCommentHandler}
186
                  key={unique}
187
                />
188
              );
189
            })}
190
          </ul>
191
        </div>
192
      </div>
193
    );
194
  }
195
 
196
  let likeButton = feedIsLiked ? (
197
    <a
198
      href={feed_unlike_url}
199
      id={`btn-unlike-${feed_unique}`}
200
      data-feed-unique={feed_unique}
201
      className="btn-unlike"
202
      onClick={(event) => {
203
        likeHandler(event, feed_unlike_url);
204
      }}
205
    >
206
      <i className="fas fa-heart"></i>
207
      Ya no me gusta
208
    </a>
209
  ) : (
210
    <a
211
      href={feed_like_url}
212
      id={`btn-like-${feed_unique}`}
213
      data-feed-unique={feed_unique}
214
      className="btn-like"
215
      onClick={(event) => {
216
        likeHandler(event, feed_like_url);
217
      }}
218
    >
219
      <i className="far fa-heart"></i>
220
      Me gusta
221
    </a>
222
  );
223
 
224
  const readMoreHandler = (event) => {
225
    event.preventDefault();
226
    setIsReadMoreActive(!isReadMoreActive);
227
  };
228
 
229
  const htmlParsedText = (fullStringText) => {
230
    const fullText = parse(fullStringText);
231
    if (fullStringText.length > 500) {
232
      const shortenedString = fullStringText.substr(0, 500);
233
      const shortenedText = parse(`${shortenedString}... `);
234
      return (
235
        <React.Fragment>
236
          {isReadMoreActive ? fullText : shortenedText}
237
          <a
238
            href="#"
239
            onClick={(e) => {
240
              readMoreHandler(e);
241
            }}
242
          >
243
            {isReadMoreActive ? " Leer menos" : " Leer más"}
244
          </a>
245
        </React.Fragment>
246
      );
247
    } else {
248
      return fullText;
249
    }
250
  };
251
 
252
  let sharedName = null;
253
  if (shared_name) {
254
    sharedName = (
255
      <div className="shared-post-bar">
256
        <div className="post-bar">
257
          <div className="post_topbar">
258
            <div className="usy-dt">
259
              <img
260
                src={shared_image}
261
                alt=""
262
                style={{
263
                  width: "50px",
264
                  height: "auto",
265
                }}
266
              />
267
              <div className="usy-name">
268
                <h3>{shared_name}</h3>
269
                <span>
270
                  <img
271
                    style={{
272
                      width: "12px",
273
                      height: "auto",
274
                    }}
275
                    src="/images/clock.png"
276
                    alt=""
277
                  />
278
                  {shared_time_elapse}
279
                </span>
280
              </div>
281
            </div>
282
          </div>
283
          <div className="job_descp">
284
            <div className="show-read-more">
285
              {htmlParsedText(shared_description)}
286
            </div>
287
            {shared_file_image ? (
288
              <img src={shared_file_image} className="Entradas" />
289
            ) : null}
290
            {shared_file_video ? (
291
              <video
292
                src={shared_file_video}
293
                controls
294
                poster={shared_file_image_preview}
295
                preload="none"
296
              />
297
            ) : null}
298
            {shared_file_document ? (
299
              <a href={shared_file_document} target="_blank">
300
                Descargar
301
              </a>
302
            ) : null}
303
          </div>
304
        </div>
305
      </div>
306
    );
307
  }
59 steven 308
  const OwnerDescription = () => <div className="show-read-more">
309
    {htmlParsedText(owner_description)}
310
  </div>
55 steven 311
  const TopBar = () => <div className="post_topbar">
312
    <div className="usy-dt">
313
      <a href={owner_url}>
314
        <img
315
          src={owner_image}
316
          alt=""
317
          style={{
318
            width: "50px",
319
            height: "auto",
320
          }}
321
        />
322
      </a>
323
      <div className="usy-name">
324
        <a href={owner_url}>
325
          <h3>{owner_name}</h3>
326
        </a>
327
        <span>
328
          <img src="/images/clock.png" alt="" />
329
          {owner_time_elapse}
330
          {feed_delete_url ? (
331
            <a
332
              href="#"
333
              className="btn-feed-trash"
334
              data-link={feed_delete_url}
335
              data-feed-unique={feed_unique}
336
              onClick={(e) => {
337
                e.preventDefault();
338
                handleShowConfirmModal();
339
              }}
340
            >
341
              <i className="fa fa-trash"></i>
342
            </a>
343
          ) : null}
344
        </span>
345
      </div>
346
    </div>
347
  </div>
1 www 348
 
1021 stevensc 349
  const Content = ({ showDescription }) => <div className="job_descp">
58 steven 350
    {
351
      !!showDescription && (
59 steven 352
        <OwnerDescription />
58 steven 353
      )
354
    }
355
    {owner_file_image ? (
356
      <img src={owner_file_image} className="Entradas" />
357
    ) : null}
358
    {owner_file_video ? (
359
      <video
360
        src={owner_file_video}
361
        controls
362
        poster={owner_file_image_preview}
363
        preload="none"
364
      />
365
    ) : null}
366
    {owner_file_document ? (
367
      <a href={owner_file_document} target="_blank">
368
        Descargar
369
      </a>
370
    ) : null}
371
    {sharedName}
55 steven 372
  </div>
1 www 373
  return (
374
    <React.Fragment>
56 steven 375
      <Modal
376
        show={show}
377
        onHide={handleClose}
59 steven 378
        dialogClassName="modal-md"
56 steven 379
      >
380
        <div
381
          className="row"
382
        >
383
          <div
384
            className="col-md-8 col-sm-12 col-12"
385
          >
205 steven 386
            <Content
387
              showDescription
388
            />
56 steven 389
          </div>
390
          <div
391
            className="col-md-4 col-sm-12 col-12"
392
          >
393
            <TopBar />
59 steven 394
            <OwnerDescription />
56 steven 395
          </div>
396
        </div>
397
      </Modal>
718 steven 398
      <div className={styles.postContainer} >
58 steven 399
        <TopBar
400
          showDescription
401
        />
718 steven 402
        <div
403
          onClick={() => (owner_file_image || owner_file_video || owner_file_document) ? handleShow() : null}
404
        >
405
          <Content
406
            showDescription
407
          />
408
        </div>
1 www 409
        <div className="job-status-bar">
410
          <ul className="like-com">
411
            <li>{likeButton}</li>
412
            <li>
413
              <a
414
                href="#"
415
                id={`btn-comments-${feed_unique}`}
416
                className="btn-indicator"
417
              >
722 steven 418
                <i className="fas fa-comments"></i> {totalComments}
1 www 419
              </a>
420
            </li>
421
            <li>
422
              <a
423
                href="#"
424
                id={`btn-share-${feed_unique}`}
425
                className="btn-indicator"
426
              >
1023 stevensc 427
                <i className="fas fa-share"></i> {ownerShared}
1 www 428
              </a>
429
            </li>
430
          </ul>
431
          <a
432
            href={feed_share_url}
433
            data-feed-unique={feed_unique}
434
            className="btn-feed-share"
435
            onClick={(e) => {
436
              btnShareHandler(e);
437
            }}
438
          >
439
            <i className="fas fa-share"></i>Compartir
440
          </a>
441
        </div>
442
        {commentsRender}
443
        <div>
444
          <form
445
            className={`form-comment-feed-${feed_unique}`}
446
            data-feed-unique={feed_unique}
447
            onSubmit={handleSubmit(submitCommentHandler)}
448
          >
449
            <div className={styles.feedCommentContainer}>
450
              <input
451
                className={styles.commentInput}
452
                type="text"
453
                name="comment"
454
                id={`comment-${feed_unique}`}
455
                maxLength="256"
456
                placeholder="Escribe un comentario"
457
                ref={register({
458
                  required: {
459
                    value: "true",
460
                    message: "El campo es requerido",
461
                  },
462
                })}
463
              />
464
              <button type="submit" className={styles.submitButton}>
465
                Enviar
466
              </button>{" "}
467
              {/* Falta multilenguaje */}
468
            </div>
469
          </form>
470
          {errors.comment && (
471
            <FormErrorFeedback>{errors.comment.message}</FormErrorFeedback>
472
          )}
473
        </div>
474
      </div>
475
      <ConfirmModal
476
        show={showConfirmModal}
477
        onClose={() => {
478
          setShowConfirmModal(false);
479
        }}
480
        onAccept={handleModalAccept}
481
        acceptLabel="Aceptar"
482
      />
483
    </React.Fragment>
484
  );
485
};
486
 
487
const mapStateToProps = (state) => ({
488
  currentFeed: state.feed.currentFeed,
489
  isShareModalOpen: state.feed.isShareModalOpen,
490
  feedType: state.shareModal.feedType,
491
});
492
 
493
const mapDispatchToProps = {
494
  deleteFeed: (feedId) => deleteFeed(feedId),
1021 stevensc 495
  openShareModal: (postUrl, modalType, feedType, feed_unique) => OpenShareModalAction(postUrl, modalType, feedType, feed_unique),
1 www 496
  addNotification: (notification) => addNotification(notification),
497
};
498
 
1033 stevensc 499
export default connect(null, mapDispatchToProps)(FeedTemplate);