103 lines
2.6 KiB
TypeScript
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>
|
|
);
|
|
};
|