Rev 7089 | Rev 7102 | Ir a la última revisión | Autoría | Comparar con el anterior | Ultima modificación | Ver Log |
import React, { useEffect, useState, useRef } from 'react'
import { useDispatch, useSelector } from 'react-redux'
import { axios } from '../../../utils'
import {
EmailIcon,
EmailShareButton,
FacebookIcon,
FacebookShareButton,
RedditIcon,
RedditShareButton,
TelegramIcon,
TelegramShareButton,
TwitterIcon,
TwitterShareButton,
WhatsappIcon,
WhatsappShareButton,
} from 'react-share'
import parse from 'html-react-parser'
import RecommendIcon from '@mui/icons-material/Recommend'
import FavoriteIcon from '@mui/icons-material/FavoriteTwoTone'
import VolunteerActivismIcon from '@mui/icons-material/VolunteerActivism'
import EmojiEmotionsIcon from '@mui/icons-material/EmojiEmotions'
import TungstenIcon from '@mui/icons-material/Tungsten'
import GroupsRoundedIcon from '@mui/icons-material/GroupsRounded'
import { feedTypes } from '../../redux/feed/feed.types'
import { shareModalTypes } from '../../../redux/share-modal/shareModal.types'
import { deleteFeed } from '../../redux/feed/feed.actions'
import { openShareModal } from '../../../redux/share-modal/shareModal.actions'
import { addNotification } from '../../../redux/notification/notification.actions'
import FeedCommentSection from './CommentSection'
import useOutsideClick from '../../hooks/useOutsideClick'
import FeedModal from './FeedModal'
import ConfirmModal from '../modals/ConfirmModal'
import SurveyForm from '../survey-form/SurveyForm'
import ReactionsButton from '../UI/buttons/ReactionsButton'
const Feed = ({ feed, owner_shared, image }) => {
const {
feed_unique,
owner_name,
owner_url,
owner_image,
owner_time_elapse,
owner_file_image,
owner_file_video,
owner_file_document,
owner_feed_type,
feed_highlighted,
feed_share_url,
feed_delete_url,
comments,
comment_add_url,
feed_share_external_url,
} = feed
const [totalComments, setTotalComments] = useState(0)
const [ownerReactions, setOwnerReaction] = useState(feed.feed_reactions)
const [totalReactions, setTotalReactions] = useState(0)
const [sharedState, setSharedState] = useState(owner_shared)
const [shareUrl, setShareUrl] = useState('')
const [showComments, setShowComments] = useState(false)
const [shareOptions, setShareOptions] = useState(false)
const [show, setShow] = useState(false)
const shareContainer = useRef(null)
const dispatch = useDispatch()
useOutsideClick(shareContainer, () => setShareOptions(false))
const reactionsOptions = [
{
type: 'r',
icon: <RecommendIcon style={{ color: '#7405f9' }} />,
},
{
type: 's',
icon: <VolunteerActivismIcon style={{ color: '#6495ED' }} />,
},
{
type: 'l',
icon: <FavoriteIcon style={{ color: '#DF704D' }} />,
},
{
type: 'i',
icon: (
<TungstenIcon
style={{ color: '#F5BB5C', transform: 'rotate(180deg)' }}
/>
),
},
{
type: 'f',
icon: <EmojiEmotionsIcon style={{ color: '#FF7F50' }} />,
},
]
const getShareUrl = new Promise((resolve, reject) => {
if (shareOptions) {
axios
.get(feed_share_external_url)
.then(({ data }) => {
if (!data.success) {
dispatch(addNotification({ style: 'danger', msg: data.data }))
setShareOptions(false)
return reject(data.data)
}
setShareUrl(data.data)
return resolve(data.data)
})
.catch((err) => reject(err))
}
})
const displayComments = () => {
setShowComments(!showComments)
}
const btnShareHandler = () => {
dispatch(
openShareModal(
feed_share_url,
shareModalTypes.SHARE,
feedTypes.DASHBOARD,
feed_unique
)
)
}
useEffect(() => setSharedState(owner_shared), [owner_shared])
useEffect(() => {
const feedReactions = ownerReactions?.reduce(
(acc, reaction) => acc + Number(reaction.total),
0
)
setTotalReactions(feedReactions)
}, [ownerReactions])
return (
<>
<FeedModal isShow={show} handleClose={() => setShow(false)} feed={feed} />
<div className={`feed ${feed_highlighted ? 'highlighted' : ''}`}>
<FeedHeader
ownerName={owner_name}
ownerImage={owner_image}
ownerTimeElapse={owner_time_elapse}
ownerUrl={owner_url}
feedDeleteUrl={feed_delete_url}
feedUnique={feed_unique}
feedType={owner_feed_type}
/>
<div
onClick={() =>
(owner_file_image || owner_file_video || owner_file_document) &&
setShow(true)
}
>
<Feed.Content
isShare={!!feed.shared_name}
image={feed.owner_file_image}
fileVideo={feed.owner_file_video}
imagePreview={feed.owner_file_image_preview}
document={feed.owner_file_document}
description={feed.owner_description}
type={feed.feed_content_type}
voteUrl={feed.feed_vote_url}
sharedItem={{
name: feed.shared_name,
image: feed.shared_image,
time_elapse: feed.shared_time_elapse,
description: feed.shared_description,
file_video: feed.shared_file_video,
file_image_preview: feed.shared_file_image_preview,
file_image: feed.shared_file_image,
file_document: feed.shared_file_document,
}}
/>
</div>
<div className="reactions-counter">
{reactionsOptions
.filter((option) =>
ownerReactions.find(
(reaction) => reaction.reaction === option.type
)
)
.map((reaction) => reaction.icon)}
<span>{totalReactions} reacciones</span>
</div>
<ul className="reactions-list">
<li>
<ReactionsButton
onChange={(reactions) => setOwnerReaction(reactions)}
currentReaction={feed.feed_my_reaction}
withLabel
deleteUrl={feed.feed_delete_reaction_url}
reactionTypesUrl={{
r: feed.feed_save_reaction_recommended_url,
s: feed.feed_save_reaction_support_url,
l: feed.feed_save_reaction_love_url,
i: feed.feed_save_reaction_interest_url,
f: feed.feed_save_reaction_fun_url,
}}
/>
</li>
<li>
<button
type="button"
id={`btn-comments-${feed_unique}`}
className="btn-indicator"
onClick={displayComments}
>
<img src="/images/icons/message.png" className="mr-1 img-icon" />
{totalComments}
</button>
</li>
<li>
<button
type="button"
id={`btn-share-${feed_unique}`}
className="btn-indicator"
onClick={btnShareHandler}
>
<img src="/images/icons/share.png" className="mr-1 img-icon" />
{sharedState}
</button>
</li>
<li className="position-relative">
<button
type="button"
className="btn-indicator"
onClick={() => setShareOptions(!shareOptions)}
>
<i className="mr-1 far fa-share-square" />
</button>
{shareOptions && (
<div className="ext_share" ref={shareContainer}>
<FacebookShareButton
beforeOnClick={() => getShareUrl}
url={shareUrl}
>
<FacebookIcon size={32} round />
</FacebookShareButton>
<TwitterShareButton
beforeOnClick={() => getShareUrl}
url={shareUrl}
>
<TwitterIcon size={32} round />
</TwitterShareButton>
<TelegramShareButton
beforeOnClick={() => getShareUrl}
url={shareUrl}
>
<TelegramIcon size={32} round />
</TelegramShareButton>
<WhatsappShareButton
beforeOnClick={() => getShareUrl}
url={shareUrl}
>
<WhatsappIcon size={32} round />
</WhatsappShareButton>
<RedditShareButton
beforeOnClick={() => getShareUrl}
url={shareUrl}
>
<RedditIcon size={32} round />
</RedditShareButton>
<EmailShareButton
beforeOnClick={() => getShareUrl}
url={shareUrl}
>
<EmailIcon size={32} round />
</EmailShareButton>
</div>
)}
</li>
</ul>
<FeedCommentSection
isShow={showComments}
image={image}
addUrl={comment_add_url}
currentComments={comments}
updateTotalComments={(totalComments) =>
setTotalComments(totalComments)
}
/>
</div>
</>
)
}
export const FeedContent = ({
showDescription = true,
image,
video,
imagePreview,
document,
description,
isShare,
sharedItem,
type,
voteUrl,
}) => {
return (
<div className="job_descp">
{type !== 'fast-survey' && showDescription ? (
<Feed.Description description={description} />
) : (
<SurveyForm
active={description.active}
question={description.question}
answers={[
description.answer1,
description.answer2,
description.answer3,
description.answer4,
description.answer5,
]}
votes={
description.votes1 && [
description.votes1,
description.votes2,
description.votes3,
description.votes4,
description.votes5,
]
}
time={description.time_remaining}
voteUrl={voteUrl}
resultType={description.result_type}
/>
)}
{image && <img src={image} className="Entradas" loading="lazy" />}
{video && (
<video src={video} controls poster={imagePreview} preload="none" />
)}
{document && (
<a href={document} download target="_blank" rel="noreferrer">
<img
className="pdf"
src="/images/extension/pdf.png"
alt="pdf"
width="40px"
/>
</a>
)}
{isShare && (
<Feed.Shared
name={sharedItem.name}
ownerImage={sharedItem.image}
image={sharedItem.file_image}
timeElapse={sharedItem.time_elapse}
description={sharedItem.description}
video={sharedItem.file_video}
imagePreview={sharedItem.file_image_preview}
document={sharedItem.file_document}
/>
)}
</div>
)
}
export const FeedDescription = ({ description }) => {
const [isReadMoreActive, setIsReadMoreActive] = useState(false)
const labels = useSelector(({ intl }) => intl.labels)
const readMoreHandler = () => setIsReadMoreActive(!isReadMoreActive)
const htmlParsedText = (fullStringText) => {
const fullText = parse(fullStringText)
if (fullStringText.length > 500) {
const shortenedString = fullStringText.substr(0, 500)
const shortenedText = parse(`${shortenedString}... `)
return (
<p>
{isReadMoreActive ? fullText : shortenedText}
<span className="cursor-pointer" onClick={readMoreHandler}>
{isReadMoreActive ? labels.read_less : labels.read_more}
</span>
</p>
)
}
return <p>{fullText}</p>
}
return <div className="show-read-more">{htmlParsedText(description)}</div>
}
export const FeedShared = ({
name,
ownerImage,
image,
timeElapse,
description,
video,
imagePreview,
document,
}) => {
const [isReadMoreActive, setIsReadMoreActive] = useState(false)
const labels = useSelector(({ intl }) => intl.labels)
const readMoreHandler = () => setIsReadMoreActive(!isReadMoreActive)
const htmlParsedText = (fullStringText = '') => {
const fullText = parse(fullStringText)
if (fullStringText.length > 500) {
const shortenedString = fullStringText.substr(0, 500)
const shortenedText = parse(`${shortenedString}... `)
return (
<p>
{isReadMoreActive ? fullText : shortenedText}
<span className="cursor-pointer" onClick={readMoreHandler}>
{isReadMoreActive ? labels.read_less : labels.read_more}
</span>
</p>
)
}
return <p>{fullText}</p>
}
return (
<div className="shared-post-bar">
<div className="post-bar">
<div className="post_topbar">
<div className="usy-dt">
<img
src={ownerImage}
alt=""
style={{ width: '50px', height: 'auto' }}
/>
<div className="usy-name">
<h3>{name}</h3>
<span>{timeElapse}</span>
</div>
</div>
</div>
<div className="job_descp">
<div className="show-read-more">{htmlParsedText(description)}</div>
{image && <img src={image} className="Entradas" loading="lazy" />}
{video && (
<video src={video} controls poster={imagePreview} preload="none" />
)}
{document && (
<a href={document} target="_blank" rel="noreferrer">
<img
className="pdf"
src="/images/extension/pdf.png"
alt="pdf"
width="40px"
/>
</a>
)}
</div>
</div>
</div>
)
}
export const FeedHeader = ({
ownerName,
ownerImage,
ownerTimeElapse,
ownerUrl,
feedDeleteUrl,
feedUnique,
feedType,
}) => {
const [showConfirmModal, setShowConfirmModal] = useState(false)
const [displayOption, setDisplayOption] = useState(false)
const deleteButton = useRef(null)
const labels = useSelector(({ intl }) => intl.labels)
const dispatch = useDispatch()
useOutsideClick(deleteButton, () => setDisplayOption(false))
const handleShowConfirmModal = () => {
setShowConfirmModal(!showConfirmModal)
}
const deleteFeedHandler = () => {
axios.post(feedDeleteUrl).then((res) => {
const { data } = res
if (!data.success) {
dispatch(addNotification({ style: 'danger', msg: data.data }))
return
}
dispatch(addNotification({ style: 'success', msg: data.data }))
handleShowConfirmModal()
dispatch(deleteFeed(feedUnique))
})
}
return (
<>
<div className="post_topbar">
<div className="usy-dt">
<a href={ownerUrl}>
<img
src={ownerImage}
alt=""
style={{ width: '50px', height: 'auto' }}
/>
</a>
<div className="usy-name">
<a href={ownerUrl}>
<h3>{ownerName}</h3>
</a>
<span>
{feedType === 'g' && <GroupsRoundedIcon />}
{ownerTimeElapse}
</span>
</div>
</div>
{feedDeleteUrl && (
<div className="cursor-pointer d-flex align-items-center">
<img
src="/images/icons/options.png"
className="cursor-pointer img-icon options"
onClick={() => setDisplayOption(!displayOption)}
/>
<div className={`feed-options ${displayOption ? 'active' : ''}`}>
<ul>
<li>
<button
className="option-btn"
onClick={handleShowConfirmModal}
ref={deleteButton}
>
<i className="fa fa-trash-o mr-1" />
{labels.delete}
</button>
</li>
</ul>
</div>
<ConfirmModal
show={showConfirmModal}
onClose={() => handleShowConfirmModal(false)}
onAccept={deleteFeedHandler}
acceptLabel="Aceptar"
/>
</div>
)}
</div>
</>
)
}
Feed.Shared = FeedShared
Feed.Description = FeedDescription
Feed.Content = FeedContent
Feed.Header = FeedHeader
export default React.memo(Feed)