Skip to content

Commit

Permalink
feat: nft assets main page and nft apis
Browse files Browse the repository at this point in the history
  • Loading branch information
denniswon committed Mar 5, 2024
1 parent b9ba8ba commit a5efe44
Show file tree
Hide file tree
Showing 14 changed files with 156 additions and 284 deletions.
2 changes: 1 addition & 1 deletion CODEOWNERS
Original file line number Diff line number Diff line change
@@ -1 +1 @@
* @dphilipson @avasisht23 @denniswon
* @dphilipson @denniswon @alex-miao
36 changes: 36 additions & 0 deletions app/[address]/nfts/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { Nfts, Page } from '@/components/nfts';
import { getAlchemySettings } from '@/utils/alchemy';
import { PAGE_SIZE } from '@/utils/constants';
import { Alchemy, NftFilters, NftOrdering, OwnedNftsResponse } from 'alchemy-sdk';
import { Address } from 'viem';

const alchemy = new Alchemy(getAlchemySettings());

export default async function Page({
params: { address },
searchParams: { pageKey, pageSize = PAGE_SIZE }
}: {
params: { address: Address };
searchParams: { pageKey?: string; pageSize?: number | undefined };
}) {
const {
ownedNfts: items,
pageKey: nextPageKey,
totalCount
}: OwnedNftsResponse = await alchemy!.nft.getNftsForOwner(address, {
pageKey,
pageSize,
excludeFilters: [NftFilters.SPAM],
orderBy: NftOrdering.TRANSFERTIME
});
const totalNumberOfPages = Math.ceil(totalCount / pageSize);

const page: Page = {
pageSize,
prevPageKey: pageKey,
nextPageKey,
totalNumberOfPages
};

return <Nfts address={address} items={items} page={page} />;
}
42 changes: 42 additions & 0 deletions app/api/[address]/nfts/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { Page } from '@/components/nfts';
import { getAlchemySettings } from '@/utils/alchemy';
import { PAGE_SIZE } from '@/utils/constants';
import { Alchemy, NftFilters, NftOrdering, OwnedNftsResponse } from 'alchemy-sdk';

// Next.js edge runtime
// https://nextjs.org/docs/pages/api-reference/edge
export const runtime = 'edge';
export const preferredRegion = 'iad1';

const alchemy = new Alchemy(getAlchemySettings());

export async function GET(req: Request) {
const { pathname, searchParams } = new URL(req.url);
const address = pathname.split('/')[0];
const pageKey = searchParams.get('pageKey') || undefined;
const _pageSize = searchParams.get('pageSize');
const pageSize = _pageSize != null ? parseInt(_pageSize) : PAGE_SIZE;

const {
ownedNfts: items,
pageKey: nextPageKey,
totalCount
}: OwnedNftsResponse = await alchemy!.nft.getNftsForOwner(address, {
pageKey,
pageSize,
excludeFilters: [NftFilters.SPAM],
orderBy: NftOrdering.TRANSFERTIME
});
const totalNumberOfPages = Math.ceil(totalCount / pageSize);

const page: Page = {
pageSize,
prevPageKey: pageKey,
nextPageKey,
totalNumberOfPages
};

return new Response(JSON.stringify({ address, items, page }), {
headers: { 'Cache-Control': 'max-age=1, stale-while-revalidate=300' }
});
}
70 changes: 0 additions & 70 deletions app/auth/page.tsx

This file was deleted.

6 changes: 3 additions & 3 deletions app/images/page.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Images, TagWithImageCount } from '@/components/images';
import { IMAGES_PER_PAGE_COUNT, IMAGE_SIZE } from '@/utils/constants';
import { IMAGE_SIZE, PAGE_SIZE } from '@/utils/constants';
import { getXataClient } from '@/utils/xata';
import { compact, pick } from 'lodash';

