Rev 2852 | Rev 3202 | Ir a la última revisión | Autoría | Comparar con el anterior | Ultima modificación | Ver Log |
import React, { useEffect, useState } from "react";
import { useDispatch } from "react-redux";
import { useForm } from "react-hook-form";
import FormErrorFeedback from "../../../shared/form-error-feedback/FormErrorFeedback";
import FeedCommentTemplate from "./feed-comment/FeedCommentTemplate";
import { shareModalTypes } from "../../../redux/share-modal/shareModal.types";
import parse from "html-react-parser";
import { axios } from "../../../utils";
import ConfirmModal from "../../../shared/confirm-modal/ConfirmModal";
import { Modal } from "react-bootstrap";
import { feedTypes } from "../../../redux/feed/feed.types";
import { BsFillTrashFill, BsHeart, BsHeartFill, BsTrash } from 'react-icons/bs'
import { RiShareForwardLine } from 'react-icons/ri'
import { TbSend } from "react-icons/tb";
import { BiDotsVerticalRounded, BiMessage } from "react-icons/bi";
import styles from "./feedTemplate.module.scss";
import styleFeed from "../share-feed/shareFeed.module.scss";
// Redux actions
import { openShareModal } from "../../../redux/share-modal/shareModal.actions";
import { addNotification } from "../../../redux/notification/notification.actions";
import { deleteFeed } from "../../../redux/feed/feed.actions";
const FeedTemplate = ({ feed, owner_shared, image }) => {
// Destructuring feed data
const {
feed_unique,
owner_name,
owner_url,
owner_image,
owner_time_elapse,
owner_description,
owner_file_image,
owner_file_video,
owner_file_document,
owner_file_image_preview,
shared_name,
shared_image,
shared_time_elapse,
shared_description,
shared_file_video,
shared_file_image_preview,
shared_file_image,
shared_file_document,
feed_likes,
feed_like_url,
feed_unlike_url,
feed_is_liked,
feed_share_url,
feed_delete_url,
comments,
comment_add_url,
} = feed;
// react hook form
const { register, handleSubmit, errors } = useForm();
const dispatch = useDispatch()
const [totalComments, setTotalComments] = useState(comments.length || 0);
const [feedIsLiked, setFeedIsLiked] = useState(feed_is_liked);
const [commentsState, setCommentsState] = useState(comments);
const [sharedState, setSharedState] = useState(owner_shared);
const [likesState, setLikesState] = useState(feed_likes);
const [isReadMoreActive, setIsReadMoreActive] = useState(false);
const [showConfirmModal, setShowConfirmModal] = useState(false);
const [displayOption, setDisplayOption] = useState(false)
const [show, setShow] = useState(false);
const handleClose = () => setShow(false);
const handleShow = () => setShow(true);
useEffect(() => {
setSharedState(owner_shared)
}, [owner_shared]);
const deleteFeedHandler = () => {
axios.post(feed_delete_url)
.then((res) => {
const { data } = res
if (data.success) {
dispatch(deleteFeed(feed_unique));
dispatch(addNotification({
style: "success",
msg: data.data,
}));
} else {
dispatch(addNotification({
style: "danger",
msg: data.data,
}));
}
});
};
const handleShowConfirmModal = () => {
setShowConfirmModal(!showConfirmModal);
};
const likeHandler = (likeUrl) => {
axios.post(likeUrl)
.then((res) => {
const { success, data } = res.data;
if (!success) {
setFeedIsLiked((previousState) => !previousState);
dispatch(addNotification({
style: "danger",
msg: data,
}));
} else {
setLikesState(data.likes)
setFeedIsLiked(!feedIsLiked);
}
});
};
const submitCommentHandler = (data, e) => {
const currentFormData = new FormData();
for (let input in data) {
currentFormData.append(input, data[input]);
}
axios.post(comment_add_url, currentFormData).then((res) => {
const resData = res.data;
const { data, success, total_comments } = resData;
if (success) {
const newComment = data;
setTotalComments(total_comments);
setCommentsState([newComment, ...commentsState]);
e.target.reset();
} else {
dispatch(addNotification({
style: "danger",
msg: data,
}));
}
});
};
const deleteCommentHandler = (commentUnique, deleteCommentUrl) => {
axios.post(deleteCommentUrl)
.then((res) => {
const { success, data, total_comments } = res.data;
if (success) {
const newCommentsState = commentsState.filter(
(comment) => comment.unique !== commentUnique
);
setCommentsState(newCommentsState);
setTotalComments(total_comments);
} else {
dispatch(addNotification({
style: "danger",
msg: data,
}));
}
})
.catch((error) => {
dispatch(addNotification({
style: "danger",
msg: error.message,
}));
});
};
const btnShareHandler = () => {
dispatch(openShareModal(feed_share_url, shareModalTypes.SHARE, feedTypes.DASHBOARD, feed_unique))
};
let commentsRender = null;
if (commentsState.length) {
commentsRender = (
<div className={styles.commentSection}>
<div className={`comment-sec comment-sec-${feed_unique}`}>
<ul>
{[...commentsState].reverse().map((commentData) => {
const { unique } = commentData;
return (
<FeedCommentTemplate
commentData={commentData}
onDeleteHandler={deleteCommentHandler}
key={unique}
/>
);
})}
</ul>
</div>
</div>
);
}
const readMoreHandler = (event) => {
event.preventDefault();
setIsReadMoreActive(!isReadMoreActive);
};
const htmlParsedText = (fullStringText) => {
const fullText = parse(fullStringText);
if (fullStringText.length > 500) {
const shortenedString = fullStringText.substr(0, 500);
const shortenedText = parse(`${shortenedString}... `);
return (
<React.Fragment>
{isReadMoreActive ? fullText : shortenedText}
<a
href="#"
onClick={(e) => {
readMoreHandler(e);
}}
>
{isReadMoreActive ? " Leer menos" : " Leer más"}
</a>
</React.Fragment>
);
} else {
return fullText;
}
};
let sharedName = null;
if (shared_name) {
sharedName = (
<div className="shared-post-bar">
<div className="post-bar">
<div className="post_topbar">
<div className="usy-dt">
<img
src={shared_image}
alt=""
style={{
width: "50px",
height: "auto",
}}
/>
<div className="usy-name">
<h3>{shared_name}</h3>
<span>
{shared_time_elapse}
</span>
</div>
</div>
</div>
<div className="job_descp">
<div className="show-read-more">
{htmlParsedText(shared_description)}
</div>
{shared_file_image ? (
<img src={shared_file_image} className="Entradas" />
) : null}
{shared_file_video ? (
<video
src={shared_file_video}
controls
poster={shared_file_image_preview}
preload="none"
/>
) : null}
{shared_file_document ? (
<a href={shared_file_document} target="_blank">
Descargar
</a>
) : null}
</div>
</div>
</div>
);
}
const OwnerDescription = () => <div className="show-read-more">
{htmlParsedText(owner_description)}
</div>
const TopBar = () => (
< div className="post_topbar" >
<div className="usy-dt">
<a href={owner_url}>
<img src={owner_image} alt="" style={{
width: "50px",
height: "auto",
}}
/>
</a>
<div className="usy-name">
<a href={owner_url}>
<h3>{owner_name}</h3>
</a>
<span>
{owner_time_elapse}
</span>
</div>
</div>
{
feed_delete_url
&&
<div className="cursor-pointer d-flex align-items-center">
<BiDotsVerticalRounded
onClick={() => setDisplayOption(!displayOption)}
style={{ fontSize: '1.5rem' }}
/>
<div className={`feed-options ${displayOption ? 'active' : ''}`}>
<ul>
<li>
<button
className="option-btn"
onClick={handleShowConfirmModal}
>
<BsTrash className="mr-1" />
Delete
</button>
</li>
</ul>
</div>
</div>
}
</div >
)
const Content = ({ showDescription }) => (
<div className="job_descp">
{
showDescription
&&
<OwnerDescription />
}
{
owner_file_image
&&
<img src={owner_file_image} className="Entradas" />
}
{
owner_file_video
&&
<video
src={owner_file_video}
controls
poster={owner_file_image_preview}
preload="none"
/>
}
{
owner_file_document
&&
<a href={owner_file_document} target="_blank">
Descargar
</a>
}
{sharedName}
</div>
)
return (
<React.Fragment>
<Modal
show={show}
onHide={handleClose}
dialogClassName="modal-md"
>
<div
className="row"
>
<div
className="col-md-8 col-sm-12 col-12"
>
<Content
showDescription
/>
</div>
<div
className="col-md-4 col-sm-12 col-12"
>
<TopBar />
<OwnerDescription />
</div>
</div>
</Modal>
<div className={styles.postContainer}>
<TopBar
showDescription
/>
<div
onClick={() => (owner_file_image || owner_file_video || owner_file_document) ? handleShow() : null}
>
<Content
showDescription
/>
</div>
<div className="job-status-bar">
<ul className="reactions-list">
<li>
<button
type="button"
id={feedIsLiked ? `btn-unlike-${feed_unique}` : `btn-like-${feed_unique}`}
data-feed-unique={feed_unique}
className={feedIsLiked ? "btn-unlike" : "btn-like"}
onClick={() => {
likeHandler(feedIsLiked ? feed_unlike_url : feed_like_url);
}}
>
{feedIsLiked ? <BsHeartFill className="mr-1" /> : <BsHeart className="mr-1" />}
{likesState}
</button>
</li>
<li>
<button
type="button"
id={`btn-comments-${feed_unique}`}
className="btn-indicator"
>
<BiMessage className="mr-1" />
{totalComments}
</button>
</li>
<li>
<button
type="button"
id={`btn-share-${feed_unique}`}
className="btn-indicator"
onClick={btnShareHandler}
>
<RiShareForwardLine className="mr-1" />
{sharedState}
</button>
</li>
</ul>
</div>
{commentsRender}
<div>
<form
className={`form-comment-feed-${feed_unique}`}
data-feed-unique={feed_unique}
onSubmit={handleSubmit(submitCommentHandler)}
>
<div className={styles.feedCommentContainer}>
<img src={image} alt="User profile image" />
<input
className={styles.commentInput}
type="text"
name="comment"
id={`comment-${feed_unique}`}
maxLength="256"
placeholder="Escribe un comentario"
ref={register({
required: {
value: "true",
message: "El campo es requerido",
},
})}
/>
<button className={`${styleFeed.shareIconContainer} ${styleFeed.iconActive}`} >
<TbSend className={styleFeed.shareIcon} />
</button>
{/* Falta multilenguaje */}
</div>
</form>
{
errors.comment
&&
<FormErrorFeedback>{errors.comment.message}</FormErrorFeedback>
}
</div>
</div>
<ConfirmModal
show={showConfirmModal}
onClose={() => setShowConfirmModal(false)}
onAccept={deleteFeedHandler}
acceptLabel="Aceptar"
/>
</React.Fragment>
);
};
export default React.memo(FeedTemplate);