Skip to content

Commit

Permalink
feat(#1368): add Expeditions Task Cards
Browse files Browse the repository at this point in the history
  • Loading branch information
adamazad committed Aug 31, 2022
1 parent 596a89f commit ebedc47
Show file tree
Hide file tree
Showing 12 changed files with 252 additions and 91 deletions.
56 changes: 0 additions & 56 deletions src/components/expeditions/ExpeditionsModal.tsx

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { ExternalLink } from 'react-feather'
import { Box } from 'rebass'
import styled from 'styled-components'

export const Wrapper = styled.div`
border-radius: 12px;
background-color: ${({ theme }) => theme.bg1And2};
`

export const Card = styled(Box)`
display: flex;
flex-flow: column nowrap;
padding: 24px;
gap: 16px;
`

export const StyledExternalLink = styled(ExternalLink)`
font-size: 13px;
font-style: italic;
text-decoration: underline;
&:hover {
color: white;
}
`
Original file line number Diff line number Diff line change
@@ -1,33 +1,8 @@
import { ExternalLink } from 'react-feather'
import { Box } from 'rebass'
import styled from 'styled-components'

import { TYPE } from '../../theme'
import { ButtonPrimary } from '../Button'
import Row from '../Row'
import { TagFailed, TagSuccess, TagWarning } from '../Tag'

const Wrapper = styled.div`
border-radius: 12px;
background-color: ${({ theme }) => theme.bg1And2};
`

const Card = styled(Box)`
display: flex;
flex-flow: column nowrap;
padding: 24px;
gap: 16px;
`

export const StyledExternalLink = styled(ExternalLink)`
font-size: 13px;
font-style: italic;
text-decoration: underline;
&:hover {
color: white;
}
`
import { ButtonPrimary } from '../../../../components/Button'
import Row from '../../../../components/Row'
import { TagFailed, TagSuccess, TagWarning } from '../../../../components/Tag'
import { TYPE } from '../../../../theme'
import { Card, StyledExternalLink, Wrapper } from './ExpeditionsCard.styled'

type StatusTags = 'active' | 'upcoming' | 'expired'

Expand All @@ -37,7 +12,9 @@ export interface TaskCardProps {
title: string
description: string
buttonText: string
butttonDisabled?: boolean
infoLink?: string
onClick?: () => void
}

const StatusTag = ({ status }: Pick<TaskCardProps, 'status'>) => {
Expand All @@ -53,7 +30,16 @@ const StatusTag = ({ status }: Pick<TaskCardProps, 'status'>) => {

// Buttons to be implemented as needed. Maybe fixed set of buttons or button can be passed as child

export const TaskCard = ({ duration = 'Weekly', title, description, infoLink, status, buttonText }: TaskCardProps) => {
export function TaskCard({
duration = 'Weekly',
title,
description,
infoLink,
status,
buttonText,
butttonDisabled = false,
onClick,
}: TaskCardProps) {
return (
<Wrapper>
<Card>
Expand All @@ -63,13 +49,12 @@ export const TaskCard = ({ duration = 'Weekly', title, description, infoLink, st
</TYPE.White>
<StatusTag status={status} />
</Row>

<TYPE.White fontSize="20px">{title}</TYPE.White>

<TYPE.White fontSize="14px">{description}</TYPE.White>

{infoLink && <StyledExternalLink href={infoLink}>More info</StyledExternalLink>}
<ButtonPrimary padding="8px">{buttonText}</ButtonPrimary>
<ButtonPrimary padding="8px" onClick={onClick} disabled={butttonDisabled}>
{buttonText}
</ButtonPrimary>
</Card>
</Wrapper>
)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './ExpeditionsCard'
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { ReactNode } from 'react'
import styled from 'styled-components'

import SwprLogo from '../../../../assets/images/swpr-logo.png'
import { AutoColumn } from '../../../../components/Column'
import Modal from '../../../../components/Modal'
import Row from '../../../../components/Row'
import { useShowExpeditionsPopup } from '../../../../state/application/hooks'
import { TYPE } from '../../../../theme'
import { LiquidityProvisionTaskCard } from './partials/LiquidityProvisionTaskCard/LiquidityProvisionTaskCard'
import { LiquidityStakingTaskCard } from './partials/LiquidityStakingTaskCard'

const ContentWrapper = styled(AutoColumn)`
width: 100%;
background-color: ${({ theme }) => theme.dark1};
padding: 32px;
overflow-y: auto;
`

const Text = ({ children }: { children: ReactNode }) => (
<TYPE.White fontSize="16px" lineHeight="150%">
{children}
</TYPE.White>
)

export interface ExpeditionsModalProps {
onDismiss: () => void
}

export function ExpeditionsModal({ onDismiss }: ExpeditionsModalProps) {
const open = useShowExpeditionsPopup()

return (
<Modal maxWidth={630} onDismiss={onDismiss} isOpen={open}>
<ContentWrapper gap="lg">
<AutoColumn gap={'32px'}>
<Row justifyContent={'center'} gap={'8px'}>
<img src={SwprLogo} alt="SwprLogo" style={{ height: '40px' }} />
<TYPE.LargeHeader>Swapr Expeditions</TYPE.LargeHeader>
</Row>
<Row>
<Text>
Expeditions are missions you can complete on Swapr to earn “Star Fragments”. These can be redeemed for
special NFT's and various other rewards.
</Text>
</Row>
<Row>
<Text>Learn More</Text>
</Row>
</AutoColumn>
<AutoColumn justify={'center'} gap="32px">
<LiquidityProvisionTaskCard />
<LiquidityStakingTaskCard />
</AutoColumn>
</ContentWrapper>
</Modal>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './ExpeditionsModal'
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { useContext, useState } from 'react'

import { claimUserWeeklyFragments } from '../../../../api'
import { WeeklyFragmentType } from '../../../../constants'
import { ExpeditionsContext } from '../../../../contexts/ExpeditionsContext'
import { computeFragmentState } from '../../../../utils'
import { TaskCard as TaskCardBase, TaskCardProps } from '../../../ExpeditionsCard'

const TaskCard = (props: Omit<TaskCardProps, 'description' | 'duration' | 'title'>) => (
<TaskCardBase
description="Get some fragments each week for providing at least $50 of liquidity on Swapr!"
duration="Weekly"
title="Provide Liquidity"
{...props}
/>
)

export function LiquidityProvisionTaskCard() {
const [isClaiming, setIsClaiming] = useState(false)
const { rewards, isLoading, provider } = useContext(ExpeditionsContext)

if (isLoading) {
return <TaskCard buttonText={'Loading...'} status={'upcoming'} />
}

const { liquidityProvision } = rewards
const { isAvailableToClaim, isClaimed, isIncomplete } = computeFragmentState(liquidityProvision)

const claimFrgments = async () => {
if (!isClaimed && !isAvailableToClaim && !isClaiming) {
return
}

setIsClaiming(true)
try {
const address = await provider.getSigner().getAddress()
const signature = await provider.getSigner().signMessage('Claim Swapr weekly liquidity provision fragments')
await claimUserWeeklyFragments({ address, signature, type: WeeklyFragmentType.LIQUIDITY_PROVISION })
} catch (error) {
console.error(error)
} finally {
setIsClaiming(true)
}
}

let buttonText: string = ''

if (isClaimed) {
buttonText = 'Claimed'
} else if (isAvailableToClaim) {
buttonText = `Claim ${liquidityProvision.claimableFragments} Fragments`
} else if (isIncomplete) {
buttonText = 'TASK NOT YET COMPLETED'
}

return (
<TaskCard
buttonText={buttonText}
status={rewards.liquidityStaking.claimableFragments > 0 ? 'active' : 'upcoming'}
butttonDisabled={isIncomplete}
onClick={claimFrgments}
/>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './LiquidityProvisionTaskCard'
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { useContext, useState } from 'react'

import { claimUserWeeklyFragments } from '../../../../api'
import { WeeklyFragmentType } from '../../../../constants'
import { ExpeditionsContext } from '../../../../contexts/ExpeditionsContext'
import { computeFragmentState } from '../../../../utils'
import { TaskCard as TaskCardBase, TaskCardProps } from '../../../ExpeditionsCard'

const TaskCard = (props: Omit<TaskCardProps, 'description' | 'duration' | 'title'>) => (
<TaskCardBase
description="Get some fragments each week for staking at least $50 of liquidity on Swapr!"
duration="Weekly"
title="Stake Liquidity"
{...props}
/>
)

export function LiquidityStakingTaskCard() {
const [isClaiming, setIsClaiming] = useState(false)
const { rewards, isLoading, provider } = useContext(ExpeditionsContext)

if (isLoading) {
return <TaskCard buttonText={'Loading...'} status={'upcoming'} />
}

const { liquidityStaking } = rewards
const { isAvailableToClaim, isClaimed, isIncomplete } = computeFragmentState(liquidityStaking)

const claimFrgments = async () => {
if (!isClaimed && !isAvailableToClaim && !isClaiming) {
return
}

setIsClaiming(true)
try {
const address = await provider.getSigner().getAddress()
const signature = await provider.getSigner().signMessage('Claim Swapr weekly liquidity staking fragments')
await claimUserWeeklyFragments({ address, signature, type: WeeklyFragmentType.LIQUIDITY_STAKING })
// Update local state
} catch (error) {
console.error(error)
} finally {
setIsClaiming(true)
}
}

let buttonText: string = ''

if (isClaiming) {
buttonText = 'Claiming...'
} else if (isClaimed) {
buttonText = 'Claimed'
} else if (isAvailableToClaim) {
buttonText = `Claim ${liquidityStaking.claimableFragments} Fragments`
} else if (isIncomplete) {
buttonText = 'TASK NOT YET COMPLETED'
}

return (
<TaskCard
buttonText={buttonText}
status={rewards.liquidityStaking.claimableFragments > 0 ? 'active' : 'upcoming'}
butttonDisabled={isIncomplete}
onClick={claimFrgments}
/>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './LiquidityStakingTaskCard'
1 change: 1 addition & 0 deletions src/modules/expeditions/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export {}
13 changes: 13 additions & 0 deletions src/modules/expeditions/utils/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { WeeklyFragmentRewards } from '../api'

export function computeFragmentState(rewards: WeeklyFragmentRewards) {
const isClaimed = rewards.claimedFragments > 0
const isAvailableToClaim = rewards.claimableFragments > 0
const isIncomplete = !isClaimed && !isAvailableToClaim

return {
isClaimed,
isAvailableToClaim,
isIncomplete,
}
}

0 comments on commit ebedc47

Please sign in to comment.