oxen-website/components/cards/ArticleCard.tsx

91 lines
2.4 KiB
TypeScript
Raw Normal View History

2021-01-22 03:43:42 +01:00
import classNames from 'classnames';
2021-02-08 07:37:50 +01:00
import Link from 'next/link';
import { useRouter } from 'next/router';
import React from 'react';
2021-01-22 03:43:42 +01:00
import { useMeasure } from 'react-use';
2021-02-04 06:42:15 +01:00
import { IPost } from '../../types/cms';
2021-01-22 03:43:42 +01:00
import { generateURL } from '../../utils/routing';
2021-02-08 07:37:50 +01:00
import { TagRow } from '../TagRow';
2021-01-22 03:43:42 +01:00
2021-01-29 03:50:49 +01:00
export function ArticleCard(props: IPost): JSX.Element {
2021-01-22 03:43:42 +01:00
const {
title,
2021-02-08 07:37:50 +01:00
description,
2021-01-29 03:50:49 +01:00
subtitle,
2021-02-08 07:37:50 +01:00
featureImage,
publishedDate,
author,
slug,
2021-01-22 03:43:42 +01:00
} = props;
2021-02-08 07:37:50 +01:00
const router = useRouter();
2021-01-22 03:43:42 +01:00
const [ref, { width }] = useMeasure();
const isSmall = width < 130;
2021-02-08 07:37:50 +01:00
const { href, as } = generateURL(slug);
2021-01-22 03:43:42 +01:00
2021-02-23 07:48:23 +01:00
// Order tags such that the search tag appears first
2021-02-23 08:33:54 +01:00
const searchTag = String(router.query?.tag);
const tags = props.tags?.find(t => t === searchTag)
2021-02-23 07:48:23 +01:00
? [searchTag, ...props.tags.filter(t => t !== searchTag)]
: props.tags;
2021-01-22 03:43:42 +01:00
return (
<div
ref={ref}
2021-02-23 08:20:00 +01:00
style={{ wordBreak: 'break-word' }}
2021-01-22 03:43:42 +01:00
className={classNames(
2021-02-08 07:37:50 +01:00
'overflow-hidden w-full bg-opacity-75',
2021-01-22 03:43:42 +01:00
isSmall ? 'pb-3' : 'pb-1',
)}
>
<div
2021-02-08 07:37:50 +01:00
onClick={() => router.push(href, as)}
className="relative aspect-w-16 aspect-h-9"
2021-01-22 03:43:42 +01:00
>
2021-02-11 06:26:56 +01:00
{featureImage?.imageUrl && (
2021-02-08 07:37:50 +01:00
<img
className="object-cover cursor-pointer"
2021-02-18 05:44:53 +01:00
src={`${featureImage?.imageUrl}?w=300`}
alt={featureImage?.description ?? title}
2021-02-08 07:37:50 +01:00
/>
2021-01-22 03:43:42 +01:00
)}
</div>
2021-02-08 07:37:50 +01:00
<div>
2021-01-22 03:43:42 +01:00
<div className={isSmall ? 'py-1' : 'py-3'}>
2021-02-08 07:37:50 +01:00
<Link href={href} as={as}>
<a>
<p
className={classNames(
isSmall ? 'text-base' : 'text-lg',
'font-sans overflow-hidden cursor-pointer mb-3 hover:underline leading-none text-primary',
)}
>
{title}
</p>
</a>
</Link>
2021-02-04 01:57:27 +01:00
<p
style={{
2021-02-08 07:37:50 +01:00
height: '4em',
2021-02-04 01:57:27 +01:00
paddingBottom: '2.1em',
}}
2021-02-08 07:37:50 +01:00
className="mt-1 overflow-hidden text-xs leading-none text-gray-800"
2021-02-04 01:57:27 +01:00
>
2021-02-08 07:37:50 +01:00
{description?.substr(0, 250) ?? subtitle}...
2021-02-04 01:57:27 +01:00
</p>
2021-01-22 03:43:42 +01:00
2021-02-08 07:37:50 +01:00
<div className="flex flex-col space-y-1">
<p className="mt-2 font-sans text-xs text-gray-800">
2021-02-11 06:26:56 +01:00
{publishedDate} {author?.name}
2021-02-08 07:37:50 +01:00
</p>
2021-02-12 01:06:54 +01:00
<TagRow tags={tags} limit={3} />
2021-02-08 07:37:50 +01:00
</div>
2021-01-22 03:43:42 +01:00
</div>
</div>
</div>
);
}