import React, { useEffect } from "react"; import { useInView } from "react-intersection-observer"; import classNames from "classnames"; import { format } from "date-fns"; import Chip from "components/Chip"; import { DropdownMenu, DropdownMenuItem } from "components/dropdown-menu"; import Thumbs from "components/Thumbs"; const Post = ({ className, datetime, author, type, ranking, content, modified, seen, archived, state, dimIfArchived = true, canThumb, canRunActions, onLike, onDislike, onHide, onBanUser, onAnnounceProcedureProposal, onAcceptProcedureProposal, onRejectProcedureProposal, onRejectProcedureProposalByChairman, onSeen, }) => { const { ref, inView } = useInView({ threshold: 0.9, trackVisibility: true, delay: 1500, skip: seen, triggerOnce: true, }); useEffect(() => { if (!seen && inView && onSeen) { onSeen(); } }); const wrapperClassName = classNames( "flex items-start p-4 lg:p-2 lg:py-3 lg:-mx-2 transition duration-500", { "bg-yellow-100 bg-opacity-50": !seen, "opacity-25 hover:opacity-100": dimIfArchived && !!archived, }, className ); const labels = []; if (type === "post") { labels.push( <Chip key="type__post" condensed color="grey-125" className="text-grey-300" > Příspěvek </Chip> ); } if (type === "procedure-proposal") { labels.push( <Chip key="type__procedure-proposal" condensed color="cyan-200"> Návrh postupu </Chip> ); labels.push( { pending: ( <Chip key="state__pending" condensed color="grey-500"> Čeká na zpracování </Chip> ), announced: ( <Chip key="state__announced" condensed color="blue-300"> Vyhlášený </Chip> ), accepted: ( <Chip key="state__accepted" condensed color="green-400"> Schválený </Chip> ), rejected: ( <Chip key="state__rejected" condensed color="red-600"> Zamítnutý </Chip> ), "rejected-by-chairman": ( <Chip key="state__rejected-by-chairmen" condensed color="red-600"> Zamítnutý předsedajícím </Chip> ), }[state] ); } if (archived) { labels.push( <Chip key="isArchived" condensed color="grey-125" className="text-grey-300" > Archivovaný </Chip> ); } const showAnnounceAction = type === "procedure-proposal" && state === "pending"; const showAcceptAction = type === "procedure-proposal" && state === "announced"; const showRejectAction = type === "procedure-proposal" && state === "announced"; const showRejectByChairmanAction = type === "procedure-proposal" && ["announced", "pending"].includes(state); const showBanAction = true; const showHideAction = !archived; return ( <div className={wrapperClassName} ref={ref}> <img src={`https://a.pirati.cz/piratar/${author.username}.jpg`} className="w-8 h-8 lg:w-14 lg:h-14 rounded mr-3 object-cover" alt={author.name} /> <div className="flex-1"> <div className="mb-1"> <div className="flex justify-between items-start xl:items-center"> <div className="flex flex-col xl:flex-row xl:items-center"> <div className="flex flex-col xl:flex-row xl:items-center"> <span className="font-bold">{author.name}</span> <div className="mt-1 xl:mt-0 xl:ml-2 leading-tight"> <span className="text-grey-200 text-sm">{author.group}</span> <span className="text-grey-200 ml-1 text-sm"> @ {format(datetime, "H:mm")} {modified && ( <span className="text-grey-200 text-sm block md:inline md:ml-2 underline"> (upraveno) </span> )} </span> </div> </div> <div className="hidden lg:flex flex-row flex-wrap lg:flex-no-wrap lg:items-center mt-1 xl:mt-0 xl:ml-2 space-x-2"> {labels} </div> </div> <div className="flex items-center space-x-4"> <Thumbs likes={ranking.likes} dislikes={ranking.dislikes} readOnly={!canThumb} onLike={onLike} onDislike={onDislike} myVote={ranking.myVote} /> {canRunActions && ( <DropdownMenu right> {showAnnounceAction && ( <DropdownMenuItem onClick={onAnnounceProcedureProposal} icon="ico--bullhorn" title="Vyhlásit procedurální návrh" /> )} {showAcceptAction && ( <DropdownMenuItem onClick={onAcceptProcedureProposal} icon="ico--thumbs-up" title="Schválit procedurální návrh" /> )} {showRejectAction && ( <DropdownMenuItem onClick={onRejectProcedureProposal} icon="ico--thumbs-down" title="Zamítnout procedurální návrh" /> )} {showRejectByChairmanAction && ( <DropdownMenuItem onClick={onRejectProcedureProposalByChairman} icon="ico--thumbs-down" title="Zamítnout procedurální návrh předsedajícím" /> )} {showBanAction && ( <DropdownMenuItem onClick={onBanUser} icon="ico--lock" title="Zablokovat uživatele" /> )} {showHideAction && ( <DropdownMenuItem onClick={onHide} icon="ico--eye-off" title="Skrýt příspěvek" /> )} </DropdownMenu> )} </div> </div> </div> <div className="flex lg:hidden flex-row flex-wrap my-2 space-x-2"> {labels} </div> <p className="text-sm lg:text-base text-black leading-normal"> {content} </p> </div> </div> ); }; export default Post;