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

Issue 2365 fix #4351

Closed
wants to merge 24 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
ebd58a3
toggle and prompt added
vrrayz Mar 12, 2023
65604d3
textbox with label and button
vrrayz Mar 12, 2023
ab1ede2
Preview and Validate Modal plus code formatting
vrrayz Apr 8, 2023
bac9450
Preview and validate modal
vrrayz Apr 8, 2023
483dc25
Added custom modal size props
vrrayz Apr 12, 2023
060e06b
Preview and validate modal
vrrayz Apr 12, 2023
991e0c6
csv format validation
vrrayz Apr 12, 2023
4ef0893
Merge branch 'Joystream:dev' into issue-2365-fix
vrrayz Apr 14, 2023
bb366e1
Display destination payment
vrrayz Apr 18, 2023
c932d7f
Merge branch 'issue-2365-fix' of https://github.com/vrrayz/pioneer in…
vrrayz Apr 18, 2023
2c33f9f
Merge branch 'Joystream:dev' into issue-2365-fix
vrrayz Apr 30, 2023
57f575b
linting error fix
vrrayz Apr 30, 2023
937596c
linting error fix
vrrayz Apr 30, 2023
c856032
linting error fix
vrrayz Apr 30, 2023
f31fa65
linting error fix
vrrayz Apr 30, 2023
b5ae643
maximum accounts is 20 error
vrrayz Apr 30, 2023
f40b1ae
Merge branch 'Joystream:dev' into issue-2365-fix
vrrayz Jun 18, 2023
de994e0
validation for multiple funding request
vrrayz Jun 19, 2023
f94e907
refactored funding request validation for multiple
vrrayz Jun 19, 2023
9e4b20c
keyring for address verification on funding request
vrrayz Jun 19, 2023
d432b61
Merge branch 'dev' of https://github.com/vrrayz/pioneer into issue-23…
vrrayz Jun 19, 2023
0be3f57
Merge branch 'Joystream:dev' into issue-2365-fix
vrrayz Jun 19, 2023
f034e0d
preview before submit validation
vrrayz Jun 20, 2023
52e28b9
Merge branch 'issue-2365-fix' of https://github.com/vrrayz/pioneer in…
vrrayz Jun 20, 2023
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
26 changes: 24 additions & 2 deletions packages/ui/src/common/components/Modal/Modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,20 @@ interface ModalProps {
children: ReactNode
isDark?: boolean
className?: any
customModalSize?: any
marginRight?: any
}

