Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(404 Page, Empty State): Implement 404 page and empty state in marketplace #46

Merged
merged 5 commits into from Apr 18, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Binary file added public/assets/images/404/nft_error_bg.webp
Binary file not shown.
Binary file added public/assets/images/404/nft_error_bg_dark.webp
Binary file not shown.
Binary file not shown.
Binary file not shown.
2 changes: 1 addition & 1 deletion src/layouts/BaseLayout.jsx
Expand Up @@ -35,7 +35,7 @@ const BaseLayout = ({ children, videos }) => {
<Header headerStyle={router.pathname === '/marketplace' ? 'colored' : null} videos={videos} />
<div className='header gap' />
{children}
<Footer />
{router.pathname !== '/404' && <Footer />}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why footer is not there is 404 route?

@flashburst Sharad says it wasn't there in design.

</div>
)
}
Expand Down
35 changes: 35 additions & 0 deletions src/pages/404.jsx
@@ -0,0 +1,35 @@
import Seo from '@/components/Seo/Seo'
import { BaseLayout } from '@/layouts/BaseLayout'
import { resourcesVideoData } from '@/service/video-api'
import Error404 from '@/views/404'

export async function getStaticProps () {
const videoData = await resourcesVideoData()

return {
props: {
videos: videoData
},
revalidate: 60 * 60 // one hour
}
}

const PageNotFound = (props) => {
return (
<>
<Seo
ogURL='/404'
title='Page Not Found / Neptune Mutual'
ogImage='/assets/images/meta/home.png'
ogImageAlt='Neptune Mutual NFT 404'
description='The page you requested either does not exist or has been deleted'
/>

<BaseLayout videos={props.videos}>
<Error404 />
</BaseLayout>
</>
)
}

export default PageNotFound
1 change: 1 addition & 0 deletions src/pages/404.scss
@@ -0,0 +1 @@
@import "../views/404.scss";
28 changes: 20 additions & 8 deletions src/pages/marketplace/[tokenId].jsx
Expand Up @@ -13,15 +13,27 @@ import { resourcesVideoData } from '@/service/video-api'
import { NftDetails } from '@/views/NftDetails'

