docbrown/app/javascript/readingList/components/ItemListItem.jsx
ludwiczakpawel 88a3b573ea
Page headers unified (#15158)
* fix; remove the bottom 100%

* dashboard

* fixes + magic border-radius

* everything

* fix

* fix

* spec

* split PRs

* Update app/assets/stylesheets/views/listings.scss

Co-authored-by: Ridhwana <Ridhwana.Khan16@gmail.com>

Co-authored-by: Ridhwana <ridhwana.khan16@gmail.com>
2021-10-25 21:41:29 +02:00

88 lines
2.8 KiB
JavaScript

// Item list item
import { h } from 'preact';
import PropTypes from 'prop-types';
export const ItemListItem = ({ item, children }) => {
const adaptedItem = {
path: item.reactable.path,
title: item.reactable.title,
user: item.reactable.user,
publishedDate: item.reactable.readable_publish_date_string,
readingTime: item.reactable.reading_time,
tags: item.reactable.tags,
};
// update readingTime to 1 min if the reading time is less than 1 min
adaptedItem.readingTime = Math.max(1, adaptedItem.readingTime || null);
return (
<article className="flex p-4 m:p-6 pb-0 m:pb-2 pr-2 m:pr-6">
<a
className="crayons-avatar crayons-avatar--l"
href={`/${adaptedItem.user.username}`}
datatestid="item-user"
>
<img
src={adaptedItem.user.profile_image_90}
alt={adaptedItem.user.name}
className="crayons-avatar__image"
/>
</a>
<div className="flex-1 pl-2 m:pl-4">
<a href={adaptedItem.path} class="flex crayons-link">
<h2
className="fs-base lh-tight m:fs-l fw-bold break-word"
// eslint-disable-next-line react/no-danger
dangerouslySetInnerHTML={{ __html: filterXSS(adaptedItem.title) }}
/>
</a>
<p className="fs-s">
<a
href={`/${adaptedItem.user.username}`}
className="crayons-link fw-medium"
>
{adaptedItem.user.name}
</a>
<span class="color-base-30"> </span>
<span className="color-base-60">
{adaptedItem.publishedDate}
<span class="color-base-30"> </span>
{`${adaptedItem.readingTime} min read`}
</span>
{adaptedItem.tags.length > 0 ? (
<span datatestid="item-tags">
<span class="color-base-30"> </span>
{adaptedItem.tags.map((tag) => (
<a className="crayons-tag" key={tag} href={`/t/${tag.name}`}>
{`#${tag.name}`}
</a>
))}
</span>
) : (
''
)}
</p>
</div>
<div className="m:self-center">{children}</div>
</article>
);
};
const readingListItemPropTypes = PropTypes.shape({
reactable: {
path: PropTypes.string.isRequired,
title: PropTypes.string.isRequired,
reading_time: PropTypes.number.isRequired,
readable_publish_date_string: PropTypes.string.isRequired,
user: PropTypes.shape({
username: PropTypes.string.isRequired,
profile_image_90: PropTypes.string.isRequired,
name: PropTypes.string.isRequired,
}),
tags: PropTypes.arrayOf(PropTypes.string).isRequired,
},
});
ItemListItem.propTypes = {
item: PropTypes.oneOfType([readingListItemPropTypes]).isRequired,
};