234 lines
8.6 KiB
TypeScript
Executable File
234 lines
8.6 KiB
TypeScript
Executable File
import { useRef } from "react";
|
|
|
|
/* -------------------------------------------------------------------------- */
|
|
/* Skeleton */
|
|
/* -------------------------------------------------------------------------- */
|
|
import "react-loading-skeleton/dist/skeleton.css";
|
|
|
|
/* -------------------------------------------------------------------------- */
|
|
/* Components */
|
|
/* -------------------------------------------------------------------------- */
|
|
import Typography from "../../typography/Typography";
|
|
import SkeletonCard from "../../SkeletonCard";
|
|
import AspectRatio from "../../AspectRatio";
|
|
import Card from "../../Card";
|
|
import Link from "../../typography/Link";
|
|
|
|
/* -------------------------------------------------------------------------- */
|
|
/* Icons */
|
|
/* -------------------------------------------------------------------------- */
|
|
import { ReactComponent as SVGArrowRight } from "assets/svg/arrow-right.svg";
|
|
import { ReactComponent as SVGCaretRight } from "assets/svg/caret-right.svg";
|
|
import { ReactComponent as SVGArrowLeft } from "assets/svg/arrow-left.svg";
|
|
|
|
/* -------------------------------------------------------------------------- */
|
|
/* Swiper */
|
|
/* -------------------------------------------------------------------------- */
|
|
import { Swiper, SwiperSlide } from "swiper/react";
|
|
import SwiperCore, { Navigation } from "swiper";
|
|
import { Pagination } from "swiper";
|
|
import "swiper/css/pagination";
|
|
import "swiper/css/navigation";
|
|
// import "./styles.css";
|
|
import "swiper/css";
|
|
import { useTranslation } from "react-i18next";
|
|
/* -------------------------------------------------------------------------- */
|
|
/* Article mock data */
|
|
/* -------------------------------------------------------------------------- */
|
|
|
|
const articles = [
|
|
{
|
|
CoverImg:
|
|
"https://i.kinja-img.com/gawker-media/image/upload/t_original/ijsi5fzb1nbkbhxa2gc1.png",
|
|
Body: "1 ipsum dolor sit amet consectetur adipisicing elit.Consequuntur maxime, adipisicing elit.sit amet consectetur adipisicing elit.Consequuntur ma",
|
|
Link: "http://pinterest.com",
|
|
},
|
|
{
|
|
CoverImg:
|
|
"https://i.kinja-img.com/gawker-media/image/upload/t_original/ijsi5fzb1nbkbhxa2gc1.png",
|
|
Body: "2 ipsum dolor sit amet consectetur adipisicing elit.Consequuntur maxime, adipisicing elit.",
|
|
Link: "http://pinterest.com",
|
|
},
|
|
{
|
|
CoverImg:
|
|
"https://i.kinja-img.com/gawker-media/image/upload/t_original/ijsi5fzb1nbkbhxa2gc1.png",
|
|
Body: "2 ipsum dolor sit amet consectetur adipisicing elit.Consequuntur maxime, adipisicing elit.",
|
|
Link: "http://pinterest.com",
|
|
},
|
|
{
|
|
CoverImg:
|
|
"https://i.kinja-img.com/gawker-media/image/upload/t_original/ijsi5fzb1nbkbhxa2gc1.png",
|
|
Body: "2 ipsum dolor sit amet consectetur adipisicing elit.Consequuntur maxime, adipisicing elit.",
|
|
Link: "http://pinterest.com",
|
|
},
|
|
{
|
|
CoverImg:
|
|
"https://i.kinja-img.com/gawker-media/image/upload/t_original/ijsi5fzb1nbkbhxa2gc1.png",
|
|
Body: "2 ipsum dolor sit amet consectetur adipisicing elit.Consequuntur maxime, adipisicing elit.",
|
|
Link: "http://pinterest.com",
|
|
},
|
|
{
|
|
CoverImg:
|
|
"https://i.kinja-img.com/gawker-media/image/upload/t_original/ijsi5fzb1nbkbhxa2gc1.png",
|
|
Body: "2 ipsum dolor sit amet consectetur adipisicing elit.Consequuntur maxime, adipisicing elit.",
|
|
Link: "http://pinterest.com",
|
|
},
|
|
{
|
|
CoverImg:
|
|
"https://i.kinja-img.com/gawker-media/image/upload/t_original/ijsi5fzb1nbkbhxa2gc1.png",
|
|
Body: "2 ipsum dolor sit amet consectetur adipisicing elit.Consequuntur maxime, adipisicing elit.",
|
|
Link: "http://pinterest.com",
|
|
},
|
|
];
|
|
/* -------------------------------------------------------------------------- */
|
|
/* How many Skeleton cards should be added to the design */
|
|
/* -------------------------------------------------------------------------- */
|
|
let twoCards: boolean = false;
|
|
let threeCards: boolean = false;
|
|
console.log(`Number of cards ${articles.length}`);
|
|
if (articles.length == 2) {
|
|
twoCards = true;
|
|
} else if (articles.length == 3) {
|
|
threeCards = true;
|
|
}
|
|
|
|
SwiperCore.use([Navigation]);
|
|
|
|
const FeaturedArticlesCards = () => {
|
|
const navigationPrevRef = useRef(null);
|
|
const navigationNextRef = useRef(null);
|
|
const paginationRef = useRef(null);
|
|
const [t, i18next] = useTranslation();
|
|
|
|
return (
|
|
<div className="slider-wrapper articles px-8">
|
|
<div className="flex justify-end gap-2 my-2">
|
|
<div
|
|
className="prev inline-flex justify-center items-center
|
|
w-9 h-9 bg-blue-600 rounded cursor-pointer
|
|
opacity-0 md:opacity-100"
|
|
ref={navigationPrevRef}
|
|
>
|
|
<SVGArrowLeft className="w-6 h-6 fill-white "></SVGArrowLeft>
|
|
</div>
|
|
<div
|
|
className="next inline-flex justify-center items-center
|
|
w-9 h-9 bg-blue-600 rounded cursor-pointer
|
|
opacity-0 md:opacity-100"
|
|
ref={navigationNextRef}
|
|
>
|
|
<SVGArrowRight className="w-6 h-6 fill-white "></SVGArrowRight>
|
|
</div>
|
|
</div>
|
|
|
|
<Swiper
|
|
slidesPerView={1.25}
|
|
slidesPerGroup={1}
|
|
loop={articles.length > 4 ? true : false}
|
|
pagination={{ el: ".pagination", clickable: true }}
|
|
navigation={{
|
|
prevEl: ".prev",
|
|
nextEl: ".next",
|
|
}}
|
|
breakpoints={{
|
|
768: {
|
|
slidesPerView: 2,
|
|
slidesPerGroup: 2,
|
|
},
|
|
1024: {
|
|
slidesPerView: 2,
|
|
slidesPerGroup: 2,
|
|
},
|
|
1280: {
|
|
slidesPerView: 4,
|
|
slidesPerGroup: 4,
|
|
},
|
|
1580: {
|
|
slidesPerView: 4,
|
|
slidesPerGroup: 4,
|
|
},
|
|
}}
|
|
spaceBetween={25}
|
|
loopFillGroupWithBlank={true}
|
|
modules={[Pagination, Navigation]}
|
|
>
|
|
{articles.map((Articale) => (
|
|
<SwiperSlide>
|
|
<Card className="flex-1">
|
|
<Card.CardContent>
|
|
<AspectRatio>
|
|
<AspectRatio.Content>
|
|
<img src={Articale.CoverImg} />
|
|
</AspectRatio.Content>
|
|
</AspectRatio>
|
|
|
|
<Card.Body className="h-14 overflow-hidden">
|
|
{Articale.Body}
|
|
</Card.Body>
|
|
</Card.CardContent>
|
|
|
|
<Card.CardAction href={Articale.Link}>
|
|
<Typography
|
|
className="text-blue-500 font-bold"
|
|
fontWeightVariant="bold"
|
|
>
|
|
{t("mainPage.more")}
|
|
</Typography>
|
|
<SVGCaretRight className="fill-blue-500 w-4 h-4" />
|
|
</Card.CardAction>
|
|
</Card>
|
|
</SwiperSlide>
|
|
))}
|
|
|
|
{twoCards && [
|
|
<SwiperSlide className="hidden xl:block">
|
|
<SwiperSlide>
|
|
<SkeletonCard className="flex-1">
|
|
<SkeletonCard.Content>
|
|
<SkeletonCard.Media />
|
|
<SkeletonCard.Body />
|
|
</SkeletonCard.Content>
|
|
<SkeletonCard.Action />
|
|
</SkeletonCard>
|
|
</SwiperSlide>
|
|
</SwiperSlide>,
|
|
|
|
<SwiperSlide className="hidden xl:block">
|
|
<SwiperSlide>
|
|
<SkeletonCard className="flex-1">
|
|
<SkeletonCard.Content>
|
|
<SkeletonCard.Media />
|
|
<SkeletonCard.Body />
|
|
</SkeletonCard.Content>
|
|
<SkeletonCard.Action />
|
|
</SkeletonCard>
|
|
</SwiperSlide>
|
|
</SwiperSlide>,
|
|
]}
|
|
|
|
{threeCards && [
|
|
<SwiperSlide className="hidden xl:block">
|
|
<SwiperSlide>
|
|
<SkeletonCard className="flex-1">
|
|
<SkeletonCard.Content>
|
|
<SkeletonCard.Media />
|
|
<SkeletonCard.Body />
|
|
</SkeletonCard.Content>
|
|
<SkeletonCard.Action />
|
|
</SkeletonCard>
|
|
</SwiperSlide>
|
|
</SwiperSlide>,
|
|
]}
|
|
</Swiper>
|
|
|
|
<div
|
|
className="pagination my-6 w-full h-2 flex justify-center items-center
|
|
opacity-0 md:opacity-100"
|
|
ref={paginationRef}
|
|
/>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default FeaturedArticlesCards;
|