elder_scrolling/src/cards/Cards.tsx

103 lines
2.6 KiB
TypeScript

import * as React from "react";
import { useState, useEffect, useRef } from "react";
import { Loading } from "./Loading";
import { Card } from "./Card";
import { JustifiedLayout, GridLayout } from "@egjs/react-infinitegrid";
import ReactModal from "react-modal";
import { FullCard, fullcardStyles } from "./FullCard";
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,
maxCards: -1
};
export const Cards = () => {
const [cards, setCards]: CardStateHandler = useState(emptyCards);
const [loading, setLoading]: [boolean, Function] = useState(false);
const [currentCard, setCurrentCard]: [CardProps | null, Function] = useState(
null
);
const loadItems = () => {
if (cards.next === null || cards.cards.length === cards.maxCards) {
return;
}
setLoading(true);
const request = new Request(cards.next);
fetch(request)
.then(response => response.json())
.then((data: CardRequestProps) => {
setCards({
cards: [...cards.cards, ...data.cards],
next: data._links && data._links.next ? data._links.next : null,
maxcards: data._totalCount
});
setLoading(false);
});
};
const loadMoreCards = (options: any) => {
if (options.startLoading !== null) {
options.startLoading();
}
loadItems();
};
const onLayoutComplete = (options: any) => {
!options.isLayout && options.endLoading();
};
const handleCloseCard = () => {
setCurrentCard(null);
};
const handleOpenCard = (id: string) => {
const card = cards.cards.find(card => card.id === id);
if (card) {
setCurrentCard(card);
}
};
return (
<div className="container">
<ReactModal
isOpen={currentCard !== null}
style={fullcardStyles}
contentLabel=""
onRequestClose={handleCloseCard}
>
<FullCard card={currentCard} />
</ReactModal>
<GridLayout
options={{
isConstantSize: true,
isEqualSize: true,
transitionDuration: 0.2
}}
layoutOptions={{
margin: 10
}}
onAppend={loadMoreCards}
onLayoutComplete={onLayoutComplete}
>
{cards.cards.map((card: CardProps, count: number) => (
<Card card={card} key={count} onClick={handleOpenCard} />
))}
</GridLayout>
{loading ? <Loading /> : ""}
</div>
);
};