简体   繁体   English

我想单击框上的任何位置以将我导航到除按钮之外的帖子详细信息页面。 它的按钮应该是它自己的工作

[英]I want to click anywhere on the box to navigate me to the post detail page except the buttons. It's buttons should it's own job

import {
  Box,
  Flex,
  Text,
  Input,
  Image,
  useColorModeValue,
  useClipboard,
  Divider,
  IconButton,
  HStack,
  Menu,
  MenuButton,
  MenuList,
  Portal,
  MenuItem,
  useToast,
  useOutsideClick,
  useDisclosure,
} from "@chakra-ui/react";
import {
  BsThreeDots,
  BsDot,
  BsBookmark,
  BsFlag,
  BsCheckCircle,
} from "react-icons/bs";
import { BsHeart } from "react-icons/bs";
import { AiFillHeart, AiFillMessage } from "react-icons/ai";
import { FaShareSquare } from "react-icons/fa";
import parse from "html-react-parser";
import copyLink from "@/images/copy-link.svg";
import { axiosInstance } from "@/axiosConfig";
import { COLORS } from "../../constants/COLORS";
import dayjs from "dayjs";
import relativeTime from "dayjs/plugin/relativeTime";
import { useDispatch, useSelector } from "react-redux";
import { Link, useNavigate } from "react-router-dom";
import { addNotice, deleteMyPostSlice } from "../../redux/slices/userSlice";
import { FiEdit } from "react-icons/fi";
import { HiOutlineTrash } from "react-icons/hi";
import {
  addComment,
  deletePost,
  publishPost,
  unPublishPost,
} from "../../redux/asyncActions/postAction";
import CustomImage from "../small/CustomImage";
import {
  deletePostSlice,
  removeBookmarkSlice,
} from "../../redux/slices/postSlice";
import {
  EmailShareButton,
  FacebookShareButton,
  TwitterShareButton,
  LinkedinShareButton,
  FacebookIcon,
  TwitterIcon,
  LinkedinIcon,
  EmailIcon,
} from "react-share";
import AddPicker from "../small/AddPicker";
import PostTag from "./PostTag";
import LikedPeople from "../small/LikedPeopleModal";
import { useRef } from "react";
import ReportModal from "../common/ReportModal";

dayjs.extend(relativeTime);
var domain = window.location.host;