Expand All @@ -21,7 +21,7 @@ export default async function Page({ searchParams }: { searchParams: { page: str

// get a paginated list of images, sorted by date
const imagesPagePromise = xata.db.image.sort('xata.createdAt', 'desc').getPaginated({
pagination: { size: IMAGES_PER_PAGE_COUNT, offset: IMAGES_PER_PAGE_COUNT * pageNumber - IMAGES_PER_PAGE_COUNT }
pagination: { size: PAGE_SIZE, offset: PAGE_SIZE * pageNumber - PAGE_SIZE }
});

const imageCountPromise = getImageCount();
Expand All @@ -46,7 +46,7 @@ export default async function Page({ searchParams }: { searchParams: { page: str
const [imagesPage, imageCount, topTags] = await Promise.all([imagesPagePromise, imageCountPromise, topTagsPromise]);
console.timeEnd('Fetching images');

const totalNumberOfPages = Math.ceil(imageCount / IMAGES_PER_PAGE_COUNT);
const totalNumberOfPages = Math.ceil(imageCount / PAGE_SIZE);

// This page object is needed for building the buttons in the pagination component
const page = {
Expand Down
File renamed without changes.
77 changes: 0 additions & 77 deletions app/nfts/page.tsx

This file was deleted.

6 changes: 3 additions & 3 deletions app/tags/[id]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Images, TagWithImageCount } from '@/components/images';
import { IMAGES_PER_PAGE_COUNT, IMAGE_SIZE } from '@/utils/constants';
import { IMAGE_SIZE, PAGE_SIZE } from '@/utils/constants';
import { getXataClient } from '@/utils/xata';
import { compact } from 'lodash';

Expand Down Expand Up @@ -37,7 +37,7 @@ export default async function Page({
})
.select(['*', 'image.image'])
.getPaginated({
pagination: { size: IMAGES_PER_PAGE_COUNT, offset: IMAGES_PER_PAGE_COUNT * pageNumber - IMAGES_PER_PAGE_COUNT }
pagination: { size: PAGE_SIZE, offset: PAGE_SIZE * pageNumber - PAGE_SIZE }
});

// create a thumbnail for each image and apply it to the image object
Expand Down Expand Up @@ -74,7 +74,7 @@ export default async function Page({
imageCount: tagImageCount
} as TagWithImageCount;

const totalNumberOfPages = Math.ceil(tagImageCount / IMAGES_PER_PAGE_COUNT);
const totalNumberOfPages = Math.ceil(tagImageCount / PAGE_SIZE);

const page = {
pageNumber,
Expand Down
15 changes: 15 additions & 0 deletions components/auth/UserCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
Button,
Card,
CardBody,
CardFooter,
CardHeader,
Flex,
HStack,
Expand All @@ -30,6 +31,7 @@ import {
Tooltip
} from '@chakra-ui/react';
import { useMutation, useQuery } from '@tanstack/react-query';
import { useRouter } from 'next/router';
import { useCallback, useState } from 'react';
import { HiOutlineFingerPrint, HiOutlineLogout } from 'react-icons/hi';
import { encodeFunctionData } from 'viem';
Expand All @@ -55,6 +57,7 @@ const iframeCss = `
export const UserCard = () => {
const { signer, user, account } = useSignerContext();
const { client } = useAccountContext();
const router = useRouter();

const [hasClosedPrivateKeyModal, setHasClosedPrivateKeyModal] = useState(false);
const closePrivateKeyModal = useCallback(() => setHasClosedPrivateKeyModal(true), []);
Expand Down Expand Up @@ -126,6 +129,11 @@ export const UserCard = () => {
}
});

const goHome = () => {
if (!account) return;
return router.push(`/${account.address}/nfts`);
};

return (
<Card minW="500px">
<CardHeader>
Expand Down Expand Up @@ -196,6 +204,13 @@ export const UserCard = () => {
</Flex>
)}
</CardBody>
<CardFooter>
<Flex>
<Button bg="primary" flex={1} h="40px" flexDirection="row" onClick={goHome} spinnerPlacement="end">
Go Home
</Button>
</Flex>
</CardFooter>
<Modal
isOpen={!!storagePrivateKey && !hasClosedPrivateKeyModal}
closeOnOverlayClick={false}
Expand Down
Loading

0 comments on commit a5efe44

Please sign in to comment.