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: dynamic campaign promotions #202

Merged
merged 3 commits into from
Sep 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 0 additions & 10 deletions src/components/Claim/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,6 @@ import SafeToken from '@/public/images/token.svg'
import css from './styles.module.css'
import { useRouter } from 'next/router'
import { AppRoutes } from '@/config/routes'
import { canRedeemSep5Airdrop } from '@/utils/airdrop'
import { Sep5InfoBox } from '../Sep5InfoBox'
import { formatAmount } from '@/utils/formatters'
import { ClaimCard } from '../ClaimCard'
import { InfoAlert } from '../InfoAlert'
Expand Down Expand Up @@ -78,8 +76,6 @@ const ClaimOverview = (): ReactElement => {
// Allocation, vesting and voting power
const { data: allocation } = useSafeTokenAllocation()

const canRedeemSep5 = canRedeemSep5Airdrop(allocation)

const { ecosystemVesting, investorVesting } = getVestingTypes(allocation?.vestingData ?? [])

const { sep5, user, ecosystem, investor, total } = useTaggedAllocations()
Expand Down Expand Up @@ -213,12 +209,6 @@ const ClaimOverview = (): ReactElement => {
</Typography>
</Box>

{canRedeemSep5 && (
<Grid item xs={12}>
<Sep5InfoBox />
</Grid>
)}

<Grid item container gap={3} flexWrap="nowrap" xs={12} mb={1}>
<Grid item xs={6}>
<TextField
Expand Down
27 changes: 2 additions & 25 deletions src/components/DashboardWidgets/ClaimingWidget.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { BigNumber } from 'ethers'
import { formatEther } from 'ethers/lib/utils'
import { useSafeAppsSDK } from '@safe-global/safe-apps-react-sdk'
import { Box, Button, Typography, Link, Skeleton, Card, IconButton, Grid, Tooltip } from '@mui/material'
import { Box, Button, Typography, Link, Skeleton, Card, IconButton, Grid } from '@mui/material'
import ModeEditOutlinedIcon from '@mui/icons-material/ModeEditOutlined'
import CheckSharpIcon from '@mui/icons-material/CheckSharp'
import { useState } from 'react'
Expand All @@ -10,15 +10,12 @@ import type { ReactElement } from 'react'

import { ExternalLink } from '@/components/ExternalLink'
import SafeToken from '@/public/images/token.svg'
import { DISCORD_URL, FORUM_URL, SEP5_EXPIRATION_DATE } from '@/config/constants'
import { DISCORD_URL, FORUM_URL } from '@/config/constants'
import { getGovernanceAppSafeAppUrl } from '@/utils/safe-apps'
import { useDelegate } from '@/hooks/useDelegate'
import { useSafeTokenAllocation } from '@/hooks/useSafeTokenAllocation'
import { SelectedDelegate } from '@/components/SelectedDelegate'
import { formatAmount } from '@/utils/formatters'
import { Sep5DeadlineChip } from '@/components/Sep5DeadlineChip'
import { TypographyChip } from '@/components/TypographyChip'
import { canRedeemSep5Airdrop } from '@/utils/airdrop'

import css from './styles.module.css'

Expand Down Expand Up @@ -82,7 +79,6 @@ const VotingPowerWidget = (): ReactElement => {
const { safe } = useSafeAppsSDK()
const delegate = useDelegate()
const { data: allocation } = useSafeTokenAllocation()
const canRedeemSep5 = canRedeemSep5Airdrop(allocation)

const totalClaimed = allocation?.vestingData.reduce((acc, { amountClaimed }) => {
return acc.add(amountClaimed)
Expand All @@ -96,23 +92,6 @@ const VotingPowerWidget = (): ReactElement => {

return (
<Grid container p={1} height={1}>
{canRedeemSep5 && (
<Grid item xs={12} display="flex" justifyContent="space-between" mb="auto">
<TypographyChip fontWeight={700} px={1}>
New allocation
</TypographyChip>

<Tooltip
title={`You qualify for a new SAFE allocation! Ensure you execute at least one claim before ${SEP5_EXPIRATION_DATE}`}
arrow
placement="top"
>
<span>
<Sep5DeadlineChip px={1} />
</span>
</Tooltip>
</Grid>
)}
<Grid item xs={12} display="flex" flexDirection="column" alignItems="center" mt={4}>
<Typography variant="subtitle2" color="primary.light" textAlign="center">
Your voting power
Expand Down Expand Up @@ -164,7 +143,6 @@ const VotingPowerWidget = (): ReactElement => {

export const ClaimingWidget = (): ReactElement => {
const { data: allocation, isLoading } = useSafeTokenAllocation()
const canRedeemSep5 = canRedeemSep5Airdrop(allocation)

if (isLoading) {
return (
Expand All @@ -186,7 +164,6 @@ export const ClaimingWidget = (): ReactElement => {
sx={{
minWidth: WIDGET_WIDTH,
maxWidth: WIDGET_WIDTH,
border: canRedeemSep5 ? ({ palette }) => `1px solid ${palette.primary.main}` : undefined,
}}
>
<>{allocation?.votingPower.eq(0) ? <CtaWidget /> : <VotingPowerWidget />}</>
Expand Down
159 changes: 80 additions & 79 deletions src/components/Points/CampaignPromo.tsx
Original file line number Diff line number Diff line change
@@ -1,40 +1,45 @@
import { Box, LinearProgress, Stack, SvgIcon, Typography } from '@mui/material'
import { Box, LinearProgress, Stack, Typography } from '@mui/material'
import PaperContainer from '../PaperContainer'
import MorhoIcon from '@/public/images/morpho.svg'
import SpotlightIcon from '@/public/images/spotlight.svg'

import css from './styles.module.css'
import { MORPHO_CAMPAIGN_IDS } from '@/config/constants'
import { useChainId } from '@/hooks/useChainId'
import { useCampaignInfo } from '@/hooks/useCampaigns'
import { useCampaignsPaginated } from '@/hooks/useCampaigns'
import { getRelativeTime } from '@/utils/date'
import { getSafeAppUrl } from '@/utils/safe-apps'
import { useAddress } from '@/hooks/useAddress'
import { useMemo } from 'react'
import { ExternalLink } from '../ExternalLink'
import { formatAmount } from '@/utils/formatters'

export const CampaignPromo = () => {
const chainId = useChainId()
const address = useAddress()
const morphoCampaignId = MORPHO_CAMPAIGN_IDS[chainId]
const { data: campaignsPage } = useCampaignsPaginated()

const morphoCampaign = useCampaignInfo(morphoCampaignId)
// We only check the first page as it contains the most up-to-date campaigns
const promotedCampaign = useMemo(
() => campaignsPage?.find((campaign) => campaign.isPromoted && new Date(campaign.endDate).getTime() > Date.now()),
[campaignsPage],
)

const safeAppUrl = useMemo(
() => (address ? getSafeAppUrl(chainId, address, 'https://safe-app.morpho.org/') : ''),
[chainId, address],
() =>
address && promotedCampaign?.safeAppUrl
? getSafeAppUrl(chainId, address, promotedCampaign?.safeAppUrl ?? '')
: undefined,
[address, chainId, promotedCampaign?.safeAppUrl],
)

if (!morphoCampaign) {
if (!promotedCampaign) {
return null
}

const hasStarted = new Date(morphoCampaign.startDate).getTime() <= Date.now()
const hasEnded = new Date(morphoCampaign.endDate).getTime() <= Date.now()
const hasStarted = new Date(promotedCampaign.startDate).getTime() <= Date.now()
const hasEnded = new Date(promotedCampaign.endDate).getTime() <= Date.now()

const progress =
Math.max(Date.now() - new Date(morphoCampaign.startDate).getTime(), 0) /
(new Date(morphoCampaign.endDate).getTime() - new Date(morphoCampaign.startDate).getTime())
Math.max(Date.now() - new Date(promotedCampaign.startDate).getTime(), 0) /
(new Date(promotedCampaign.endDate).getTime() - new Date(promotedCampaign.startDate).getTime())

if (hasEnded) {
return null
Expand All @@ -45,7 +50,7 @@ export const CampaignPromo = () => {
<LinearProgress
className={css.progressBar}
variant="determinate"
value={progress}
value={progress * 100}
sx={{
Copy link
Member

Choose a reason for hiding this comment

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

Did something change about the progress value so that we have to multiply it now?

Copy link
Member Author

Choose a reason for hiding this comment

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

It was wrong before but noone realized it. It has to be between 0 and 100 and not 0 and 1

mt: '-40px',
ml: '-32px',
Expand All @@ -54,78 +59,74 @@ export const CampaignPromo = () => {
/>
<Stack alignItems="center">
<Typography variant="body2" color="text.secondary" mb={2}>
{morphoCampaign
{promotedCampaign
? !hasStarted
? `Starts ${getRelativeTime(new Date(morphoCampaign.startDate))}`
: `Ends ${getRelativeTime(new Date(morphoCampaign.endDate))}`
? `Starts ${getRelativeTime(new Date(promotedCampaign.startDate))}`
: `Ends ${getRelativeTime(new Date(promotedCampaign.endDate))}`
: null}
</Typography>
<Box position="relative">
<SvgIcon
component={SpotlightIcon}
inheritViewBox
sx={{
position: 'absolute',
top: 0,
left: '-21px',
width: '42px',
height: '56px',
}}
/>
<SvgIcon
component={MorhoIcon}
inheritViewBox
sx={{
width: '148px',
height: '100px',
}}
/>
<SvgIcon
component={SpotlightIcon}
inheritViewBox
sx={{
position: 'absolute',
top: 0,
right: '-21px',
width: '42px',
height: '56px',
transform: 'rotateY(180deg)',
}}
/>
{promotedCampaign.iconUrl ? (
<Box position="relative">
{promotedCampaign.iconUrl && (
<img
alt={'Campaign icon'}
src={promotedCampaign.iconUrl}
style={{ maxWidth: '176px', maxHeight: '80px', borderRadius: '8px' }}
/>
)}
</Box>
) : (
<Typography variant="h1" fontWeight={700} maxWidth="80%" className={css.gradientText} mb={2}>
{promotedCampaign.name}
</Typography>
)}
<Box className={css.prizePoolBox}>
<Typography variant="overline" color="text.secondary" fontWeight={700}>
Prize pool
</Typography>
{promotedCampaign.rewardValue ? (
<Typography mt={1} variant="h4" fontSize="27px" fontWeight={700}>
{formatAmount(Number(promotedCampaign.rewardValue), 0)}{' '}
<span style={{ color: '#817EE9' }}>{promotedCampaign.rewardText}</span>
</Typography>
) : (
<Typography mt={1} variant="h4" fontSize="27px" fontWeight={700}>
{promotedCampaign.rewardText}
</Typography>
)}

<Typography variant="body2">& Safe points</Typography>
</Box>

<Typography mt={5} variant="overline" color="text.secondary">
Prize pool
</Typography>
<Typography mt={1} variant="h4" fontSize="27px" fontWeight={700}>
600,000 <span style={{ color: '#2470FF' }}>MORPHO</span>
</Typography>
<Typography variant="body2">& Safe points</Typography>
<Typography variant="body2" color="text.secondary" mt={5}>
<ExternalLink href="https://dub.sh/morphocampaign" isPartner>
Learn more
</ExternalLink>{' '}
and participate in campaign:
Participate in campaign:
</Typography>
<Stack direction="row" alignItems="center" spacing={2} mt={2}>
<ExternalLink variant="button" color="primary" href={safeAppUrl} target="_blank" isPartner>
Safe App
</ExternalLink>
<Typography>or</Typography>
<ExternalLink
isPartner
href="https://app.morpho.org/"
target="_blank"
variant="button"
sx={{
color: '#2470FF',
'&:hover': {
backgroundColor: ({ palette }) => `rgba(36, 112, 255, ${palette.action.hoverOpacity})`,
},
}}
>
Morpho
</ExternalLink>
{safeAppUrl && (
<>
<ExternalLink variant="button" color="primary" href={safeAppUrl} target="_blank" isPartner>
Safe App
</ExternalLink>
<Typography>or</Typography>
</>
)}

{promotedCampaign.partnerUrl && (
<ExternalLink
isPartner
href={promotedCampaign.partnerUrl}
target="_blank"
variant="button"
sx={{
color: '#FFF',
'&:hover': {
backgroundColor: ({ palette }) => `rgba(255, 255, 255, ${palette.action.hoverOpacity})`,
},
}}
>
{promotedCampaign.name}
</ExternalLink>
)}
</Stack>
</Stack>
</PaperContainer>
Expand Down
12 changes: 12 additions & 0 deletions src/components/Points/styles.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,15 @@
.progressBar {
background: none;
}

.prizePoolBox {
border-radius: 6px;
border: 1px solid var(--mui-palette-border-light);
width: 100%;
display: flex;
flex-direction: column;
align-items: center;
gap: 8px;
margin-top: 32px;
padding: 16px 0px;
}
16 changes: 0 additions & 16 deletions src/components/Sep5DeadlineChip/index.tsx

This file was deleted.

44 changes: 0 additions & 44 deletions src/components/Sep5InfoBox/index.tsx

This file was deleted.

Loading
Loading