Skip to content

Commit

Permalink
Merge pull request #7 from mrwhittleman/gallery
Browse files Browse the repository at this point in the history
Gallery upgrades
  • Loading branch information
mulekatz authored Apr 5, 2024
2 parents f9744e5 + 014a3bb commit c51a9d7
Show file tree
Hide file tree
Showing 10 changed files with 392 additions and 215 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"@adraffy/ens-normalize": "^1.10.1",
"@ensdomains/ensjs": "^3.4.4",
"@fortawesome/fontawesome-svg-core": "^6.5.1",
"@fortawesome/free-regular-svg-icons": "^6.5.2",
"@fortawesome/free-solid-svg-icons": "^6.5.1",
"@fortawesome/react-fontawesome": "^0.2.0",
"@heroicons/react": "^2.1.1",
Expand Down
8 changes: 5 additions & 3 deletions src/components/CopyClipboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,14 @@ const CopyClipboard = ({ copyData }: { copyData: string }) => {
try {
await navigator.clipboard.writeText(copyData);
toast({
title: "Copied to clipboard.",
className: "bg-tertiary-foreground border",
title: "Success",
description: "Transaction ID copied to clipboard.",
variant: "success",
});
} catch (err) {
toast({
title: "Failed to copy to clipboard.",
title: "Error",
description: "Something went wrong.",
variant: "destructive",
});
}
Expand Down
78 changes: 50 additions & 28 deletions src/components/GalleryView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {
PaginationNext,
PaginationPrevious,
} from "@/components/ui/pagination";
import SlayerCardGallery from "./SlayerCards";
import SlayerCardComponent from "./SlayerCards";
import { NftListType } from "@/types/types";
import Spinner from "./Spinner";

Expand All @@ -39,12 +39,12 @@ const GalleryView = () => {
const location = useLocation();
const [nfts, setNfts] = useState<NftListType[]>([]);
const [cache, setCache] = useState<Record<number, CacheEntry>>({});
/* const [cursor, setCursor] = useState(""); */
const [pageIndex, setPageIndex] = useState(1);
const [pageIndex, setPageIndex] = useState<number>(1);
const [loading, setLoading] = useState(false);
const [errorMessage, setErrorMessage] = useState("");

// API URL for fetching NFTs
/* const apiUrl = "https://2d6aa0e1.slayersguild.pages.dev/api/nfts"; */
const apiUrl = "https://slayersguild-b60.pages.dev/api/nfts";

// Number of items to display depeding on device width
Expand All @@ -56,7 +56,7 @@ const GalleryView = () => {
} else if (window.innerWidth < 768) {
return 15;
} else if (window.innerWidth < 1920) {
return 20;
return 24;
} else if (window.innerWidth < 2560) {
return 32;
} else {
Expand All @@ -71,7 +71,7 @@ const GalleryView = () => {

// Fetch NFTs from the NFT-List API
const fetchNfts = useCallback(
async (pageIndex: number, direction?: string) => {
async (newPageIndex: number, direction?: string) => {
setLoading(true);
setErrorMessage("");

Expand All @@ -86,13 +86,16 @@ const GalleryView = () => {
queryParams.set("cursor", cursorRef.current);
break;
case direction === "prev":
if (pageIndex === 1) {
if (newPageIndex === 1) {
queryParams.delete("cursor");
} else {
queryParams.set("cursor", ((pageIndex - 1) * PER_PAGE).toString());
queryParams.set(
"cursor",
((newPageIndex - 1) * PER_PAGE).toString()
);
}
break;
case pageIndex === lastPage:
case newPageIndex === lastPage:
queryParams.set(
"cursor",
(TOTAL_ITEMS - (TOTAL_ITEMS % PER_PAGE)).toString()
Expand All @@ -109,7 +112,7 @@ const GalleryView = () => {
const newQueryParams = "?" + queryParams.toString();
navigate(currentPath + newQueryParams);

const cacheEntry = cache[pageIndex];
const cacheEntry = cache[newPageIndex];
const isCacheValid =
cacheEntry && Date.now() - cacheEntry.timestamp < CACHE_EXPIRY;

Expand All @@ -118,41 +121,54 @@ const GalleryView = () => {
cursorRef.current = cacheEntry.cursor;
setPageIndex(cacheEntry.pageIndex);
setLoading(false);
console.log("triggerCache");
} else {
// Fetch the NFTs from the API
try {
const response = await fetch(apiUrl + newQueryParams);
const data = await response.json();
setNfts(data.page);
const newCursor = data.cursor;
const newPageIndex = Math.floor(Number(newCursor) / PER_PAGE);
cursorRef.current = newCursor;
setPageIndex(newPageIndex);
// Update the cache entry to include cursor and pageIndex
setCache((prevCache) => ({
...prevCache,
[pageIndex]: {
[newPageIndex]: {
data: data.page,
cursor: newCursor,
pageIndex: newPageIndex,
timestamp: Date.now(),
},
}));
/* TO REMOVE!! */
/* console.log("triggered"); */
} catch (err: any) {
setErrorMessage(err.message ?? "An error occurred");
} finally {
setLoading(false);
console.log("triggeredAPI");
}
}
},
[cursorRef, cache]
[cursorRef, cache, PER_PAGE, navigate]
);

// Initial fetch
useEffect(() => {
fetchNfts(pageIndex);
// Check if the query params contain a cursor and thus are page 1 or not (for initial fetch) if not, fetch the NFTs for that page and the right pageIndex
const queryParams = new URLSearchParams(location.search);
const cursor = queryParams.get("cursor");
let newPageIndex;

if (cursor) {
newPageIndex = Math.floor(Number(cursor) / PER_PAGE + 1);
} else {
newPageIndex = 1;
}

// Restore the previous pageIndex and cursor values
setPageIndex(newPageIndex);
cursorRef.current = cursor ?? "";
fetchNfts(newPageIndex);
}, []);

// Display an error toast if there is an error message
Expand Down Expand Up @@ -182,19 +198,25 @@ const GalleryView = () => {
return (
<section className="relative flex flex-wrap justify-center items-center size-full gap-4 2k:gap-8">
{!loading ? (
<div className="grid w-full grid-cols-1 xs:grid-cols-2 sm:grid-cols-3 md:grid-cols-4 1k:grid-cols-8 2k:grid-cols-10 gap-4 2k:gap-8">
<div className="grid w-full grid-cols-1 xs:grid-cols-2 sm:grid-cols-3 md:grid-cols-4 xl:grid-cols-6 1k:grid-cols-8 2k:grid-cols-10 gap-4 2k:gap-8">
{/* Mapping through data and render the Detailed Cards */}
{nfts.map((slayer: NftListType) => {
{nfts.map((slayer: NftListType, index) => {
const props = {
slayer,
className: "cursor-pointer outline-4 hover:outline",
history: {
limit: PER_PAGE.toString(),
cursor: cursorRef.current,
getCursor: () => cursorRef.current,
},
type: "gallery",
};

return <SlayerCardGallery key={slayer.tokenId} {...props} />;
return (
<SlayerCardComponent
key={`${slayer.tokenId}-gallery-${index}`}
{...props}
/>
);
})}
</div>
) : (
Expand All @@ -203,22 +225,22 @@ const GalleryView = () => {
</div>
)}

<Pagination className="sticky bottom-8 py-2 px-8 flex w-full max-w-2xl rounded-lg bg-tertiary/85 backdrop-blur-sm">
<Pagination className="sticky bottom-0 md:bottom-8 py-2 px-4 flex w-screen md:max-w-2xl md:rounded-lg bg-tertiary-foreground md:bg-tertiary-foreground/85 backdrop-blur-sm select-none left-0 right-0 ml-[-4rem] mr-[-4rem]">
<PaginationContent>
<PaginationItem>
{pageIndex > 1 ? (
<PaginationPrevious
onClick={handlePreviousClick}
className="cursor-pointer hover:bg-primary/15 transition-all"
className="cursor-pointer h-16 md:h-12 lg:h-10 hover:bg-primary/15 transition-all"
/>
) : (
<PaginationPrevious className="opacity-20 pointer-events-none transition-all" />
<PaginationPrevious className="opacity-20 h-16 md:h-12 lg:h-10 pointer-events-none transition-all" />
)}
</PaginationItem>

<PaginationItem>
<PaginationLink
className="cursor-pointer hover:bg-primary/15 transition-all focus-visible:bg-accent/65"
className="cursor-pointer h-16 md:h-12 lg:h-10 hover:bg-primary/15 transition-all focus-visible:bg-accent/65"
onClick={handleFirstPageClick}
isActive={pageIndex === 1}
>
Expand All @@ -230,17 +252,17 @@ const GalleryView = () => {
<PaginationItem className="mx-6">
<PaginationLink
isActive
className="hover:bg-primary/15 transition-all"
className="hover:bg-primary/15 h-16 md:h-12 lg:h-10 transition-all"
>
{pageIndex}
</PaginationLink>
</PaginationItem>
) : (
<PaginationEllipsis className="mx-6" />
<PaginationEllipsis className="mx-6 h-16 md:h-12 lg:h-10" />
)}
<PaginationItem>
<PaginationLink
className="cursor-pointer hover:bg-primary/15 transition-all"
className="cursor-pointer h-16 md:h-12 lg:h-10 hover:bg-primary/15 transition-all"
onClick={() =>
fetchNfts(pageIndex === lastPage ? pageIndex : lastPage)
}
Expand All @@ -253,10 +275,10 @@ const GalleryView = () => {
{pageIndex < lastPage ? (
<PaginationNext
onClick={handleNextClick}
className="cursor-pointer hover:bg-primary/15 transition-all"
className="cursor-pointer h-16 md:h-12 lg:h-10 hover:bg-primary/15 transition-all"
/>
) : (
<PaginationNext className="opacity-20 pointer-events-none transition-all" />
<PaginationNext className="opacity-20 pointer-events-none h-16 md:h-12 lg:h-10 transition-all" />
)}
</PaginationItem>
</PaginationContent>
Expand Down
30 changes: 30 additions & 0 deletions src/components/ImageViewer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import React from "react";
import {
Dialog,
DialogContent,
DialogDescription,
DialogHeader,
DialogTitle,
DialogTrigger,
} from "@/components/ui/dialog";

const ImageViewer = ({
children,
imageUrl,
altName,
}: {
children: React.ReactNode;
imageUrl: string;
altName: string;
}) => {
return (
<Dialog>
<DialogTrigger asChild>{children}</DialogTrigger>
<DialogContent className="flex p-0 w-full min-w-fit">
<img className="rounded-lg" src={imageUrl} alt={altName} width={1024} />
</DialogContent>
</Dialog>
);
};

export default ImageViewer;
2 changes: 1 addition & 1 deletion src/components/Navigation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export default function Navigation() {
src={Logo}
alt="Slayers Guild Logo"
height={64}
className="h-16"
className="h-12 sm:h-16"
/>
<div className="hidden sm:flex flex-col self-end">
<h2 className="text-sm font-thin tracking-widest">Vechain</h2>
Expand Down
Loading

0 comments on commit c51a9d7

Please sign in to comment.