Proyectos de Subversion LeadersLinked - Antes de SPA

Rev

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