diff --git a/centrifuge-app/src/components/IssuerSection.tsx b/centrifuge-app/src/components/IssuerSection.tsx index 260f434a0..dcd8fd446 100644 --- a/centrifuge-app/src/components/IssuerSection.tsx +++ b/centrifuge-app/src/components/IssuerSection.tsx @@ -1,85 +1,133 @@ import { PoolMetadata } from '@centrifuge/centrifuge-js' import { useCentrifuge } from '@centrifuge/centrifuge-react' -import { Accordion, AnchorButton, Box, IconExternalLink, Shelf, Text } from '@centrifuge/fabric' +import { + Box, + IconBalanceSheet, + IconCashflow, + IconChevronRight, + IconProfitAndLoss, + Shelf, + Stack, + Text, +} from '@centrifuge/fabric' import * as React from 'react' import { useLocation } from 'react-router' +import styled from 'styled-components' import { ExecutiveSummaryDialog } from './Dialogs/ExecutiveSummaryDialog' -import { LabelValueStack } from './LabelValueStack' -import { PillButton } from './PillButton' -import { AnchorTextLink, RouterTextLink } from './TextLink' +import { AnchorPillButton, PillButton } from './PillButton' +import { RouterTextLink } from './TextLink' + +const SUBTLE_GRAY = '#91969b21' type IssuerSectionProps = { metadata: Partial | undefined } const reportLinks = [ - { label: 'Balance sheet', href: '/balance-sheet' }, - { label: 'Profit & loss', href: '/profit-and-loss' }, - { label: 'Cashflow statement', href: '/cash-flow-statement' }, - { label: 'View all', href: '/' }, + { label: 'Balance sheet', href: '/balance-sheet', icon: }, + { label: 'Profit & loss', href: '/profit-and-loss', icon: }, + { label: 'Cashflow statement', href: '/cash-flow-statement', icon: }, ] +const StyledRouterTextLink = styled(RouterTextLink)` + color: white; + text-decoration: unset; + font-size: 14px; + :active { + color: white; + } + :visited { + color: white; + } +` + export function ReportDetails({ metadata }: IssuerSectionProps) { const cent = useCentrifuge() const { pathname } = useLocation() const report = metadata?.pool?.reports?.[0] return ( - - - - - {reportLinks.map((link, i) => ( - - {link.label} - - ))} - - - } - /> - - {report && ( + <> + + + Reports + + + View all + + + + + {reportLinks.map((link, i) => ( + + + {link.icon} + + {link.label} + + + + + ))} + + + {report?.author.name && report.author.title && ( <> - + Pool analysis - {report.author.avatar?.uri && ( - - )} - + Reviewer: {report.author.name}
{report.author.title}
- - - View full report - - )} -
+ ) } export function IssuerDetails({ metadata }: IssuerSectionProps) { const cent = useCentrifuge() const [isDialogOpen, setIsDialogOpen] = React.useState(false) + + const links = [ + { + label: 'Website', + href: metadata?.pool?.links.website, + show: !!metadata?.pool?.links.website, + }, + { + label: 'Forum', + href: metadata?.pool?.links.forum, + show: !!metadata?.pool?.links.forum, + }, + { + label: 'Email', + href: `mailto:${metadata?.pool?.issuer.email}`, + show: !!metadata?.pool?.issuer.email, + }, + { + label: 'Executive Summary', + show: !!metadata?.pool?.links.executiveSummary, + onClick: () => setIsDialogOpen(true), + }, + ] return ( - <> - + + {metadata?.pool?.issuer.logo && ( )} - {metadata?.pool?.issuer.name} + - {metadata?.pool?.issuer.description} + + {metadata?.pool?.name} + + {metadata?.pool?.issuer.description} + + + setIsDialogOpen(false)} + /> + + ) +} - {metadata?.pool?.links.executiveSummary && ( - - setIsDialogOpen(true)}> - Executive summary - - setIsDialogOpen(false)} - /> - - } - /> - )} +const Links = ({ links }: { links: { label: string; href?: string; show: boolean; onClick?: () => void }[] }) => { + return ( + + {links.map((link, index) => { + if (!link.show) return null - {(metadata?.pool?.links.website || metadata?.pool?.links.forum || metadata?.pool?.issuer.email) && ( - - - {metadata?.pool?.links.website && ( - Website - )} - {metadata?.pool?.links.forum && ( - Forum - )} - {metadata?.pool?.issuer.email && ( - Email - )} - - - } - /> - )} - {!!metadata?.pool?.details?.length && ( - } /> - )} - + if (link.onClick) { + return ( + + {link.label} + + ) + } + + return ( + + {link.label} + + ) + })} + ) } diff --git a/centrifuge-app/src/components/PillButton.tsx b/centrifuge-app/src/components/PillButton.tsx index 48bf81d31..cea7e31c8 100644 --- a/centrifuge-app/src/components/PillButton.tsx +++ b/centrifuge-app/src/components/PillButton.tsx @@ -8,24 +8,25 @@ const Pill = styled.button<{ variant?: 'small' | 'regular' }>( css({ display: 'inline-block', appearance: 'none', - border: 0, color: 'textPrimary', whiteSpace: 'nowrap', cursor: 'pointer', backgroundColor: 'backgroundSecondary', textDecoration: 'none', - '&:visited,&:active': { + borderRadius: 20, + '&:visited, &:active': { color: 'textPrimary', }, '&:hover': { - color: 'textSelected', + color: 'textGold', }, }), - { + ({ theme }) => ({ + border: `1px solid ${theme.colors.textPrimary}`, '&:focus-visible': { boxShadow: '3px 3px 0 var(--fabric-focus)', }, - }, + }), ({ variant }) => variant === 'regular' ? css({ diff --git a/centrifuge-app/src/components/PoolOverview/PoolStructure.tsx b/centrifuge-app/src/components/PoolOverview/PoolStructure.tsx deleted file mode 100644 index cb7906212..000000000 --- a/centrifuge-app/src/components/PoolOverview/PoolStructure.tsx +++ /dev/null @@ -1,102 +0,0 @@ -import { Rate } from '@centrifuge/centrifuge-js' -import { Box, Card, Grid, Stack, Text, Tooltip } from '@centrifuge/fabric' -import capitalize from 'lodash/capitalize' -import { formatPercentage } from '../../utils/formatting' - -type Props = { - numOfTranches: number - poolId: string - poolStatus?: string - poolFees: { - fee: Rate - name: string - id: number - }[] -} - -export const PoolStructure = ({ numOfTranches, poolStatus, poolFees }: Props) => { - const metrics = [ - { - metric: 'Pool type', - value: capitalize(poolStatus), - }, - { - metric: 'Pool structure', - value: 'Revolving pool', - }, - { - metric: 'Tranche structure', - value: numOfTranches === 1 ? 'Unitranche' : `${numOfTranches} tranches`, - }, - ...poolFees.map((fee) => { - return { - metric: fee.name, - value: formatPercentage(fee.fee.toPercent(), true, {}, 3), - } - }), - ] - - const getValue = (metric: string, value: string) => { - if (metric === 'Pool structure') - return ( - - - {value} - - - ) - if (metric === 'Tranche structure') - return ( - - - {value} - - - ) - - if (metric === 'Pool type' && value === 'Open') - return ( - - - Open - - - ) - return ( - - {value} - - ) - } - - return ( - - - - Structure - - - {metrics.map(({ metric, value }, index) => ( - - - {metric} - - {getValue(metric, value)} - - ))} - - - - ) -} diff --git a/centrifuge-app/src/pages/Pool/Overview/index.tsx b/centrifuge-app/src/pages/Pool/Overview/index.tsx index 4c4497de8..1105e9474 100644 --- a/centrifuge-app/src/pages/Pool/Overview/index.tsx +++ b/centrifuge-app/src/pages/Pool/Overview/index.tsx @@ -1,5 +1,5 @@ -import { CurrencyBalance, Price, Rate } from '@centrifuge/centrifuge-js' -import { Box, Button, Card, Grid, IconFileText, Stack, Text, TextWithPlaceholder } from '@centrifuge/fabric' +import { CurrencyBalance, Price } from '@centrifuge/centrifuge-js' +import { Box, Button, Card, Grid, TextWithPlaceholder } from '@centrifuge/fabric' import Decimal from 'decimal.js-light' import * as React from 'react' import { useParams } from 'react-router' @@ -9,10 +9,8 @@ import { InvestRedeemDrawer } from '../../../components/InvestRedeem/InvestRedee import { IssuerDetails, ReportDetails } from '../../../components/IssuerSection' import { LayoutSection } from '../../../components/LayoutBase/LayoutSection' import { LoadBoundary } from '../../../components/LoadBoundary' -import { Cashflows } from '../../../components/PoolOverview/Cashflows' import { KeyMetrics } from '../../../components/PoolOverview/KeyMetrics' import { PoolPerformance } from '../../../components/PoolOverview/PoolPerfomance' -import { PoolStructure } from '../../../components/PoolOverview/PoolStructure' import { TrancheTokenCards } from '../../../components/PoolOverview/TrancheTokenCards' import { TransactionHistory } from '../../../components/PoolOverview/TransactionHistory' import { Spinner } from '../../../components/Spinner' @@ -142,70 +140,23 @@ export function PoolDetailOverview() { )} }> - {metadata?.pool?.reports?.length || !isTinlakePool ? ( - - - - - - - Reports - - - - - - Issuer details - - - - - ) : null} - {isTinlakePool && ( - - - Issuer details - - + + + - )} + {metadata?.pool?.reports?.length || !isTinlakePool ? ( + + + + ) : null} + {!isTinlakePool && ( - <> - - }> - { - return { - fee: poolFees?.find((f) => f.id === fee.id)?.amounts.percentOfNav ?? Rate.fromFloat(0), - name: fee.name, - id: fee.id, - } - }) || [] - } - /> - - {/* }> - - */} - - {isMedium && ( - }> - - - - - )} - }> - - - - - + }> + + + + )} diff --git a/fabric/src/icon-svg/IconBalanceSheet.svg b/fabric/src/icon-svg/IconBalanceSheet.svg new file mode 100644 index 000000000..89a2407fc --- /dev/null +++ b/fabric/src/icon-svg/IconBalanceSheet.svg @@ -0,0 +1,3 @@ + + + diff --git a/fabric/src/icon-svg/IconCashflow.svg b/fabric/src/icon-svg/IconCashflow.svg new file mode 100644 index 000000000..798a162bc --- /dev/null +++ b/fabric/src/icon-svg/IconCashflow.svg @@ -0,0 +1,3 @@ + + + diff --git a/fabric/src/icon-svg/IconProfitAndLoss.svg b/fabric/src/icon-svg/IconProfitAndLoss.svg new file mode 100644 index 000000000..5223d3810 --- /dev/null +++ b/fabric/src/icon-svg/IconProfitAndLoss.svg @@ -0,0 +1,3 @@ + + + diff --git a/fabric/src/theme/tokens/theme.ts b/fabric/src/theme/tokens/theme.ts index b0a317de6..4062c1b4b 100644 --- a/fabric/src/theme/tokens/theme.ts +++ b/fabric/src/theme/tokens/theme.ts @@ -1,4 +1,4 @@ -import { black, blackScale, blueScale, centrifugeBlue, gold, grayScale, yellowScale } from './colors' +import { black, blackScale, blueScale, gold, grayScale, yellowScale } from './colors' const statusDefault = grayScale[800] const statusInfo = blueScale[500] @@ -86,11 +86,11 @@ const colors = { backgroundButtonTertiaryHover: 'tranparent', backgroundButtonTertiaryPressed: 'transparent', backgroundButtonTertiaryDisabled: 'transparent', - textButtonTertiary: centrifugeBlue, - textButtonTertiaryFocus: centrifugeBlue, - textButtonTertiaryHover: grayScale[800], - textButtonTertiaryPressed: centrifugeBlue, - textButtonTertiaryDisabled: grayScale[500], + textButtonTertiary: grayScale[800], + textButtonTertiaryFocus: gold, + textButtonTertiaryHover: gold, + textButtonTertiaryPressed: gold, + textButtonTertiaryDisabled: gold, borderButtonTertiary: 'transparent', borderButtonTertiaryFocus: 'transparent', borderButtonTertiaryHover: 'transparent',