-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1711 from sushi-labs/feature/egn-760
feat(apps/web): add strapi banner to swap
- Loading branch information
Showing
8 changed files
with
437 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
71 changes: 71 additions & 0 deletions
71
apps/web/src/ui/swap/strapi-banner/strapi-banner-content.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
'use client' | ||
|
||
import { XMarkIcon } from '@heroicons/react/20/solid' | ||
import { Banner } from '@sushiswap/graph-client/strapi' | ||
import { LinkExternal, classNames } from '@sushiswap/ui' | ||
import type { RequestCookie } from 'next/dist/compiled/@edge-runtime/cookies' | ||
import Image from 'next/legacy/image' | ||
import { MouseEventHandler, useCallback, useMemo, useState } from 'react' | ||
import { getOptimizedMedia } from 'src/app/(cms)/lib/media' | ||
|
||
export function StrapiBannerContent({ | ||
banner, | ||
cookie: _cookie, | ||
}: { banner: Banner; cookie: RequestCookie | undefined }) { | ||
const [cookie, setCookie] = useState<RequestCookie | undefined>(_cookie) | ||
const [isImageLoading, setImageLoading] = useState(true) | ||
|
||
const hiddenBannerIds = useMemo(() => { | ||
return cookie ? cookie.value.split(',') : [] | ||
}, [cookie]) | ||
|
||
const onHide = useCallback( | ||
(event: Parameters<MouseEventHandler<HTMLDivElement>>[0]) => { | ||
event.preventDefault() | ||
|
||
const newHiddenBannerIds = [...hiddenBannerIds, banner.id] | ||
|
||
document.cookie = `hidden-banner-ids=${newHiddenBannerIds.join( | ||
',', | ||
)}; path=/; max-age=31536000` | ||
|
||
setCookie({ | ||
name: 'hidden-banner-ids', | ||
value: newHiddenBannerIds.join(','), | ||
}) | ||
}, | ||
[banner, hiddenBannerIds], | ||
) | ||
|
||
if (hiddenBannerIds.includes(banner.id)) { | ||
return <></> | ||
} | ||
|
||
const image = banner.image.attributes | ||
|
||
return ( | ||
<div className="rounded-xl w-full relative"> | ||
<LinkExternal href={banner.link}> | ||
{/* biome-ignore lint/a11y/useKeyWithClickEvents: stupid */} | ||
<div className="absolute z-10 right-0 top-0 p-2" onClick={onHide}> | ||
<XMarkIcon width={32} height={32} className="text-white" /> | ||
</div> | ||
<Image | ||
src={getOptimizedMedia({ | ||
metadata: image.provider_metadata, | ||
width: image.width, | ||
height: image.height, | ||
})} | ||
alt={image.alternativeText || ''} | ||
width={image.width} | ||
height={image.height} | ||
onLoad={() => setImageLoading(false)} | ||
className={classNames( | ||
'rounded-xl absolute bg-secondary', | ||
isImageLoading && 'animate-pulse', | ||
)} | ||
/> | ||
</LinkExternal> | ||
</div> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import { getBanners } from '@sushiswap/graph-client/strapi' | ||
import ms from 'ms' | ||
import { unstable_cache } from 'next/cache' | ||
import { cookies } from 'next/headers' | ||
import { StrapiBannerContent } from './strapi-banner-content' | ||
|
||
export async function StrapiBanner() { | ||
let banners | ||
|
||
try { | ||
banners = await unstable_cache(() => getBanners(), ['banners'], { | ||
revalidate: ms('1h'), | ||
})() | ||
} catch {} | ||
|
||
if (!banners) return <></> | ||
|
||
// Only supporting one active banner at a time for now | ||
const activeBanner = banners.find((banner) => banner.isActive) | ||
|
||
if (!activeBanner) return <></> | ||
|
||
return ( | ||
<StrapiBannerContent | ||
banner={activeBanner} | ||
cookie={cookies().get('hidden-banner-ids')} | ||
/> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
67 changes: 67 additions & 0 deletions
67
packages/graph-client/src/subgraphs/strapi/queries/banners.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
import type { VariablesOf } from 'gql.tada' | ||
|
||
import { request, type RequestOptions } from 'src/lib/request' | ||
import { graphql } from '../graphql' | ||
import { STRAPI_GRAPHQL_URL } from 'src/subgraphs/strapi/constants' | ||
import { ImageFieldsFragment } from 'src/subgraphs/strapi/fragments/image-fields' | ||
|
||
export const StrapiBannersQuery = graphql( | ||
`query Banners { | ||
banners { | ||
data { | ||
id | ||
attributes { | ||
dateFrom | ||
dateTo | ||
link | ||
image { | ||
data { | ||
...ImageFields | ||
} | ||
} | ||
} | ||
} | ||
} | ||
}`, | ||
[ImageFieldsFragment], | ||
) | ||
|
||
export type GetBanners = VariablesOf<typeof StrapiBannersQuery> | ||
|
||
export type Banner = Awaited<ReturnType<typeof getBanners>>[number] | ||
|
||
export async function getBanners( | ||
_variables: GetBanners = {}, | ||
options?: RequestOptions, | ||
) { | ||
const variables = _variables as VariablesOf<typeof StrapiBannersQuery> | ||
|
||
const result = await request( | ||
{ | ||
url: STRAPI_GRAPHQL_URL, | ||
document: StrapiBannersQuery, | ||
variables, | ||
}, | ||
options, | ||
) | ||
|
||
if (!result.banners) { | ||
throw new Error('Failed to fetch banners') | ||
} | ||
|
||
return result.banners.data.map((topic) => { | ||
const dateFrom = new Date(topic.attributes.dateFrom) | ||
const dateTo = new Date(topic.attributes.dateTo) | ||
|
||
const isActive = dateFrom <= new Date() && dateTo >= new Date() | ||
|
||
return { | ||
id: topic.id, | ||
dateFrom, | ||
dateTo, | ||
link: topic.attributes.link, | ||
image: topic.attributes.image.data, | ||
isActive, | ||
} | ||
}) | ||
} |
Oops, something went wrong.