export const Modal = ({ onClose, modalHeight = 'm', children, modalSize, isDark, className }: ModalProps) => {
export const Modal = ({
onClose,
modalHeight = 'm',
children,
modalSize,
isDark,
className,
customModalSize,
marginRight,
}: ModalProps) => {
function onBackgroundClick(e: React.MouseEvent<HTMLDivElement, MouseEvent>) {
if (e.target === e.currentTarget) {
onClose()
Expand All @@ -68,7 +79,14 @@ export const Modal = ({ onClose, modalHeight = 'm', children, modalSize, isDark,
return (
<>
<ModalGlass onClick={onBackgroundClick} />
<ModalWrap modalMaxSize={modalSize} modalHeight={modalHeight} isDark={isDark} role="modal" className={className}>
<ModalWrap
modalMaxSize={customModalSize || modalSize}
modalHeight={modalHeight}
isDark={isDark}
role="modal"
className={className}
marginRight={marginRight}
>
{children}
</ModalWrap>
</>
Expand Down Expand Up @@ -203,13 +221,15 @@ interface ModalWrapProps {
modalMaxSize: string
isDark?: boolean
modalHeight?: ModalHeight
marginRight?: string
}

export const ModalWrap = styled.section<ModalWrapProps>`
z-index: ${ZIndex.modal};
position: absolute;
inset: 0;
margin: auto auto;
margin-right: ${({ marginRight }) => (marginRight ? `${marginRight}px` : 'auto')};
display: grid;
@media only screen and (max-height: 700px) {
max-height: 100%;
Expand All @@ -233,6 +253,8 @@ export const ModalWrap = styled.section<ModalWrapProps>`
return '904px'
case 'l':
return '1240px'
default:
return `${modalMaxSize}px`
}
}};
height: ${({ modalHeight }) => (modalHeight === 'xl' ? '90vh' : 'min-content')};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import { TextMedium, TokenValue } from '@/common/components/typography'
import { BN_ZERO } from '@/common/constants'
import { camelCaseToText } from '@/common/helpers'
import { useCurrentBlockNumber } from '@/common/hooks/useCurrentBlockNumber'
import { useKeyring } from '@/common/hooks/useKeyring'
import { useLocalStorage } from '@/common/hooks/useLocalStorage'
import { useMachine } from '@/common/hooks/useMachine'
import { useModal } from '@/common/hooks/useModal'
Expand Down Expand Up @@ -87,6 +88,9 @@ export const AddNewProposalModal = () => {
const schema = useMemo(() => schemaFactory(api), [!api])

const path = useMemo(() => machineStateConverter(state.value), [state.value])

const keyring = useKeyring()

const form = useForm<AddNewProposalForm>({
resolver: useYupValidationResolver<AddNewProposalForm>(schema, path),
mode: 'onChange',
Expand All @@ -105,6 +109,7 @@ export const AddNewProposalModal = () => {
minTriggerBlock: currentBlock
? currentBlock.addn(constants?.votingPeriod ?? 0).addn(constants?.gracePeriod ?? 0)
: BN_ZERO,
keyring,
} as IStakingAccountSchema,
defaultValues: defaultProposalValues,
})
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,50 @@
import React from 'react'
import React, { useCallback, useState } from 'react'
import styled from 'styled-components'
import { useFormContext } from 'react-hook-form'

import { SelectAccount } from '@/accounts/components/SelectAccount'
import { CurrencyName } from '@/app/constants/currency'
import { InputComponent, TokenInput } from '@/common/components/forms'
import { ButtonPrimary } from '@/common/components/buttons'
import {
InlineToggleWrap,
InputComponent,
Label,
ToggleCheckbox,
TokenInput,
InputTextarea,
} from '@/common/components/forms'
import { Arrow } from '@/common/components/icons'
import { Row } from '@/common/components/Modal'
import { RowGapBlock } from '@/common/components/page/PageContent'
import { TextMedium } from '@/common/components/typography'
import { Tooltip, TooltipDefault } from '@/common/components/Tooltip'
import { TextMedium, TextSmall, TextInlineSmall } from '@/common/components/typography'

import { PreviewAndValidateModal } from './modals/PreviewAndValidate'
import { ErrorPrompt, Prompt } from './Prompt'

export const FundingRequest = () => {
const { watch, setValue } = useFormContext()
const [isPreviewModalShown, setIsPreviewModalShown] = useState(false)
const [previewModalData, setPreviewModalData] = useState<string[]>([])
const [isValidCSV, setIsValidCSV] = useState(true)
const [errorMessage, setErrorMessage] = useState<string>('')
const [payMultiple] = watch(['fundingRequest.payMultiple'])
const [hasPreviewedInput] = watch(['fundingRequest.hasPreviewedInput'],{'fundingRequest.hasPreviewedInput':true})
const [accountsAndAmounts] = watch(['fundingRequest.accountsAndAmounts'])
const verifyInput = useCallback((input: string) => {
const pattern = /^([^,:;]+),([^,:;]+)(;[^,:;]+,[^,:;]+)*;?$/;
setIsValidCSV(pattern.test(input))
setErrorMessage(!pattern.test(input)?'Not valid CSV format, use line breaks to split the rows.':'')
setValue('fundingRequest.hasPreviewedInput', false,{shouldValidate: true})
},[])
const previewInput = useCallback((input: string) => {
if(isValidCSV){
const inputSplit = input.split(';\n')
setValue('fundingRequest.hasPreviewedInput', true,{shouldValidate: true})
setIsPreviewModalShown(true)
setPreviewModalData(inputSplit)
}
},[])
return (
<RowGapBlock gap={24}>
<Row>
Expand All @@ -17,22 +54,100 @@ export const FundingRequest = () => {
</RowGapBlock>
</Row>
<Row>
<RowGapBlock gap={20}>
<InputComponent
label="Amount"
tight
units={CurrencyName.integerValue}
required
message="Amount must be greater than zero"
name="fundingRequest.amount"
>
<TokenInput id="amount-input" placeholder="0" name="fundingRequest.amount" />
</InputComponent>
<InputComponent label="Recipient account" required inputSize="l">
<SelectAccount name="fundingRequest.account" />
</InputComponent>
<RowGapBlock gap={payMultiple ? 6 : 24}>
<Row>
<InlineToggleWrap>
<Label>Pay multiple</Label>
<Tooltip
tooltipTitle="Pay multiple"
tooltipText="For multiple accounts and amounts, follow this CSV pattern:<br/>
account1, amount1<br/>
account2, amount2<br/>
...<br/>
account20, amount20"
>
<TooltipDefault />
</Tooltip>
</InlineToggleWrap>
<ToggleCheckbox falseLabel="No" trueLabel="Yes" name="fundingRequest.payMultiple" />
</Row>
{payMultiple && (
<Row>
<Prompt>
<TextSmall>
For <TextInlineSmall bold>multiple accounts and amounts</TextInlineSmall>, follow this CSV pattern:
<br />
account1, amount1
<br />
account2, amount2
<br />
...
<br />
account20, amount20
</TextSmall>
</Prompt>
</Row>
)}
</RowGapBlock>
</Row>
<Row>
{payMultiple ? (
<RowGapBlock gap={12}>
<InputComponent
label="Destination accounts and transfer amounts"
required
message={
isValidCSV
? 'You can select up to 20 recipients'
: errorMessage
}
name="fundingRequest.accountsAndAmounts"
id="accounts-amounts"
validation={isValidCSV ? undefined : 'invalid'}
inputSize="xl"
>
<InputTextarea
id="accounts-amounts"
name="fundingRequest.accountsAndAmounts"
placeholder="Destination account address and amount"
onInput={(event) => verifyInput(event.currentTarget.value)}
/>
</InputComponent>
<HiddenCheckBox name="fundingRequest.hasPreviewedInput" checked={hasPreviewedInput}/>
{!hasPreviewedInput && <ErrorPrompt>Please preview and validate the inputs to proceed</ErrorPrompt>}
<ButtonPrimary
size="medium"
onClick={() => previewInput(accountsAndAmounts)}
>
Preview and Validate <Arrow direction="right" />
</ButtonPrimary>
</RowGapBlock>
) : (
<RowGapBlock gap={20}>
<InputComponent
label="Amount"
tight
units={CurrencyName.integerValue}
required
message="Amount must be greater than zero"
name="fundingRequest.amount"
>
<TokenInput id="amount-input" placeholder="0" name="fundingRequest.amount" />
</InputComponent>
<InputComponent label="Recipient account" required inputSize="l">
<SelectAccount name="fundingRequest.account" />
</InputComponent>
</RowGapBlock>
)}
</Row>
{isPreviewModalShown && (
<PreviewAndValidateModal previewModalData={previewModalData} setIsPreviewModalShown={setIsPreviewModalShown} />
)}
</RowGapBlock>
)
}
const HiddenCheckBox = styled.input.attrs({ type: "checkbox" })`
margin-top: -12px;
height: 0px;
visibility: hidden;
`
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import React from 'react'
import styled from 'styled-components'

import { QuestionIcon } from '@/common/components/icons'
import { BorderRad, Colors } from '@/common/constants'

export interface PromptProps {
children: React.ReactNode
}

export const Prompt = ({ children }: PromptProps) => {
return (
<PromptContainer>
<IconSection>
<PromptQuestion>
<QuestionIcon />
</PromptQuestion>
</IconSection>
{children}
</PromptContainer>
)
}
const PromptContainer = styled.div`
display: grid;
grid-template-columns: 48px 1fr;
border-left: 4px solid ${Colors.Blue[200]};
color: ${Colors.Black[500]};
`
const IconSection = styled.div`
display: flex;
justify-content: center;
flex-direction: column;
align-items: center;
`
const PromptQuestion = styled.div`
display: flex;
position: relative;
justify-content: center;
align-items: center;
width: 16px;
height: 16px;
border-radius: ${BorderRad.full};
border: 1px solid ${Colors.Black[900]};
`
export const ErrorPrompt = styled.div`
display: flex;
justify-content: center;
flex-direction: column;
border-left: 4px solid ${Colors.Red[200]};
padding-left: 10.78px;
background-color: ${Colors.Red[50]};
color: ${Colors.Red[400]};
width: 504px;
height: 56px;
border-radius: 2px;
font-weight: 400;
`
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
// import { useModal } from '@/common/hooks/useModal'
import BN from 'bn.js'
import React, { useEffect, useState } from 'react'
import styled from 'styled-components'

import { AccountInfo } from '@/accounts/components/AccountInfo'
import { useMyAccounts } from '@/accounts/hooks/useMyAccounts'
import { accountOrNamed } from '@/accounts/model/accountOrNamed'
import { Account, AccountOption } from '@/accounts/types'
import { Close, CloseButton } from '@/common/components/buttons'
import {
AccountRow,
BalanceInfoInRow,
InfoTitle,
InfoValue,
Modal,
ModalBody,
ModalHeader,
} from '@/common/components/Modal'
import { TokenValue } from '@/common/components/typography'

interface PreviewAndValidateModalProps {
setIsPreviewModalShown: (bool: boolean) => void
previewModalData: string[]
}
interface AccountAndAmount {
account: Account
amount: BN
}

export const PreviewAndValidateModal = ({ setIsPreviewModalShown, previewModalData }: PreviewAndValidateModalProps) => {
const { allAccounts } = useMyAccounts()
const accounts = allAccounts as AccountOption[]
const [previewAccounts, setPreviewAccounts] = useState<AccountAndAmount[] | undefined>()

useEffect(() => {
setPreviewAccounts(
previewModalData.map((item) => {
const splitAccountsAndAmounts = item.split(',')
const amount: BN = new BN(splitAccountsAndAmounts[1].replace(';', ''))
return { account: accountOrNamed(accounts, splitAccountsAndAmounts[0], 'Unknown Member'), amount: amount }
})
)
}, [])
return (
<Modal onClose={() => undefined} modalSize="s" customModalSize={'552'} marginRight={'68'} modalHeight="xl">
<ModalHeader onClick={() => setIsPreviewModalShown(false)} title="Preview And Validate" />
<CustomModalBody>
{previewAccounts?.map((previewAccount, i) => (
<CustomAccountRow key={i}>
<AccountInfo account={previewAccount.account} />
<CustomBalanceInfoInRow>
<InfoTitle>Amount</InfoTitle>
<InfoValue>
<TokenValue value={previewAccount.amount} />
</InfoValue>
<CloseButton onClick={undefined} />
</CustomBalanceInfoInRow>
</CustomAccountRow>
))}
</CustomModalBody>
</Modal>
)
}
const CustomModalBody = styled(ModalBody)`
display: block;
`
const CustomAccountRow = styled(AccountRow)`
margin-bottom: 4px;
padding-right: 16px;
`
const CustomBalanceInfoInRow = styled(BalanceInfoInRow)`
grid-template-columns: 1fr 168px 72px;
${Close} {
margin-left: auto;
}
`
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './PreviewAndValidateModal'
Loading
Loading