-
Notifications
You must be signed in to change notification settings - Fork 1
Add Read More component to Story pages
shraddha-kesari edited this page Feb 1, 2023
·
1 revision
To implement Read more component, we need to create a js and a css file. At first, we need to fetch the stories from the API and then show them in the front end.
Below is the code snippet for read more component
import { StoryCard } from "@quintype/arrow";
import React, { useEffect, useState } from "react";
import { useDispatch, useSelector } from "react-redux";
import get from "lodash/get";
import "./read-more-stories.m.css";
// Fetching the stories from the API
const getStories = async (limit, offset = 0) => {
const FIELDS =
"id,authors,headline,slug,hero-image-s3-key,hero-image-metadata,published-at,first-published-at,last-published-at,alternative,author-name,author-id,sections,story-template,url,read-time";
const { stories } = await (
await fetch(`/api/v1/stories?fields=${FIELDS}&limit=${limit}&offset=${offset}&sort=latest-published`)
).json();
return stories;
};
// Read more component
const ReadMoreStories = () => {
const [alsoReadStories, setAlsoReadStories] = useState(null);
const [offset, setOffset] = useState(0);
const [checker, setChecker] = useState(4);
const getAlsoReadStories = async () => {
const stories = await getStories(5); // Mention the number of stories to be picked up initially
setAlsoReadStories(stories);
};
useEffect(() => {
getAlsoReadStories();
}, []);
if (!alsoReadStories) {
return null;
}
const config = {
localizationConfig: { showAuthor: false, showTime: false, showReadTime: false }, // Customise your component with this localization config
fallbackImageUrl: fallbackImageUrl, // This is a hard coded url
showSection: false,
};
const dispatch = useDispatch();
const setLoading = (isloading) => {
dispatch(isloading ? { type: "QT-PAGE_LOADING" } : { type: "QT-PAGE_FINISHED_LOADING" });
};
// When clicked on the read more button, it fetches the next 4 stories to show
const fetchStories = async () => {
setLoading(true);
const currentOffset = offset + 4; // Number can be customized
setChecker(checker + 4);
setOffset(currentOffset);
const stories = await getStories(4, currentOffset + 1);
setAlsoReadStories(alsoReadStories.concat(stories));
setLoading(false);
};
return (
<div styleName="wrapper" className="read-more-wrapper">
<div styleName="heading">Related Stories</div>
<div styleName="stories-wrapper">
{alsoReadStories.slice(0, checker).map((story, index) => (
<StoryCard story={story} config={config} aspectRatio={[[16, 9]]} isHorizontalWithImageLast key={index} />
))}
</div>
{alsoReadStories.length > checker && (
<button aria-label="read-more-button" onClick={fetchStories} styleName="read-more-button">
Read More
</button>
)}
</div>
);
};
export default ReadMoreStories;
Import this CSS file to your JS file. CSS styles are mentioned below - replace the variables and add your own styles
.wrapper {
padding-bottom: 3.2rem;
margin-bottom: 2.4rem;
border-bottom: solid 1px #dedede;
@media (min-width: 768px) {
margin-bottom: 3.2rem;
}
}
.heading {
position: relative;
font-family: var(--primary-font);
font-size: 2rem;
font-weight: var(--bold);
margin-bottom: 1.6rem;
&::before {
content: "";
width: 2.4rem;
height: 0.4rem;
background-color: var(--brand-secondary);
position: absolute;
top: 100%;
left: 0;
}
@media (min-width: 768px) {
margin-bottom: 3.2rem;
}
}
.stories-wrapper {
:global {
.arr--story-card {
margin-bottom: 2.4rem;
}
.arr--sub-headline {
display: none;
}
.section-tag {
margin-bottom: 1.2rem;
position: relative;
color: #333333;
text-transform: uppercase;
&::before {
content: "";
width: 1.8rem ;
height: 0.2rem;
background-color: var(--brand-secondary);
position: absolute;
top: 100%;
}
}
.author-name,
time,
.arr--read-time {
color: #636363;
}
.arr-separator {
font-size: 1.4rem !important;
}
h6 {
margin-bottom: 0.8rem;
color: #333333;
}
}
@media (min-width: 768px) {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-gap: 2.4rem;
:global {
.arr--story-card {
margin-bottom: 0;
flex-direction: column;
}
.arr--hero-image {
padding-left: 0;
padding-bottom: 0.8rem;
flex-grow: 0;
}
}
}
}
.read-more-button {
font-family: var(--secondary-font);
font-size: 1.6rem;
font-weight: var(--bold);
color: var(--white);
padding: 0.8rem 2.4rem;
background-color: var(--brand-primary);
border-radius: 3px;
display: block;
margin: 1.6rem auto 0;
border: none;
}
Import this component to your story template file like below -
<ReadMoreStories />