Skip to content

Commit

Permalink
Add pool details section
Browse files Browse the repository at this point in the history
  • Loading branch information
kattylucy committed Nov 15, 2024
1 parent df6d996 commit c962a38
Show file tree
Hide file tree
Showing 10 changed files with 404 additions and 136 deletions.
195 changes: 195 additions & 0 deletions centrifuge-app/src/pages/IssuerCreatePool/PoolDetailsSection.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
import { PoolMetadataInput } from '@centrifuge/centrifuge-js'
import { Box, CurrencyInput, FileUpload, Grid, Select, Text, TextAreaInput, TextInput } from '@centrifuge/fabric'
import { Field, FieldProps, useFormikContext } from 'formik'
import { useTheme } from 'styled-components'
import { FieldWithErrorMessage } from '../../../src/components/FieldWithErrorMessage'
import { Tooltips } from '../../../src/components/Tooltips'
import { isTestEnv } from '../../../src/config'
import { StyledGrid } from './PoolStructureSection'
import { validate } from './validate'

export const Line = () => {
const theme = useTheme()
return <Box border={`.5px solid ${theme.colors.borderPrimary}`} width="100%" />
}

export const PoolDetailsSection = () => {
const theme = useTheme()

Check warning on line 17 in centrifuge-app/src/pages/IssuerCreatePool/PoolDetailsSection.tsx

View workflow job for this annotation

GitHub Actions / build-app

'theme' is assigned a value but never used

Check warning on line 17 in centrifuge-app/src/pages/IssuerCreatePool/PoolDetailsSection.tsx

View workflow job for this annotation

GitHub Actions / ff-prod / build-app

'theme' is assigned a value but never used
const form = useFormikContext<PoolMetadataInput>()

Check warning on line 18 in centrifuge-app/src/pages/IssuerCreatePool/PoolDetailsSection.tsx

View workflow job for this annotation

GitHub Actions / build-app

'form' is assigned a value but never used

Check warning on line 18 in centrifuge-app/src/pages/IssuerCreatePool/PoolDetailsSection.tsx

View workflow job for this annotation

GitHub Actions / ff-prod / build-app

'form' is assigned a value but never used
const createLabel = (label: string) => `${label}${isTestEnv ? '' : '*'}`

Check warning on line 19 in centrifuge-app/src/pages/IssuerCreatePool/PoolDetailsSection.tsx

View workflow job for this annotation

GitHub Actions / build-app

'createLabel' is assigned a value but never used

Check warning on line 19 in centrifuge-app/src/pages/IssuerCreatePool/PoolDetailsSection.tsx

View workflow job for this annotation

GitHub Actions / ff-prod / build-app

'createLabel' is assigned a value but never used

return (
<Box>
<Text variant="heading2" fontWeight={700}>
Pool Details
</Text>
<StyledGrid gridTemplateColumns={['1fr', '1fr 1fr']} gap={3} mt={2}>
<Grid gap={2}>
<FieldWithErrorMessage
validate={validate.poolName}
name="poolName"
as={TextInput}
label="Pool name*"
placeholder="Type here..."
maxLength={100}
/>
<Field name="poolIcon" validate={validate.poolIcon}>
{({ field, meta, form }: FieldProps) => (
<FileUpload
name="poolIcon"
file={field.value}
onFileChange={async (file) => {
form.setFieldTouched('poolIcon', true, false)
form.setFieldValue('poolIcon', file)
}}
label="Pool icon*"
errorMessage={meta.touched && meta.error ? meta.error : undefined}
accept="image/svg+xml"
fileTypeText="SVG (in square size)"
/>
)}
</Field>
</Grid>
<Grid gap={2}>
<Field name="investorType" validate={validate.investorType}>
{({ field, meta, form }: FieldProps) => (
<FieldWithErrorMessage
name="investorType"
label={
<Tooltips type="investorType" label={<Text variant="heading4">Investor type*</Text>} size="sm" />
}
onChange={(event: any) => form.setFieldValue('investorType', event.target.value)}
onBlur={field.onBlur}
errorMessage={meta.touched && meta.error ? meta.error : undefined}
value={field.value}
as={TextInput}
placeholder="Type here..."
/>
)}
</Field>
<Field name="maxReserve" validate={validate.maxReserve}>
{({ field, form }: FieldProps) => (
<CurrencyInput
{...field}
name="maxReserve"
label="Initial maximum reserve*"
placeholder="0"
currency={form.values.currency}
onChange={(value) => form.setFieldValue('maxReserve', value)}
/>
)}
</Field>
<Field name="poolType" validate={validate.poolType}>
{({ field, form, meta }: FieldProps) => (
<Select
name="poolType"
label={<Tooltips type="poolType" size="sm" label={<Text variant="heading4">Pool type*</Text>} />}
onChange={(event) => form.setFieldValue('poolType', event.target.value)}
onBlur={field.onBlur}
errorMessage={meta.touched && meta.error ? meta.error : undefined}
value={field.value}
options={[
{ label: 'Open', value: 'open' },
{ label: 'Closed', value: 'closed' },
]}
placeholder="Select..."
/>
)}
</Field>
</Grid>
</StyledGrid>

<Box mt={4} mb={3}>
<Text>Issuer</Text>
<StyledGrid gridTemplateColumns={['1fr', '1fr 1fr']} gap={3} mt={3}>
<Grid gap={2}>
<Field name="issuerName" validate={validate.issuerName}>
{({ field, meta, form }: FieldProps) => (
<FieldWithErrorMessage
name="issuerName"
label={
<Tooltips type="issuerName" label={<Text variant="heading4">Legal name of the issuer*</Text>} />
}
onChange={(event: any) => form.setFieldValue('issuerName', event.target.value)}
onBlur={field.onBlur}
errorMessage={meta.touched && meta.error ? meta.error : undefined}
value={field.value}
as={TextInput}
placeholder="Type here..."
maxLength={100}
/>
)}
</Field>
<Field name="issuerLogo" validate={validate.issuerLogo}>
{({ field, meta, form }: FieldProps) => (
<FileUpload
file={field.value}
onFileChange={(file) => {
form.setFieldTouched('issuerLogo', true, false)
form.setFieldValue('issuerLogo', file)
}}
accept="image/*"
fileTypeText="SVG, PNG, or JPG (max. 1MB; 480x480px)"
label="Issuer logo"
/>
)}
</Field>
</Grid>
<Grid gap={2}>
<Field name="issuerRepName" validate={validate.issuerName}>
{({ field, meta, form }: FieldProps) => (
<FieldWithErrorMessage
name="issuerRepName"
label={
<Tooltips
type="issuerRepName"
label={<Text variant="heading4">Legal name of the issuer representative</Text>}
/>
}
onChange={(event: any) => form.setFieldValue('issuerRepName', event.target.value)}
onBlur={field.onBlur}
errorMessage={meta.touched && meta.error ? meta.error : undefined}
value={field.value}
as={TextInput}
placeholder="Type here..."
maxLength={100}
/>
)}
</Field>
<Field name="issuerShortDescription" validate={!isTestEnv && validate.issuerShortDescription}>
{({ field, meta, form }: FieldProps) => (
<FieldWithErrorMessage
name="issuerShortDescription"
label="Landing page description (max 100 characters)*"
onChange={(event: any) => form.setFieldValue('issuerShortDescription', event.target.value)}
onBlur={field.onBlur}
errorMessage={meta.touched && meta.error ? meta.error : undefined}
value={field.value}
as={TextAreaInput}
placeholder="Type here..."
maxLength={100}
/>
)}
</Field>
</Grid>
<Box gridColumn="span 2">
<Field name="issuerShortDescription" validate={!isTestEnv && validate.issuerDescription}>
{({ field, meta, form }: FieldProps) => (
<FieldWithErrorMessage
validate={!isTestEnv && validate.issuerDescription}
name="issuerDescription"
as={TextAreaInput}
label="Overview page description (max. 3000 characters)*"
placeholder="Type here..."
maxLength={1000}
errorMessage={meta.touched && meta.error ? meta.error : undefined}
// disabled={waitingForStoredIssuer}
/>
)}
</Field>
</Box>
</StyledGrid>
</Box>
</Box>
)
}
49 changes: 23 additions & 26 deletions centrifuge-app/src/pages/IssuerCreatePool/PoolStructureSection.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { PoolMetadataInput } from '@centrifuge/centrifuge-js'
import {
Box,
Button,
Checkbox,
CurrencyInput,
Grid,
Expand All @@ -12,6 +11,7 @@ import {
TextInput,
} from '@centrifuge/fabric'
import { Field, FieldProps, useFormikContext } from 'formik'
import * as React from 'react'
import styled, { useTheme } from 'styled-components'
import { FieldWithErrorMessage } from '../../../src/components/FieldWithErrorMessage'
import { Tooltips, tooltipText } from '../../../src/components/Tooltips'
Expand All @@ -32,16 +32,15 @@ export const StyledGrid = styled(Grid)`
padding: 40px;
border: ${({ theme }) => `1px solid ${theme.colors.borderPrimary}`};
border-radius: 8px;
gap: 24px;
@media (max-width: ${({ theme }) => theme.breakpoints.S}) {
padding: 12px;
}
`

export const StyledBox = styled(StyledGrid)``

const Line = () => {
export const Line = () => {
const theme = useTheme()
return <Box border={`.5px solid ${theme.colors.borderPrimary}`} width="100%" mt={2} mb={2} />
return <Box border={`.5px solid ${theme.colors.borderPrimary}`} width="100%" />
}

const ASSET_CLASSES = Object.keys(config.assetClasses).map((key) => ({
Expand All @@ -57,6 +56,7 @@ const CheckboxOption = ({
icon,
sublabel,
id,
height,
}: {
name: string
label: string
Expand All @@ -65,8 +65,10 @@ const CheckboxOption = ({
disabled?: boolean
icon?: React.ReactNode
id?: keyof typeof tooltipText
height?: number
}) => {
const theme = useTheme()

return (
<Box
backgroundColor="white"
Expand All @@ -76,8 +78,8 @@ const CheckboxOption = ({
border={`1px solid ${theme.colors.borderPrimary}`}
display="flex"
flexDirection={icon ? 'row' : 'column'}
justifyContent={icon ? 'space-between' : 'flex-start'}
height={icon ? 64 : null}
justifyContent={icon ? 'space-between' : 'center'}
height={height || 70}
alignItems={icon ? 'center' : 'flex-start'}
>
<Field name={name} validate={validate[name]}>
Expand Down Expand Up @@ -109,8 +111,6 @@ export const PoolStructureSection = () => {
const form = useFormikContext<PoolMetadataInput>()
const { values } = form

console.log(values)

const subAssetClasses =
config.assetClasses[form.values.assetClass]?.map((label) => ({
label,
Expand Down Expand Up @@ -142,16 +142,18 @@ export const PoolStructureSection = () => {
<Text variant="heading2" fontWeight={700}>
Pool Structure
</Text>
<StyledGrid gridTemplateColumns={['1fr', '1fr 1fr']} gap={3} mt={2}>
<StyledGrid gridTemplateColumns={['1fr', '1fr', '1fr 1fr']} gap={3} mt={2}>
<Box>
<Text variant="body2">Pool type *</Text>
<CheckboxOption
height={113}
name="poolStructure"
label="Revolving pool"
value="revolving"
sublabel="Dynamic and flexible pools that allow continuous inflows and outflows of assets. Investors can add or withdraw funds at any time, and the pool remains active indefinitely."
/>
<CheckboxOption
height={113}
name="poolStructure"
label="Static pool (coming soon)"
value="static"
Expand Down Expand Up @@ -255,7 +257,7 @@ export const PoolStructureSection = () => {
<Box mt={4} mb={3}>
<Text>Tranches</Text>
{Array.from({ length: values.trancheStructure }).map((_, index) => (
<StyledBox key={index} mt={3}>
<StyledGrid key={index} mt={3}>
<Text variant="heading3">Tranche {index + 1}</Text>
<Line />
<Grid gridTemplateColumns={['1fr', '1fr 1fr']} gap={3}>
Expand Down Expand Up @@ -292,6 +294,7 @@ export const PoolStructureSection = () => {
</Field>
</Box>
</Box>

<Box>
<Field name={`tranches.${index}.symbolName`} validate={validate.symbolName}>
{({ field, form, meta }: FieldProps) => (
Expand All @@ -303,18 +306,18 @@ export const PoolStructureSection = () => {
placeholder="4-12 characters"
minLength={4}
maxLength={12}
// disabled={isUpdating}
/>
)}
</Field>

<Box mt={3}>
{index === 0 ? (
<Grid gridTemplateColumns={['1fr', '1fr 1fr']} gap={3}>
<Field name={`tranches.${index}.apy`} validate={validate.subAssetClass}>
<Field name={`tranches.${index}.apy`} validate={validate.apy}>
{({ field, meta, form }: FieldProps) => (
<Select
label={<Tooltips type="apy" label={<Text variant="heading4">APY</Text>} />}
onChange={(event) => form.setFieldValue('subAssetClass', event.target.value)}
onChange={(event) => form.setFieldValue('apy', event.target.value)}
onBlur={field.onBlur}
errorMessage={meta.touched && meta.error ? meta.error : undefined}
value={field.value}
Expand All @@ -328,7 +331,7 @@ export const PoolStructureSection = () => {
as={NumberInput}
placeholder="0.00"
symbol="%"
name={`tranches.${index}.apy`}
name={`tranches.${index}.interestRate`}
validate={validate.interestRate}
/>
</Box>
Expand All @@ -347,10 +350,11 @@ export const PoolStructureSection = () => {
)}
</Box>
</Box>
{index === 1 || index === 2 ? (

{(index === 1 || index === 2) && (
<>
<Box>
<Field name={`tranches.${index}.minInvestment`} validate={validate.minInvestment}>
<Field name={`tranches.${index}.interestRate`} validate={validate.interestRate}>
{({ field, form, meta }: FieldProps) => (
<CurrencyInput
{...field}
Expand Down Expand Up @@ -392,18 +396,11 @@ export const PoolStructureSection = () => {
</Field>
</Box>
</>
) : null}
)}
</Grid>
</StyledBox>
</StyledGrid>
))}
</Box>
<Box />
<Line />
<Box display="flex" justifyContent="flex-end" pt={2} pb={4}>
<Button style={{ width: 163 }} small>
Next
</Button>
</Box>
</Box>
)
}
Loading

0 comments on commit c962a38

Please sign in to comment.