Files
DefectingCat.github.io/components/PostCard.tsx
DefectingCat c8505eba02 Update types
2021-12-20 16:10:39 +08:00

123 lines
3.4 KiB
TypeScript

import { FC, MouseEventHandler, useEffect } from 'react';
import { Box, Flex, Heading, Text, Link } from '@chakra-ui/react';
import { AllPostsData } from 'lib/posts';
import { Icon, Image } from '@chakra-ui/react';
import { FiCalendar, FiTag } from 'react-icons/fi';
import { useAppDispatch } from 'app/hooks';
import { setFromPath } from 'features/router/routerSlice';
import { useRouter } from 'next/router';
import useGetColors from 'lib/hooks/useGetColors';
import useLazyLoad from 'lib/hooks/useLazyload';
import dynamic from 'next/dynamic';
import useIntersection from 'lib/hooks/useIntersection';
const Date = dynamic(() => import('./DateFormater'));
interface Props {
post: AllPostsData;
}
const PostCard: FC<Props> = ({ post }) => {
const dispatch = useAppDispatch();
const router = useRouter();
const { initSrc, targetRef } = useLazyLoad(post.index_img);
const { targetRef: cardRef, inView } = useIntersection();
const { boxBg, textColor, headingColor } = useGetColors();
const goToPost: MouseEventHandler<HTMLAnchorElement> = (e) => {
e.preventDefault();
dispatch(setFromPath(location.pathname));
router.push(`/p/${post.url}`);
};
useEffect(() => {
inView && router.prefetch(`/p/${post.url}`);
}, [post.url, inView, router]);
return (
<>
<Box
as="article"
borderRadius="10px"
bg={boxBg}
overflow="hidden"
boxShadow="card"
mb="2.5rem"
ref={cardRef}
>
{post.index_img && (
<Link
href={`/p/${post.url}`}
onClick={goToPost}
_focus={{ boxShadow: 'unset' }}
>
<Image
ref={targetRef}
src={initSrc}
maxH="18rem"
w="100%"
fit="cover"
alt="Post image"
/>
</Link>
)}
<Box p="1.75rem" key={post.url}>
{/* Title */}
<Link
href={`/p/${post.url}`}
onClick={goToPost}
_focus={{ boxShadow: 'unset' }}
>
<Heading color={headingColor} mb="0.6rem" fontSize="22">
{post.title}
</Heading>
</Link>
{/* Description */}
<Text mb="0.6rem" color={textColor}>
{post.desc}
</Text>
<Flex alignItems="center" fontSize="13" color="gray.500">
{/* Date */}
<Flex alignItems="center" mr="1rem">
<Icon as={FiCalendar} mr="0.5rem" />
<Date dateString={post.date} />
</Flex>
{/* Tags */}
<Flex alignItems="center" mr="1rem">
{Array.isArray(post.tags) ? (
// Mutil tags
<Flex alignItems="center" mr="1rem">
<Icon as={FiTag} mr="0.5rem" />
{post.tags.map((item) => {
return (
<Text key={item} mr="0.5rem">
{item}
</Text>
);
})}
</Flex>
) : (
// Signal tags
post.tags && (
<Flex alignItems="center" mr="1rem">
<Icon as={FiTag} mr="0.5rem" />
<Text>{post.tags}</Text>
</Flex>
)
)}
</Flex>
</Flex>
</Box>
</Box>
</>
);
};
export default PostCard;