Proyectos de Subversion LeadersLinked - Antes de SPA

Rev

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