70 lines
1.7 KiB
TypeScript
70 lines
1.7 KiB
TypeScript
import * as React from "react";
|
|
import { useState, useEffect, useRef } from "react";
|
|
import { Loading } from "./Loading";
|
|
import { Card } from "./Card";
|
|
import { useInfiniteScroll } from "./infiniteScroll";
|
|
import {
|
|
CardProps,
|
|
CardRequestProps,
|
|
CardState,
|
|
CardStateHandler
|
|
} from "./types";
|
|
|
|
const PAGE_SIZE = 20;
|
|
|
|
const firstUrl = `https://api.elderscrollslegends.io/v1/cards?pageSize=${PAGE_SIZE}&page=1`;
|
|
|
|
const emptyCards: CardState = {
|
|
cards: [],
|
|
next: firstUrl
|
|
};
|
|
|
|
export const Cards = () => {
|
|
const [cards, setCards]: CardStateHandler = useState(emptyCards);
|
|
const [cardPage, setCardPage]: [string | null, Function] = useState(null);
|
|
const [loading, setLoading]: [boolean, Function] = useState(false);
|
|
|
|
const getNextPage = () => {
|
|
setCardPage(cards.next);
|
|
setLoading(true);
|
|
};
|
|
|
|
let pageBottomRef = useRef(null);
|
|
useInfiniteScroll(pageBottomRef, getNextPage);
|
|
|
|
const fetchMoreCards = async () => {
|
|
if (cards.next === null || cardPage === null) {
|
|
return cards;
|
|
}
|
|
|
|
const request = new Request(cardPage!);
|
|
const response = await fetch(request);
|
|
const data: CardRequestProps = await response.json();
|
|
setCards({
|
|
cards: cards.cards.concat(data.cards),
|
|
next: data._links && data._links.next ? data._links.next : null
|
|
});
|
|
setLoading(false);
|
|
};
|
|
|
|
if (cards.next && cardPage === null) {
|
|
getNextPage();
|
|
}
|
|
|
|
useEffect(() => {
|
|
fetchMoreCards();
|
|
}, [cardPage]);
|
|
|
|
return (
|
|
<div className="container">
|
|
<div className="cardbox">
|
|
{cards.cards.map((card: CardProps, count: number) => (
|
|
<Card card={card} key={count} />
|
|
))}
|
|
</div>
|
|
{loading && <Loading />}
|
|
<div id="page-bottom" ref={pageBottomRef} />
|
|
</div>
|
|
);
|
|
};
|