Proyectos de Subversion LeadersLinked - Antes de SPA

Rev

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