Proyectos de Subversion LeadersLinked - Antes de SPA

Rev

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