From 5b0b723ba9a750acbb4804a2f238242d66292379 Mon Sep 17 00:00:00 2001 From: katty barroso Date: Tue, 12 Nov 2024 14:30:38 +0100 Subject: [PATCH] Add pool structure --- centrifuge-app/src/components/Tooltips.tsx | 12 + .../IssuerCreatePool/PoolStructureSection.tsx | 206 ++++++++++++++++-- .../src/pages/IssuerCreatePool/types.tsx | 19 +- centrifuge-js/src/modules/pools.ts | 12 +- fabric/src/theme/tokens/colors.ts | 2 +- fabric/src/theme/tokens/theme.ts | 2 +- 6 files changed, 223 insertions(+), 30 deletions(-) diff --git a/centrifuge-app/src/components/Tooltips.tsx b/centrifuge-app/src/components/Tooltips.tsx index 67c170adbe..c7bc13c28b 100644 --- a/centrifuge-app/src/components/Tooltips.tsx +++ b/centrifuge-app/src/components/Tooltips.tsx @@ -346,6 +346,18 @@ export const tooltipText = { label: 'Total NAV', body: 'Total nav minus accrued fees', }, + oneTranche: { + label: '', + body: 'This pool will only have one investment class where all investors share the same level of risk and return.', + }, + twoTranches: { + label: '', + body: 'This pool will have two classes. Senior tranche which has priority in receiving returns. And Junior tranche which is the last to receive returns (after Senior tranche obligations are met) but receives higher yield as compensation for the higher risk.', + }, + threeTranches: { + label: '', + body: 'This pool will have three classes. Senior tranche is the safest tranche with priority in repayment. Mezzanine tranche has intermediate risk and receives payment after Senior tranche obligations are met. Junior tranche which only receives returns after both Senior and Mezzanine tranches are paid.', + }, } export type TooltipsProps = { diff --git a/centrifuge-app/src/pages/IssuerCreatePool/PoolStructureSection.tsx b/centrifuge-app/src/pages/IssuerCreatePool/PoolStructureSection.tsx index 3aa1edf26c..37d67d81ba 100644 --- a/centrifuge-app/src/pages/IssuerCreatePool/PoolStructureSection.tsx +++ b/centrifuge-app/src/pages/IssuerCreatePool/PoolStructureSection.tsx @@ -1,8 +1,25 @@ -import { Box, Checkbox, Grid, IconHelpCircle, Text } from '@centrifuge/fabric' -import { Field, FieldProps } from 'formik' -import { useTheme } from 'styled-components' +import { PoolMetadataInput } from '@centrifuge/centrifuge-js' +import { Box, Checkbox, CurrencyInput, Grid, IconHelpCircle, Select, Text, TextInput } from '@centrifuge/fabric' +import { Field, FieldProps, useFormikContext } from 'formik' +import styled, { useTheme } from 'styled-components' +import { Tooltips, tooltipText } from '../../../src/components/Tooltips' +import { config } from '../../config' import { validate } from './validate' +export const StyledGrid = styled(Grid)` + background-color: ${({ theme }) => theme.colors.backgroundSecondary}; + padding: 40px; + border: ${({ theme }) => `1px solid ${theme.colors.borderPrimary}`}; + border-radius: 8px; +` + +export const StyledBox = styled(StyledGrid)`` + +const ASSET_CLASSES = Object.keys(config.assetClasses).map((key) => ({ + label: key, + value: key, +})) + const CheckboxOption = ({ name, label, @@ -10,6 +27,7 @@ const CheckboxOption = ({ disabled = false, icon, sublabel, + id, }: { name: string label: string @@ -17,6 +35,7 @@ const CheckboxOption = ({ value: string | number disabled?: boolean icon?: React.ReactNode + id?: keyof typeof tooltipText }) => { const theme = useTheme() return ( @@ -47,7 +66,7 @@ const CheckboxOption = ({ /> )} - {icon && {icon}} + {icon && {icon}} />} {sublabel && ( {sublabel} @@ -59,31 +78,51 @@ const CheckboxOption = ({ export const PoolStructureSection = () => { const theme = useTheme() + const form = useFormikContext() + const { values } = form + + console.log(values) + + const subAssetClasses = + config.assetClasses[form.values.assetClass]?.map((label) => ({ + label, + value: label, + })) ?? [] + + const getTrancheName = (index: number) => { + switch (index) { + case 0: + return 'Junior' + case 1: + return values.tranches.length === 2 ? 'Senior' : 'Mezzanine' + case 2: + return 'Senior' + default: + return '' + } + } + + const handleTrancheNameChange = (e: React.ChangeEvent, index: number, form: any) => { + const newValue = e.target.value + const poolName = values.poolName + const suffix = newValue.startsWith(poolName) ? newValue.substring(poolName.length).trim() : newValue + form.setFieldValue(`tranches.${index}.tokenName`, `${poolName} ${suffix}`) + } return (
Pool Structure - + Pool type * - - { sublabel="Fixed pool of assets where funds remain locked. There are no continuous inflows or outflows during the investment period, and the pool has a defined maturity date." /> - Define tranche structure * - } /> - } /> - } /> - + + + Asset setup + + + + {({ field, meta, form }: FieldProps) => ( + Asset denomination*} />} + onChange={(event) => form.setFieldValue('assetDenomination', event.target.value)} + onBlur={field.onBlur} + errorMessage={meta.touched && meta.error ? meta.error : undefined} + value={field.value} + options={[ + { value: 'usdc', label: 'USDC' }, + { value: 'usdt', label: 'USDT (coming soon)', disabled: true }, + { value: 'dai', label: 'DAI (coming soon)', disabled: true }, + ]} + placeholder="Select..." + /> + ) + }} + + + + + + {({ field, meta, form }: FieldProps) => ( +