const NewsFeedPost = ({ data }) => {
  const [liked, setLiked] = useState(data?.has_liked);
  const [hasFav, setHasFav] = useState(data?.has_favorited);
  const [likedCount, setLikedCount] = useState(data?.likers_count);
  const [commentInput, setCommentInput] = useState("");

  const { isOpen, onOpen, onClose } = useDisclosure();

  const userId = useSelector((state) => state.userReducer?.userInfo?.id);
  const { hasCopied, onCopy } = useClipboard(
    `${domain}/post-detail/${data?.id}`
  );
  const toast = useToast();

  const bg = useColorModeValue("white", COLORS.darkGray);

  const borderColor = useColorModeValue(
    COLORS.lightGrayBorder,
    COLORS.darkGrayBorder
  );
  const navigate = useNavigate();

  const ref = useRef();
  const [isModalOpen, setIsModalOpen] = useState(false);

  useOutsideClick({
    ref: ref,
    handler: () => setIsModalOpen(false),
  });

  const dispatch = useDispatch();
  const likeThisPost = async (post_id) => {
    try {
      const r = await axiosInstance.post(`post/like/${post_id}`);
      setLikedCount(r.data.likers_count);
      setLiked((prev) => !prev);
    } catch (err) {}
  };
  const bookmarkThisPost = async (post_id) => {
    try {
      const r = await axiosInstance.post(`post/favorite/${post_id}`);
      setHasFav(r.data.favorited);
      if (r.data.favorited) {
        dispatch(addNotice("This post has been bookmarked"));
      } else {
        dispatch(addNotice("Bookmark has been removed"));
      }
      dispatch(removeBookmarkSlice(post_id));
    } catch (err) {}
  };

  const deleteThisPost = (id) => {
    dispatch(deletePost(id));
    dispatch(deleteMyPostSlice(id));
  };

  const addMyComment = (e, id) => {
    e.preventDefault();
    let data = {
      post_id: id,
      content: commentInput,
    };
    dispatch(addComment(data));
    navigate(`/post-detail/${id}`, { replace: true });
  };

  const unPublishPosts = (id) => {
    dispatch(unPublishPost(id));
    dispatch(deletePostSlice(id));
  };

  const publishPosts = (id) => {
    dispatch(publishPost(id));
    dispatch(deleteMyPostSlice(id));
  };

  return (
    <Box
      bg={bg}
      mt="1.5rem"
      p="1.5rem"
      pt="0.8rem"
      borderWidth={1}
      borderColor={borderColor}
      style={{ borderRadius: "10px" }}
      onClick={() => navigate(`/post-detail/${data?.id}`)}
    >
      <Flex mb="1.5rem" align="center" direction="row" justify="space-between">
        <Link to={`/post-detail/${data?.id}`}>
          <Text fontWeight="400">{data?.title}</Text>
        </Link>

        <Menu>
          <MenuButton>
            <BsThreeDots />
          </MenuButton>
          <Portal>
            <MenuList w="100px" p="3" bg={bg}>
              {data?.user.id === userId ? (
                <Flex direction={"column"} ml="1rem">
                  <Link to={`/post-edit/${data?.id}`}>
                    <Flex className="menuitems">
                      <FiEdit />
                      <Text ml="4" fontSize="0.8rem">
                        Edit
                      </Text>
                    </Flex>
                  </Link>

                  <Flex
                    className="menuitems"
                    onClick={() => deleteThisPost(data?.id)}
                  >
                    <HiOutlineTrash />
                    <Text ml="4" fontSize="0.8rem">
                      Delete
                    </Text>
                  </Flex>
                  {!data.is_published ? (
                    <Flex
                      className="menuitems"
                      onClick={() => publishPosts(data?.id)}
                    >
                      <BsCheckCircle />
                      <Text ml="4" fontSize="0.8rem">
                        Publish
                      </Text>
                    </Flex>
                  ) : (
                    <Flex
                      className="menuitems"
                      onClick={() => unPublishPosts(data?.id)}
                    >
                      <FiEdit />
                      <Text ml="4" fontSize="0.8rem">
                        Unpublish
                      </Text>
                    </Flex>
                  )}
                  <Flex
                    className="menuitems"
                    onClick={() => bookmarkThisPost(data?.id)}
                  >
                    <BsBookmark color={hasFav ? "lightgreen" : ""} />
                    <Text ml="4" fontSize="0.8rem">
                      {hasFav ? "Remove Bookmark" : "Bookmark"}
                    </Text>
                  </Flex>
                </Flex>
              ) : (
                <Flex direction={"column"} ml="1rem">
                  <Flex
                    className="menuitems"
                    onClick={() => bookmarkThisPost(data?.id)}
                  >
                    <BsBookmark color={hasFav ? "lightgreen" : ""} />
                    <Text ml="4" fontSize="0.8rem">
                      {hasFav ? "Remove Bookmark" : " Bookmark"}
                    </Text>
                  </Flex>
                  <Flex className="menuitems" onClick={onOpen}>
                    <BsFlag />
                    <Text ml="4" fontSize="0.8rem">
                      Report
                    </Text>
                    <ReportModal
                      modalIsOpen={isOpen}
                      closeModal={onClose}
                      type="post"
                      id={data?.id}
                    />
                  </Flex>
                </Flex>
              )}
            </MenuList>
          </Portal>
        </Menu>
      </Flex>
      <Flex direction="row" align="center" justify="space-between">
        <Box>
          <Flex direction="row" align="center">
            <Link to={`/user-profile/${data?.user?.id}`}>
              <CustomImage
                size="50px"
                char={data.user?.firstname.charAt(0)}
                imageUrl={data?.user?.photo}
                alt={`${data.user?.firstname}'s Avatar`}
                role={data?.user?.role}
              />
            </Link>
            <Flex ml="1rem" direction="column">
              <Link to={`/user-profile/${data?.user?.id}`}>
                <Text
                  fontSize={["12px", "13px", "13px", "13px"]}
                  mb="2px"
                  fontWeight="500"
                >
                  {data?.user?.firstname} {data?.user?.lastname}
                </Text>
              </Link>
              <Flex direction="row" align="center">
                <Text
                  style={{ color: "#ABAAAF" }}
                  fontSize={["9px", "9px", "9px", "12px"]}
                >
                  {dayjs(data.created_at).fromNow()}
                </Text>
                <BsDot
                  color="#ABAAAF"
                  fontSize={"20px"}
                  //  fontSize={["14px","14px","15px","24px"]}
                  ml="4px"
                />
                <Flex fontSize="10px" ml="4px">
                  in{" "}
                  <Text
                    ml="1"
                    cursor="pointer"
                    color="#FF8053"
                    onClick={() =>
                      navigate(`/?category_id=${data?.category?.id}`)
                    }
                  >
                    {data?.category?.name}
                  </Text>
                </Flex>
              </Flex>
            </Flex>
          </Flex>
        </Box>
        {data.tags && <PostTag tags={data?.tags} />}
      </Flex>
      <Box className="parseContent" mt="1.5rem" fontSize="12px">
        <Link to={`/post-detail/${data?.id}`}>{parse(data.content_html)}</Link>
      </Box>
      <Divider mt="1rem" mb="0.5rem" />
      <Flex
        direction="row"
        justify={{ base: "start", sm: "space-between" }}
        mt="1rem"
        align="center"
      >
        <Box w={{ base: "50%", sm: "50%", md: "70%", lg: "70%" }}>
          <Box pos="relative">
            <form
              onSubmit={(e) => addMyComment(e, data?.id)}
              style={{ position: "relative" }}
            >
              <Input
                value={commentInput}
                onChange={(e) => setCommentInput(e.target.value)}
                fontSize={["9px", "10px", "12px", "12px"]}
                placeholder="Add Response..."
                // zIndex={0}
              />
              <AddPicker setInput={setCommentInput} />
            </form>
          </Box>
        </Box>
        <Box width={{ base: "45%", sm: "45%", lg: "40%" }} pl="1.5rem">
          <Flex direction="row" justify="space-around" position="relative">
            <Flex direction="row" align="center">
              <IconButton
                onClick={() => likeThisPost(data.id)}
                _hover={{ background: "transparent" }}
                _active={{ background: "transparent" }}
                _focus={{ boxShadow: "none" }}
                bg="transparent"
                color="#C5D0E6"
                children={
                  liked ? (
                    <AiFillHeart fontSize={"1.7rem"} color={COLORS.hasLiked} />
                  ) : (
                    <BsHeart fontSize={"1.4rem"} />
                  )
                }
              />
              <Text
                color="#ABAAAF"
                fontSize="14px"
                onClick={() => setIsModalOpen(true)}
                cursor="pointer"
              >
                {likedCount}
              </Text>
              {isModalOpen && (
                <Box ref={ref}>
                  <LikedPeople />
                </Box>
              )}
            </Flex>
            <Link to={`/post-detail/${data?.id}`}>
              <DataIconCount icon="AiFillMessage" count={data.comments_count} />
            </Link>
            <Menu>
              <MenuButton
                bg="transparent"
                color="#C5D0E6"
                _hover={{ background: "transparent", color: "#7B6CB4" }}
                _active={{ background: "transparent" }}
                _focus={{ boxShadow: "none" }}
                className="newsfeed-iconbtn"
                as={IconButton}
                aria-label="Options"
                icon={<FaShareSquare fontSize={"1.5rem"} />}
              />
              <MenuList bg={bg}>
                <MenuItem fontSize="12px">
                  <HStack align="center" gap="4px">
                    <FacebookShareButton
                      url={`${domain}/post-detail/${data?.id}`}
                    >
                      <Flex>
                        <FacebookIcon size={22} />
                        <Text ml="3">Facebook</Text>{" "}
                      </Flex>
                    </FacebookShareButton>
                  </HStack>
                </MenuItem>
                <MenuItem fontSize="12px">
                  <TwitterShareButton url={`${domain}/post-detail/${data?.id}`}>
                    <Flex>
                      <TwitterIcon size={22} />
                      <Text ml="3">Twitter</Text>{" "}
                    </Flex>
                  </TwitterShareButton>
                </MenuItem>
                <MenuItem fontSize="12px">
                  <LinkedinShareButton
                    url={`${domain}/post-detail/${data?.id}`}
                  >
                    <Flex>
                      <LinkedinIcon size={22} />
                      <Text ml="3">LinkedIn</Text>{" "}
                    </Flex>
                  </LinkedinShareButton>
                </MenuItem>
                <MenuItem fontSize="12px">
                  <EmailShareButton url={`${domain}/post-detail/${data?.id}`}>
                    <Flex>
                      <EmailIcon size={22} />
                      <Text ml="3">Mail</Text>
                    </Flex>
                  </EmailShareButton>
                </MenuItem>
                <MenuItem fontSize="12px">
                  <HStack
                    onClick={() => {
                      onCopy();
                      toast({
                        description: "Copied Post Link",
                        status: "success",
                        position: "top-right",
                      });
                    }}
                    align="center"
                    gap="4px"
                  >
                    <Image src={copyLink} />
                    <Text>Copy Link</Text>
                  </HStack>
                </MenuItem>
              </MenuList>
            </Menu>
          </Flex>
        </Box>
      </Flex>
    </Box>
  );
};

