Skip to content

Commit

Permalink
Merge pull request #823 from setlife-network/sr/issue-811/send-bonus-…
Browse files Browse the repository at this point in the history
…split-equally

Send bonuses button UI
  • Loading branch information
sofiaromorales committed Jun 12, 2023
2 parents 0951d6c + 8a8fa40 commit a7fef35
Show file tree
Hide file tree
Showing 8 changed files with 398 additions and 10 deletions.
2 changes: 1 addition & 1 deletion api/schema/types/PaymentType.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ module.exports = gql`
): Payment
convertUSDtoSATS(
amount: Float!
amount: Int!
): Float!
}
Expand Down
84 changes: 84 additions & 0 deletions srcv2/components/SendBonus.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import React, { useState, useEffect } from 'react'
import CurrencyTextField from '@unicef/material-ui-currency-textfield'
import { useMutation } from '@apollo/client'

import SendBonusAmount from './SendBonusAmount'
import SendBonusConfirmation from './SendBonusConfirmation'
import SendBonusSuccessful from './SendBonusSuccessful'

import { CONVERT_USD_TO_SATS_AMOUNT } from '../operations/mutations/PaymentMutations'

const SendBonus = (props) => {

const {
project,
setOpen
} = props

const [selectedContributors, setSelectedContributors] = useState([])
const [screenIndex, setScreenIndex] = useState(0)
const [bonusAmount, setBonusAmount] = useState(0)
const [satsBonusAmount, setSatsBonusAmount] = useState()

const screens = [SendBonusAmount]

const buttonText = ['Continue', 'Send bonuses', 'Finish']

const [fetchSatsAmount, {
dataSatsAmount,
loadingSatsAmount,
errorSatsAmount
}] = useMutation(CONVERT_USD_TO_SATS_AMOUNT)

const nextStep = async () => {
if (screenIndex == 0) {
const variables = { amount: parseInt(bonusAmount, 10) }
const { data } = await fetchSatsAmount({ variables })
setSatsBonusAmount(data.convertUSDtoSATS)
}
setScreenIndex(screenIndex + 1)
}

const disableContinue = !selectedContributors.length || !bonusAmount

if (screenIndex == 3) { setOpen(false) }

return (
<div className='SendBonus lg:px-16'>
{screenIndex == 0 &&
<SendBonusAmount
project={project}
selectedContributors={selectedContributors}
setSelectedContributors={setSelectedContributors}
bonusAmount={bonusAmount}
setBonusAmount={setBonusAmount}
/>
}
{screenIndex == 1 &&
<SendBonusConfirmation
selectedContributors={selectedContributors}
bonusAmount={bonusAmount.replace(',', '')}
satsBonusAmount={satsBonusAmount}
/>
}
{screenIndex == 2 &&
<SendBonusSuccessful
bonusAmount={bonusAmount.replace(',', '')}
satsBonusAmount={satsBonusAmount}
/>
}
<div className='grid absolute bottom-10 left-16 right-16 gap-2'>
<button
className={`${disableContinue ? 'bg-med-gray' : 'bg-setlife'} rounded-full py-2 w-full text-white`}
onClick={() => nextStep()}
type='button'
disabled={disableContinue}
>
{`${buttonText[screenIndex]}`}
</button>
</div>
</div>
)
}

export default SendBonus
64 changes: 64 additions & 0 deletions srcv2/components/SendBonusAmount.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import React, { useState } from 'react'

import SendBonusEqualy from './SendBonusEqualy'

const BONUS_SPLIT_TYPES = [
{
type: 'equaly',
name: 'Split Equaly'
},
{
type: 'customize',
name: 'Customize'
}
]

const SendBonusAmount = (props) => {

const {
project,
selectedContributors,
setSelectedContributors,
bonusAmount,
setBonusAmount
} = props

const [selectedBonusSplitType, setSelectedBonusSplitType] = useState(0)

return (
<div className='SendBonusAmount'>
<p className='font-bold text-xl mb-4'>
Enter info below to send a bonus
</p>
<div className='rounded-full bg-white-light grid grid-cols-2'>
<button
type='button'
className={`font-bold rounded-full mr-1 ml-2 my-2 py-1 px-2 ${selectedBonusSplitType == 0 ? 'bg-setlife text-white' : 'bg-med-gray'}`}
onClick={() => setSelectedBonusSplitType(0)}
>
<p>
{BONUS_SPLIT_TYPES[0].name}
</p>
</button>
<button
type='button'
className={`bg-med-gray font-bold rounded-full mr-2 ml-1 my-2 py-1 px-2 ${selectedBonusSplitType == 1 ? 'bg-setlife text-white' : 'bg-med-gray'}`}
onClick={() => setSelectedBonusSplitType(1)}
>
<p>
{BONUS_SPLIT_TYPES[1].name}
</p>
</button>
</div>
<SendBonusEqualy
project={project}
selectedContributors={selectedContributors}
setSelectedContributors={setSelectedContributors}
bonusAmount={bonusAmount}
setBonusAmount={setBonusAmount}
/>
</div>
)
}

export default SendBonusAmount
63 changes: 63 additions & 0 deletions srcv2/components/SendBonusConfirmation.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import React from 'react'
import {
Icon
} from '@material-ui/core'

const SendBonusConfirmation = (props) => {

const {
bonusAmount,
satsBonusAmount,
selectedContributors
} = props

const renderSenders = () => {
return selectedContributors.map(sc => {
return (
<div className='sendingContributor grid grid-cols-2 mb-4'>
<div>
<p className='font-bold'>
{sc.name}
</p>
</div>
<div className='grid grid-cols-1 text-right'>
<p className='font-bold'>
{`${Intl.NumberFormat().format(Math.trunc(satsBonusAmount))} SATS`}
</p>
<p className='text-gray'>
{`${Intl.NumberFormat('de-DE', { style: 'currency', currency: 'USD' }).format(Math.trunc(bonusAmount))}`}
</p>
</div>
</div>
)
})
}

return (
<div className='SendBonusConfirmation'>
<p className='font-bold text-xl mb-4'>
Confirmation page
</p>
<p className='font-bold text-xl mb-4 m-auto '>
Please review the amount below and confirm before sending
</p>
<p className='text-5xl m-auto text-center my-4'>
<Icon className='fa-solid fa-money-bill-trend-up text-setlife' fontSize='inherit'/>
</p>
<p className='text-center text-4xl'>
{`${Intl.NumberFormat().format(Math.trunc(satsBonusAmount))} SATS`}
</p>
<p className='text-center text-md text-gray'>
{`~ ${Intl.NumberFormat('de-DE', { style: 'currency', currency: 'USD' }).format(Math.trunc(bonusAmount))}`}
</p>
<p className='font-bold text-md text-gray'>
Sending to
</p>
<div className='rounded-lg bg-white-light mt-4 pt-4 pb-2 px-4'>
{renderSenders()}
</div>
</div>
)
}

export default SendBonusConfirmation
111 changes: 111 additions & 0 deletions srcv2/components/SendBonusEqualy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
import React, { useState, useEffect } from 'react'
import CurrencyTextField from '@unicef/material-ui-currency-textfield'
import { Icon } from '@material-ui/core'

import { selectCurrencyInformation } from '../scripts/selectors'

const SendBonusEqualy = (props) => {

const {
selectedContributors,
setSelectedContributors,
project,
bonusAmount,
setBonusAmount
} = props

const [selectedContributorsIdx, setSelectedContributorsIdx] = useState([])

useEffect(() => {
const contributors = project.contributors.filter((c, idx) => selectedContributorsIdx.includes(idx))
setSelectedContributors(contributors)
}, [selectedContributorsIdx])

const currencyInformation = project.expected_budget_currency
? selectCurrencyInformation({
currency: project.expected_budget_currency
})
: null

const selectContributor = (idx) => {
if (selectedContributorsIdx.includes(idx)) {
setSelectedContributorsIdx(
selectedContributorsIdx.filter(c => c != idx)
)
return
}
setSelectedContributorsIdx([...selectedContributorsIdx, idx])
}

const handleBonusAmountChange = (amount) => {
if (amount.includes('.')) {
setBonusAmount(amount.slice(0, amount.indexOf('.')))
return
}
setBonusAmount(amount)
}

const allContributorsSelected = selectedContributorsIdx.length == project.contributors.length

const renderContributors = (contributors) => {
return contributors.map((c, idx) => {
const isSelected = selectedContributorsIdx.includes(idx)
return (
<div className='contributor mb-3 flex'>
<button
type='button'
onClick={() => selectContributor(idx)}
className={`mr-4 rounded-full border-solid border-2 border-setlife text-center h-6 w-6 text-sm col-span-1 my-auto ${isSelected ? 'bg-setlife' : 'bg-white'}`}
>
<Icon className='icon fa-solid fa-check text-white text-center w-full h-full m-auto align-middle' fontSize='inherit'/>
</button>
<div className='my-auto rounded-full h-10 w-10 bg-light text-4xl text-center col-span-1'>
<Icon className='icon fas fa-user text-gray text-center w-full h-full mt-2.5' fontSize='medium'/>
</div>
<div className='my-auto col-span-6 pl-4'>
<p className='truncate'>
{c.name}
</p>
</div>
</div>
)
})
}

const indicesArray = Array.from({ length: project.contributors.length }, (value, index) => index);

return (
<div className='SendBonusEqualy'>
<div className='mt-10'>
<CurrencyTextField
fullWidth
label='Payment amount'
variant='outlined'
currencySymbol={`${currencyInformation['symbol']}`}
minimumValue='0'
outputFormat='string'
decimalCharacter={`${currencyInformation['decimal']}`}
digitGroupSeparator={`${currencyInformation['thousand']}`}
onChange={(event) => handleBonusAmountChange(event.target.value)}
/>
</div>
<div className='mt-10'>
<p className='font-bold text-md mb-4'>
Active contributors for this project
</p>
<button
type='button'
onClick={() => setSelectedContributorsIdx(allContributorsSelected ? [] : indicesArray)}
className={`rounded-full border-solid border-2 border-med-gray bg-med-gray text-center text-sm my px-4 py-1 mb-4`}
>
{allContributorsSelected ? 'Select None' : 'Select All'}
</button>
<div className='overflow-scroll h-72'>
{renderContributors(project.contributors)}
</div>
</div>
</div>
)
}

export default SendBonusEqualy
40 changes: 40 additions & 0 deletions srcv2/components/SendBonusSuccessful.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import React from 'react'
import {
Icon,
} from '@material-ui/core'

const SendBonusSuccessful = (props) => {

const {
bonusAmount,
satsBonusAmount,
} = props

return (
<div className='SendBonusSuccessful'>
<div>
<div
type='button'
className='h-16 w-16 bg-setlife rounded-full text-3xl m-auto flex'
onClick={() => history.push(`/add-payment/${projectId}`)}
>
<Icon className='icon fa-solid fa-check text-white font-bold w-fit h-fit m-auto pb-1 leading-8 text-center' fontSize='inherit'/>
</div>
<p className='font-bold text-xl mb-4 m-auto text-center mt-8'>
Bonuses have been sent!
</p>
<p className='text-5xl m-auto text-center my-4 mt-8'>
<Icon className='fa-solid fa-money-bill-trend-up text-setlife' fontSize='inherit'/>
</p>
<p className='text-center text-4xl mt-6'>
{`${Intl.NumberFormat().format(Math.trunc(satsBonusAmount))} SATS`}
</p>
<p className='text-center text-md text-gray'>
{`~ ${Intl.NumberFormat('de-DE', { style: 'currency', currency: 'USD' }).format(Math.trunc(bonusAmount))}`}
</p>
</div>
</div>
)
}

export default SendBonusSuccessful
8 changes: 7 additions & 1 deletion srcv2/operations/mutations/PaymentMutations.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,15 @@ export const UPDATE_PAYMENT = gql`

export const CREATE_BITCOIN_INVOICE = gql`
mutation GenerateBitcoinInvoice($paymentId: Int!){
generateBitcoinInvoiceFromPayment(paymentId: $paymentId){
generateBitcoinInvoiceFromPayment(paymentId: $paymentId) {
external_uuid
bitcoinCheckoutUrl
}
}
`

export const CONVERT_USD_TO_SATS_AMOUNT = gql`
mutation ConvertUSDtoSATS($amount: Int!) {
convertUSDtoSATS(amount: $amount)
}
`
Loading

0 comments on commit a7fef35

Please sign in to comment.