export async function getStaticProps (context) {
const [nftDetailsResponse, premiumNftsResponse, videoResponse] = await Promise.all([NftApi.getNftDetails(context.params.tokenId), NftApi.premiumNfts(), resourcesVideoData()])
try {
const [nftDetailsResponse, premiumNftsResponse, videoResponse] = await Promise.all([NftApi.getNftDetails(context.params.tokenId), NftApi.premiumNfts(), resourcesVideoData()])

return {
props: {
nftDetails: nftDetailsResponse.data[0],
premiumNfts: premiumNftsResponse.data,
videos: videoResponse
},
revalidate: 60 * 60 // one hour
if (nftDetailsResponse.data.length === 0) {
return {
notFound: true
}
}

return {
props: {
nftDetails: nftDetailsResponse.data[0],
premiumNfts: premiumNftsResponse.data,
videos: videoResponse
},
revalidate: 60 * 60 // one hour
}
} catch (error) {
return {
notFound: true
}
}
}

Expand Down
36 changes: 26 additions & 10 deletions src/pages/marketplace/mint/[tokenId].jsx
Expand Up @@ -13,16 +13,28 @@ import { resourcesVideoData } from '@/service/video-api'
import { MintNft } from '@/views/MintNft'

export async function getStaticProps (context) {
const [nftDetailsResponse, premiumNftsResponse, mintingLevelResponse, videoResponse] = await Promise.all([NftApi.getNftDetails(context.params.tokenId), NftApi.premiumNfts(), NftApi.mintingLevels(), resourcesVideoData()])

return {
props: {
nftDetails: nftDetailsResponse.data[0],
premiumNfts: premiumNftsResponse.data,
mintingLevels: mintingLevelResponse.data,
videos: videoResponse
},
revalidate: 60 * 60 // one hour
try {
const [nftDetailsResponse, premiumNftsResponse, mintingLevelResponse, videoResponse] = await Promise.all([NftApi.getNftDetails(context.params.tokenId), NftApi.premiumNfts(), NftApi.mintingLevels(), resourcesVideoData()])

if (nftDetailsResponse.data.length === 0) {
return {
notFound: true
}
}

return {
props: {
nftDetails: nftDetailsResponse.data[0],
premiumNfts: premiumNftsResponse.data,
mintingLevels: mintingLevelResponse.data,
videos: videoResponse
},
revalidate: 60 * 60 // one hour
}
} catch (error) {
return {
notFound: true
}
}
}

Expand Down Expand Up @@ -53,6 +65,10 @@ const MintNftPage = ({ nftDetails, premiumNfts, mintingLevels, videos }) => {
logWantToMint()
}, [logWantToMint])

// if (router.isFallback || !nftDetails) {
// return console.log('Page Not Found')
// }

if (!nftDetails) {
return <></>
}
Expand Down
28 changes: 20 additions & 8 deletions src/pages/marketplace/page/[page].jsx
Expand Up @@ -5,15 +5,27 @@ import { getSSRData } from '@/utils/ssr'
import { Marketplace } from '@/views/Marketplace'

export async function getServerSideProps (context) {
const { data, marketplaceFilters, pageData } = await getSSRData(context)
const videoData = await resourcesVideoData()
try {
const { data, marketplaceFilters, pageData } = await getSSRData(context)
const videoData = await resourcesVideoData()

return {
props: {
data,
marketplaceFilters,
pageData,
videos: videoData
if (data.length === 0) {
return {
notFound: true
}
}

return {
props: {
data,
marketplaceFilters,
pageData,
videos: videoData
}
}
} catch (error) {
return {
notFound: true
}
}
}
Expand Down
1 change: 1 addition & 0 deletions src/styles/global.scss
Expand Up @@ -144,6 +144,7 @@ button,
//Pages
@import "../pages/index.scss";
@import "../pages/marketplace/index.scss";
@import "../pages/404.scss";
@import "../views/NftDetails.scss";
@import "../views/MintNft.scss";
@import "../views/mint-nft/MintingLevels.scss";
Expand Down
24 changes: 24 additions & 0 deletions src/views/404.jsx
@@ -0,0 +1,24 @@
import { Button } from '@/components/Button/Button'

const Error404 = () => {
return (
<div className='pagenotfound page'>
<div className='inner container'>
<h2>404 Error</h2>
<h1>Page Not Found</h1>
<p>Sorry, the page you are looking for doesn’t exist or has been moved.</p>
</div>
<Button
type='anchor'
variant='primary'
size='xl'
href='/'
iconTrailing='arrow-narrow-right'
>
Take me to homepage
</Button>
</div>
)
}

export default Error404
79 changes: 79 additions & 0 deletions src/views/404.scss
@@ -0,0 +1,79 @@
@use "../design-system/utils";
@use "../design-system/colors";
@use "../design-system/typography/styles";
@use "../design-system/typography/weights";

.pagenotfound.page {
display: flex;
justify-content: center;
align-items: center;
text-align: center;
flex-direction: column;
gap: 32px;
height: calc(100vh - var(--header-height));
position: relative;

&::before {
content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: url("../../public/assets/images/404/nft_error_bg.webp") no-repeat center top;
background-size: 100% 100%;
z-index: -1;
}

.inner.container {
display: flex;
flex-direction: column;
gap: 12px;
padding: 0 16px;

h1 {
@include styles.display-xl;

@media (max-width: 767px) {
@include styles.display-md;
}
}

h2 {
@include styles.text-md;
@include weights.semibold;
color: colors.$primary-600;
}

p {
@include styles.text-xl;
@include weights.regular;

@media (max-width: 767px) {
@include styles.text-lg;
}
}
}

.ui.primary.button {
display: inline-flex;
}
}

.dark .pagenotfound.page {
&::before {
background: url("../../public/assets/images/404/nft_error_bg_dark.webp") no-repeat center top;
background-size: 100% 100%;
mix-blend-mode: overlay;
}

.inner.container {
h2 {
color: colors.$primary-300;
}

p {
color: colors.$gray-25;
}
}
}
6 changes: 3 additions & 3 deletions src/views/MintNft.jsx
Expand Up @@ -67,7 +67,7 @@ const MintNft = ({ nftDetails, premiumNfts, mintingLevels }) => {
<CustomTooltip text={
<div className='progress tooltip'>
<div className='label'>Required:</div>
<div className='value'>${required.toLocaleString('en-US')}</div>
<div className='value'>${required?.toLocaleString('en-US')}</div>
<br />
<div className='label'>Your Policy Purchase:</div>
<div className='value'>${current.toLocaleString('en-US')}</div>
Expand Down Expand Up @@ -138,14 +138,14 @@ const MintNft = ({ nftDetails, premiumNfts, mintingLevels }) => {
<h3>Your Milestones</h3>
srmasharad marked this conversation as resolved.
Show resolved Hide resolved
{buildProgress({
title: 'Policy Purchase',
required: requirements.policyPurchase,
required: requirements?.policyPurchase,
current: currentProgress.totalPolicyPurchased,
percent: policyPurchasePercent,
remaining: policyPurchaseRemaining
})}
{buildProgress({
title: 'Added Liquidity',
required: requirements.liquidity,
required: requirements?.liquidity,
current: currentProgress.totalLiquidityAdded,
percent: liquidityPercent,
remaining: liquidityRemaining
Expand Down
28 changes: 18 additions & 10 deletions src/views/marketplace/MarketplaceSection.jsx
Expand Up @@ -134,17 +134,25 @@ const MarketPlaceSection = ({ data = [], filters = [], pageData }) => {
<NftPlaceholder key={i} />
))}
{(!loading || isNavigating) &&
data.map((nft) => (
<NftCard
key={nft.tokenId}
name={nft.nickname}
nftId={nft.tokenId}
views={nft.views}
count={nft.siblings}
image={`${imageOrigin}/thumbnails/${nft.tokenId}.webp`}
/>
))}
data.map((nft) => (
<NftCard
key={nft.tokenId}
name={nft.nickname}
nftId={nft.tokenId}
views={nft.views}
count={nft.siblings}
image={`${imageOrigin}/thumbnails/${nft.tokenId}.webp`}
/>
))}
</div>

{!loading && !isNavigating && data.length === 0 &&
<div className='noresult found'>
<div className='content'>
<h2>No Results Found</h2>
<p>Adjust your filters and try again.</p>
</div>
</div>}
</div>

<Pagination
Expand Down