-
Notifications
You must be signed in to change notification settings - Fork 3.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: coinbase cb1 campaign (#11243)
<!-- Before opening a pull request, please read the [contributing guidelines](https://github.com/pancakeswap/pancake-frontend/blob/develop/CONTRIBUTING.md) first --> <!-- start pr-codex --> --- ## PR-Codex overview This PR introduces a new feature for the `Cb1Membership`, enhancing user engagement by displaying a modal to eligible users. It also updates translations and adds constants related to this feature. ### Detailed summary - Added `LS_CB1` constant to `apps/web/src/config/constants/index.ts`. - Introduced `Cb1Membership` component in `apps/web/src/components/Cb1/Cb1Membership.tsx`. - Implemented logic for showing the membership modal based on user eligibility. - Updated translations in `packages/localization/src/config/translations.json`. - Refactored imports in `apps/web/src/pages/_app.tsx` for new hooks and components. > ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}` <!-- end pr-codex -->
- Loading branch information
Showing
5 changed files
with
154 additions
and
3 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
import { useTranslation } from '@pancakeswap/localization' | ||
import { Button, Modal, ModalV2, Text, useMatchBreakpoints } from '@pancakeswap/uikit' | ||
import { ASSET_CDN } from 'config/constants/endpoints' | ||
import { useRouter } from 'next/router' | ||
import { Suspense, useEffect, useState } from 'react' | ||
import styled from 'styled-components' | ||
import { useShowCb1Popup } from './useCb1Membership' | ||
|
||
export const Cb1Membership = () => { | ||
return ( | ||
<Suspense fallback={null}> | ||
<Cb1Inner /> | ||
</Suspense> | ||
) | ||
} | ||
|
||
const Cb1Inner = () => { | ||
const { t } = useTranslation() | ||
const showCb1 = useShowCb1Popup() | ||
const [close, setClose] = useState(showCb1) | ||
const { isMobile } = useMatchBreakpoints() | ||
const router = useRouter() | ||
|
||
useEffect(() => { | ||
if (!showCb1) { | ||
setClose(false) | ||
} | ||
}, [showCb1]) | ||
return ( | ||
<ModalV2 | ||
isOpen={showCb1 && !close} | ||
closeOnOverlayClick | ||
onDismiss={() => { | ||
setClose(true) | ||
}} | ||
> | ||
<Modal title={t('You are Eligible!')} width={isMobile ? '100%' : '336px'}> | ||
<Cb1Image src={`${ASSET_CDN}/web/promotions/cb1.png`} /> | ||
<Text | ||
style={{ | ||
marginTop: '24px', | ||
}} | ||
> | ||
$8.453 {t('to be earned!')} | ||
</Text> | ||
<Text | ||
style={{ | ||
marginTop: '24px', | ||
}} | ||
> | ||
<b>Coinbase One </b> | ||
{t( | ||
'members who trade on PancakeSwap on Base, BNB, or Arbitrum are eligible to earn a portion of $8453 airdropped to their wallet biweekly! Must trade a minimum of $100 to qualify.', | ||
)} | ||
</Text> | ||
<Button | ||
style={{ | ||
marginTop: '24px', | ||
}} | ||
onClick={() => { | ||
router.replace('/') | ||
setClose(true) | ||
}} | ||
> | ||
{t('Trade now to participate!')} | ||
</Button> | ||
</Modal> | ||
</ModalV2> | ||
) | ||
} | ||
|
||
const Cb1Image = styled.img` | ||
width: 100%; | ||
height: auto; | ||
` |
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,68 @@ | ||
import { getChainName } from '@pancakeswap/chains' | ||
import { LS_CB1 } from 'config/constants' | ||
import useAccountActiveChain from 'hooks/useAccountActiveChain' | ||
import { useEffect, useState } from 'react' | ||
|
||
interface CB1State { | ||
expired: number | ||
} | ||
|
||
const BASE_URI = 'https://attestation-api.pancakeswap.com' | ||
|
||
const EXPIRE = 1000 * 24 * 3600 | ||
|
||
async function getCb1Membership(chain: string, address: string) { | ||
const resp = await fetch(`${BASE_URI}/api/attestation/base?userAddress=${address}`) | ||
const json = await resp.json() | ||
const attested = Boolean(json?.qualified) | ||
return attested | ||
} | ||
|
||
function updateExpire(address: string) { | ||
const cb1State: CB1State = { | ||
expired: Date.now() + EXPIRE, | ||
} | ||
localStorage.setItem(`${LS_CB1}-${address}`, JSON.stringify(cb1State)) | ||
} | ||
|
||
async function showCb1Popup(chain?: string, address?: string) { | ||
if (!address || !chain) { | ||
return false | ||
} | ||
if (!['base', 'bsc', 'arb'].includes(chain)) { | ||
return false | ||
} | ||
|
||
const lsItem = localStorage.getItem(`${LS_CB1}-${address}`) | ||
if (lsItem) { | ||
const cb1State: CB1State = JSON.parse(lsItem) | ||
const shouldShow = Date.now() > cb1State.expired | ||
if (shouldShow) { | ||
updateExpire(address) | ||
} | ||
return shouldShow | ||
} | ||
const attested = await getCb1Membership(chain, address) | ||
if (attested) { | ||
updateExpire(address) | ||
} | ||
return attested | ||
} | ||
|
||
export const useShowCb1Popup = () => { | ||
const { account, chainId } = useAccountActiveChain() | ||
const [showCb1, setShowCb1] = useState(false) | ||
|
||
const chainName = getChainName(chainId) | ||
|
||
useEffect(() => { | ||
const load = async () => { | ||
const show = await showCb1Popup(chainName, account) | ||
requestAnimationFrame(() => setShowCb1(show)) | ||
} | ||
|
||
load() | ||
}, [account, chainName]) | ||
|
||
return showCb1 | ||
} |
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