I在此处输入图像描述

I have a post where there are lots of button.我有一个帖子,里面有很多按钮。 Each button has it's own task.每个按钮都有自己的任务。 Whenever I click on any white space or anywhere except this buttons, I should get navigated to post details page.每当我点击除此按钮之外的任何空白或任何地方时,我都应该导航到发布详细信息页面。 So I have assigned navigate function on the onclick of the parent container that is "Box".因此,我在父容器“Box”的 onclick 上分配了导航 function。 The issue is that since all children are wrapped in box so clicking on those buttons also navigate.问题是,由于所有的孩子都被包裹在盒子里,所以点击这些按钮也会导航。 I want to navigate only on white spaces.我只想在空白处导航。 I wrote a clumsy way of using e.stopPropagation() so buttons click prevent navigate() but still few buttons are navigating.我编写了一种使用 e.stopPropagation() 的笨拙方式,因此按钮单击阻止了 navigate(),但仍然很少有按钮在导航。 Is there any way of navigating only when anywhere except buttons?有没有什么方法可以只在按钮以外的任何地方导航?

In the click event listener, check if the event current target is not a button.在点击事件监听器中,检查事件当前目标是否不是按钮。

if(!evt.currentTarget.matches('button'))

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 我想在输入字段中只接受 1-24 并禁用所有其他按钮。 这怎么可能 - I want to accept only 1-24 in the input field and disable all other buttons. how is it possible 这是我必须通过各种按钮显示信息的代码。 问题是当我单击一个按钮时,其他按钮会显示信息 - Here is code where I have to display information through various buttons. The issue is that when I click one button, the other buttons display info 当我单击特定的“addToBasket”按钮时,我不想更改所有“addToBasket”按钮。 只有点击的按钮应该改变 - I do not want all the "addToBasket" buttons to change when i click on a specefic "addToBasket" button. Only the clicked button should change 使用反应 js_在下一页上没有路由按钮,在按钮点击时导航到全新的页面 - Navigate to totally new page on button click using react js_having no route buttons on next page 想要通过单击按钮导航到第一页 - Want to navigate to first page on a button click 如何在 RTK 查询中的 POST 后导航到更新/详细信息页面 - How to navigate to the update/detail page after a POST in RTK query 每次我选择将卡片重定向到其产品详细信息页面而不是 la - I want to view the latest updated page not the last viewed page each time I select a card redirecting it to it's product detail page instead of the la 如果没有在任何地方记录,我应该如何知道用于 React.js 项目的节点版本? - How should I know the node version to use for a React.js project, if it's not documented anywhere? 我想用原生按钮制作一个圆圈 - I want to make a circle with buttons in react native 如何使用单选按钮在 NextJS 的页面之间导航 - How do I navigate between pages on NextJS using radio buttons
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM