Rev 6835 | Rev 7142 | Ir a la última revisión | Autoría | Comparar con el anterior | Ultima modificación | Ver Log |
import React, { useEffect, useRef, useState } from 'react'import { axios } from '../../../utils'import { feedTypes } from '../../../redux/feed/feed.types'import { deleteFeed } from '../../../redux/feed/feed.actions'import { openShareModal } from '../../../redux/share-modal/shareModal.actions'import { shareModalTypes } from '../../../redux/share-modal/shareModal.types'import { addNotification } from '../../../redux/notification/notification.actions'import { connect, useDispatch, useSelector } from 'react-redux'import parse from 'html-react-parser'import TungstenIcon from '@mui/icons-material/Tungsten'import FavoriteIcon from '@mui/icons-material/FavoriteTwoTone'import RecommendIcon from '@mui/icons-material/Recommend'import AccessTimeIcon from '@mui/icons-material/AccessTime'import SendOutlinedIcon from '@mui/icons-material/SendOutlined'import ChatOutlinedIcon from '@mui/icons-material/ChatOutlined'import ShareOutlinedIcon from '@mui/icons-material/ShareOutlined'import EmojiEmotionsIcon from '@mui/icons-material/EmojiEmotions'import VolunteerActivismIcon from '@mui/icons-material/VolunteerActivism'import InputOption from './InputOption'import Avatar from '../../UI/AvatarImage'import ConfirmModal from '../../modals/ConfirmModal'import FeedCommentSection from '../CommentSection'import withExternalShare from './withExternalShare'import FeedModal from '../FeedModal'import withReactions from '../withReaction'import SurveyForm from '../../survey-form/SurveyForm'import './Feed.scss'const Feed = (props) => {const {isShare = false,feed_unique,feed_share_url,feed_share_external_url,feed_delete_url,feed_my_reaction,feed_save_reaction_recommended_url,feed_save_reaction_support_url,feed_save_reaction_love_url,feed_save_reaction_interest_url,feed_save_reaction_fun_url,feed_delete_reaction_url,feed_reactions,owner_url,image,owner_image,owner_name,owner_description,owner_shared,owner_comments,owner_time_elapse,owner_file_image_preview,owner_file_video,owner_file_image,owner_file_document,comment_add_url,comments,shared_name,shared_image,shared_time_elapse,shared_description,shared_file_video,shared_file_image_preview,shared_file_image,owner_external_shared,shared_file_document,shared_url,feed_increment_external_counter_url,feed_content_type,feed_vote_url,addNotification, // REDUX ACTIONopenShareModal, // REDUX ACTION} = propsconst [ownerReactions, setOwnerReaction] = useState(feed_reactions)const [currentReaction, setCurrentReaction] = useState(feed_my_reaction)const [totalReactions, setTotalReactions] = useState(0)const [totalComments, setTotalComments] = useState(owner_comments)const [externalShare, setExternalShare] = useState(owner_external_shared)const [sharedState, setSharedState] = useState(owner_shared)const [showComments, setShowComments] = useState(false)const [showModal, setShowModal] = useState(false)const labels = useSelector(({ intl }) => intl.labels)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: (<TungstenIconstyle={{ color: '#F5BB5C', transform: 'rotate(180deg)' }}/>),},{type: 'f',icon: <EmojiEmotionsIcon style={{ color: '#FF7F50' }} />,},]const handleShare = () =>openShareModal(feed_share_url,shareModalTypes.SHARE,feedTypes.DASHBOARD,feed_unique)const handleExternalShare = (value) => setExternalShare(value)const displayCommentSection = () => setShowComments(!showComments)const saveReaction = async (type) => {const reactionTypesUrl = {r: feed_save_reaction_recommended_url,s: feed_save_reaction_support_url,l: feed_save_reaction_love_url,i: feed_save_reaction_interest_url,f: feed_save_reaction_fun_url,}await axios.post(reactionTypesUrl[type]).then((res) => {const { success, data } = res.dataif (!success) {addNotification({ style: 'danger', msg: data })}setOwnerReaction(data.reactions)setCurrentReaction(type)})}const deleteReaction = async () => {await axios.post(feed_delete_reaction_url).then((res) => {const { success, data } = res.dataif (!success) {addNotification({ style: 'danger', msg: data })return}setOwnerReaction(data.reactions)setCurrentReaction('')})}const ExternalShareButton = withExternalShare(InputOption,feed_share_external_url,{Icon: SendOutlinedIcon,color: 'gray',title: 'Send',shareUrl: feed_increment_external_counter_url,setValue: handleExternalShare,withTitle: true,})const WithReactionIcon = withReactions(InputOption, {onSelect: saveReaction,onDelete: deleteReaction,myReaction: currentReaction,withTitle: true,})useEffect(() => setSharedState(owner_shared), [owner_shared])useEffect(() => {const feedReactions = ownerReactions?.reduce((acc, reaction) => acc + Number(reaction.total),0)setTotalReactions(feedReactions)}, [ownerReactions])return (<>{showModal && (<FeedModalisShow={true}feed={props}handleClose={() => setShowModal(false)}/>)}<div className="feed"><Feed.Headerimage={owner_image}name={owner_name}timeElapsed={owner_time_elapse}viewUrl={owner_url}deleteUrl={feed_delete_url}feedUnique={feed_unique}/><divclassName="feed__body"onClick={() =>(owner_file_image || owner_file_video || owner_file_document) &&setShowModal(true)}><Feed.Contentdescription={owner_description}image={owner_file_image}imagePreview={owner_file_image_preview}video={owner_file_video}document={owner_file_document}sharedItem={{name: shared_name,image: shared_image,time_elapse: shared_time_elapse,description: shared_description,file_video: shared_file_video,file_image_preview: shared_file_image_preview,file_image: shared_file_image,file_document: shared_file_document,shared_url,}}type={feed_content_type}voteUrl={feed_vote_url}/></div>{!isShare && feed_content_type !== 'fast-survey' && (<div className="px-3 d-flex align-items-center justify-content-between"><div className="reactions-counter">{reactionsOptions.filter((option) =>ownerReactions.find((reaction) => reaction.reaction === option.type)).map((reaction) => reaction.icon)}<span>{totalReactions} reacciones</span></div><divclassName="d-inline-flex align-items-center"style={{ gap: '5px' }}>{!!totalComments && (<span>{`${totalComments} ${labels.comments?.toLowerCase()}`}</span>)}{!!sharedState && (<span>{`${sharedState} ${labels.shared?.toLowerCase()}`}</span>)}{!!externalShare && (<span>{`${externalShare} ${labels.sends?.toLowerCase()}`}</span>)}</div></div>)}{!isShare && feed_content_type !== 'fast-survey' && (<div className="feed__buttons"><WithReactionIcon withTitle /><InputOptionIcon={ChatOutlinedIcon}title={labels.comment}color="gray"onClick={displayCommentSection}withTitle/><InputOptionIcon={ShareOutlinedIcon}title={labels.share}color="gray"onClick={handleShare}withTitle/><ExternalShareButton /></div>)}<div className="px-2 pb-2"><FeedCommentSectionfeedId={feed_unique}image={image}addUrl={comment_add_url}updateTotalComments={(total) => setTotalComments(total)}currentComments={comments}isShow={showComments}/></div></div></>)}const Content = ({description,image,imagePreview,video,document,sharedItem,type,voteUrl,}) => {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 (<>{isReadMoreActive ? fullText : shortenedText}<span className="cursor-pointer" onClick={readMoreHandler}>{isReadMoreActive ? labels.read_less : labels.read_more}</span></>)}return <p>{fullText}</p>}return (<>{type !== 'fast-survey' ? (htmlParsedText(description)) : (<SurveyFormactive={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} target="_blank" rel="noreferrer">{labels.download}</a>)}{sharedItem.name && (<div className="py-3 px-md-3"><FeedisShare={true}owner_name={sharedItem.name}owner_image={sharedItem.image}owner_time_elapse={sharedItem.time_elapse}owner_description={sharedItem.description}owner_file_video={sharedItem.file_video}owner_file_image_preview={sharedItem.file_image_preview}owner_file_image={sharedItem.file_image}owner_file_document={sharedItem.file_document}owner_url={sharedItem.shared_url}/></div>)}</>)}const Header = ({image = '',name = '',timeElapsed = '',deleteUrl = '',viewUrl = '',feedUnique = '',}) => {const [showConfirmModal, setShowConfirmModal] = useState(false)const [displayOption, setDisplayOption] = useState(false)const deleteButton = useRef()const labels = useSelector(({ intl }) => intl.labels)const dispatch = useDispatch()const handleShowConfirmModal = () => setShowConfirmModal(!showConfirmModal)const deleteFeedHandler = () => {axios.post(deleteUrl).then((res) => {const { data } = resif (!data.success) {dispatch(addNotification({ style: 'danger', msg: data.data }))return}dispatch(addNotification({ style: 'success', msg: data.data }))handleShowConfirmModal()dispatch(deleteFeed(feedUnique))})}useEffect(() => {const handleClickOutside = (event) => {if (deleteButton.current &&!deleteButton.current.contains(event.target)) {setDisplayOption(false)}}document.addEventListener('mousedown', handleClickOutside)return () => {document.removeEventListener('mousedown', handleClickOutside)}}, [deleteButton])return (<div className="feed__header"><div className="d-inline-flex" style={{ gap: '.5rem' }}><Avatar imageUrl={image} name={name} size="xl" /><div className="feed__info"><a href={viewUrl}><h2>{name}</h2></a><div className="time__elapse"><p>{timeElapsed}</p><AccessTimeIcon className="time__elapse-icon" /></div></div></div>{deleteUrl && (<div className="cursor-pointer d-flex align-items-center position-relative"><imgsrc="/images/icons/options.png"className="cursor-pointer img-icon options"onClick={() => setDisplayOption(!displayOption)}/><div className={`feed-options ${displayOption ? 'active' : ''}`}><ul><li><buttonclassName="option-btn"onClick={handleShowConfirmModal}ref={deleteButton}><i className="fa fa-trash-o mr-1" />{labels.delete}</button></li></ul></div><ConfirmModalshow={showConfirmModal}onClose={() => handleShowConfirmModal(false)}onAccept={deleteFeedHandler}acceptLabel={labels.accept}/></div>)}</div>)}Feed.Content = ContentFeed.Header = Headerconst mapDispatchToProps = {addNotification: (notification) => addNotification(notification),openShareModal: (postUrl, modalType, feedType) =>openShareModal(postUrl, modalType, feedType),}export default connect(null, mapDispatchToProps)(Feed)