diff --git a/centrifuge-app/src/components/IssuerSection.tsx b/centrifuge-app/src/components/IssuerSection.tsx
index 1388461e0..b5238987d 100644
--- a/centrifuge-app/src/components/IssuerSection.tsx
+++ b/centrifuge-app/src/components/IssuerSection.tsx
@@ -28,9 +28,9 @@ type IssuerSectionProps = {
}
const reportLinks = [
- { label: 'Balance sheet', href: '/balance-sheet', icon: },
- { label: 'Profit & loss', href: '/profit-and-loss', icon: },
- { label: 'Cashflow statement', href: '/cash-flow-statement', icon: },
+ { 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)`
@@ -78,7 +78,7 @@ export function ReportDetails({ metadata }: IssuerSectionProps) {
{link.label}
-
+
))}
diff --git a/centrifuge-app/src/components/Report/DataFilter.tsx b/centrifuge-app/src/components/Report/DataFilter.tsx
new file mode 100644
index 000000000..c856ad847
--- /dev/null
+++ b/centrifuge-app/src/components/Report/DataFilter.tsx
@@ -0,0 +1,385 @@
+import { Loan, Pool } from '@centrifuge/centrifuge-js'
+import { useGetNetworkName } from '@centrifuge/centrifuge-react'
+import {
+ AnchorButton,
+ Box,
+ Button,
+ DateInput,
+ IconBalanceSheet,
+ IconCashflow,
+ IconDownload,
+ IconProfitAndLoss,
+ SearchInput,
+ Select,
+ Shelf,
+} from '@centrifuge/fabric'
+import * as React from 'react'
+import { useNavigate } from 'react-router'
+import { nftMetadataSchema } from '../../schemas'
+import { useBasePath } from '../../utils/useBasePath'
+import { useActiveDomains } from '../../utils/useLiquidityPools'
+import { useLoans } from '../../utils/useLoans'
+import { useMetadata } from '../../utils/useMetadata'
+import { useCentNFT } from '../../utils/useNFTs'
+import { useDebugFlags } from '../DebugFlags'
+import { GroupBy, Report, ReportContext } from './ReportContext'
+import { formatPoolFeeTransactionType } from './utils'
+
+type ReportFilterProps = {
+ pool: Pool
+}
+
+export function ReportFilter({ pool }: ReportFilterProps) {
+ const {
+ csvData,
+ setStartDate,
+ startDate,
+ endDate,
+ setEndDate,
+ report,
+ loanStatus,
+ setLoanStatus,
+ txType,
+ setTxType,
+ groupBy,
+ setGroupBy,
+ activeTranche,
+ setActiveTranche,
+ address,
+ setAddress,
+ network,
+ setNetwork,
+ loan,
+ setLoan,
+ } = React.useContext(ReportContext)
+ const navigate = useNavigate()
+ const basePath = useBasePath()
+
+ const { data: domains } = useActiveDomains(pool.id)
+ const getNetworkName = useGetNetworkName()
+ const loans = useLoans(pool.id) as Loan[] | undefined
+
+ const { showOracleTx } = useDebugFlags()
+
+ const reportOptions: { label: string; value: Report }[] = [
+ { label: 'Balance sheet', value: 'balance-sheet' },
+ { label: 'Profit & loss', value: 'profit-and-loss' },
+ { label: 'Cash flow statement', value: 'cash-flow-statement' },
+ { label: 'Investor transactions', value: 'investor-tx' },
+ { label: 'Asset transactions', value: 'asset-tx' },
+ { label: 'Fee transactions', value: 'fee-tx' },
+ ...(showOracleTx === true ? [{ label: 'Oracle transactions', value: 'oracle-tx' as Report }] : []),
+ // { label: 'Pool balance', value: 'pool-balance' },
+ { label: 'Token price', value: 'token-price' },
+ { label: 'Asset list', value: 'asset-list' },
+ { label: 'Investor list', value: 'investor-list' },
+ ]
+
+ return (
+
+ }
+ onClick={() => navigate(`${basePath}/${pool.id}/reporting/balance-sheet`)}
+ >
+ Balance sheet
+
+ }
+ onClick={() => navigate(`${basePath}/${pool.id}/reporting/profit-and-loss`)}
+ >
+ Profit & loss
+
+ }
+ onClick={() => navigate(`${basePath}/${pool.id}/reporting/cash-flow-statement`)}
+ >
+ Cash flow
+
+
+ {!['investor-list', 'asset-list', 'balance-sheet', 'cash-flow-statement', 'profit-and-loss'].includes(report) && (
+ <>
+ setStartDate(e.target.value)} />
+ setEndDate(e.target.value)} />
+ >
+ )}
+
+ {['pool-balance', 'token-price'].includes(report) && (
+
+ )
+}
+
+function LoanOption({ loan }: { loan: Loan }) {
+ const nft = useCentNFT(loan.asset.collectionId, loan.asset.nftId, false, false)
+ const { data: metadata } = useMetadata(nft?.metadataUri, nftMetadataSchema)
+ return (
+
+ )
+}
diff --git a/centrifuge-app/src/components/Report/ReportFilter.tsx b/centrifuge-app/src/components/Report/ReportFilter.tsx
index 72193d630..3ed858089 100644
--- a/centrifuge-app/src/components/Report/ReportFilter.tsx
+++ b/centrifuge-app/src/components/Report/ReportFilter.tsx
@@ -1,197 +1,96 @@
-import { Loan, Pool } from '@centrifuge/centrifuge-js'
-import { useGetNetworkName } from '@centrifuge/centrifuge-react'
-import { AnchorButton, Box, DateInput, SearchInput, Select, Shelf } from '@centrifuge/fabric'
+import { Pool } from '@centrifuge/centrifuge-js'
+import {
+ AnchorButton,
+ Box,
+ Button,
+ DateInput,
+ IconBalanceSheet,
+ IconCashflow,
+ IconDownload,
+ IconProfitAndLoss,
+ Select,
+ Shelf,
+} from '@centrifuge/fabric'
import * as React from 'react'
import { useNavigate } from 'react-router'
-import { nftMetadataSchema } from '../../schemas'
+import styled from 'styled-components'
import { useBasePath } from '../../utils/useBasePath'
-import { useActiveDomains } from '../../utils/useLiquidityPools'
-import { useLoans } from '../../utils/useLoans'
-import { useMetadata } from '../../utils/useMetadata'
-import { useCentNFT } from '../../utils/useNFTs'
-import { useDebugFlags } from '../DebugFlags'
-import { GroupBy, Report, ReportContext } from './ReportContext'
-import { formatPoolFeeTransactionType } from './utils'
+import { GroupBy, ReportContext } from './ReportContext'
+
+interface StyledButtonProps {
+ selected?: boolean
+}
+
+const StyledButton = styled(Button)`
+ margin-right: 12px;
+ & > span {
+ background-color: ${({ selected, theme }) =>
+ selected ? theme.colors.backgroundPrimary : theme.colors.backgroundInverted};
+ color: ${({ selected, theme }) => (selected ? theme.colors.textPrimary : theme.colors.textInverted)};
+ }
+
+ &:hover > span {
+ background-color: ${({ selected, theme }) =>
+ selected ? theme.colors.backgroundPrimary : theme.colors.backgroundHover};
+ color: ${({ selected, theme }) => (selected ? theme.colors.textPrimary : theme.colors.textHover)};
+ }
+`
type ReportFilterProps = {
pool: Pool
}
export function ReportFilter({ pool }: ReportFilterProps) {
- const {
- csvData,
- setStartDate,
- startDate,
- endDate,
- setEndDate,
- report,
- loanStatus,
- setLoanStatus,
- txType,
- setTxType,
- groupBy,
- setGroupBy,
- activeTranche,
- setActiveTranche,
- address,
- setAddress,
- network,
- setNetwork,
- loan,
- setLoan,
- } = React.useContext(ReportContext)
+ const { csvData, setStartDate, startDate, endDate, setEndDate, groupBy, setGroupBy, report } =
+ React.useContext(ReportContext)
const navigate = useNavigate()
const basePath = useBasePath()
- const { data: domains } = useActiveDomains(pool.id)
- const getNetworkName = useGetNetworkName()
- const loans = useLoans(pool.id) as Loan[] | undefined
-
- const { showOracleTx } = useDebugFlags()
-
- const reportOptions: { label: string; value: Report }[] = [
- { label: 'Balance sheet', value: 'balance-sheet' },
- { label: 'Profit & loss', value: 'profit-and-loss' },
- { label: 'Cash flow statement', value: 'cash-flow-statement' },
- { label: 'Investor transactions', value: 'investor-tx' },
- { label: 'Asset transactions', value: 'asset-tx' },
- { label: 'Fee transactions', value: 'fee-tx' },
- ...(showOracleTx === true ? [{ label: 'Oracle transactions', value: 'oracle-tx' as Report }] : []),
- // { label: 'Pool balance', value: 'pool-balance' },
- { label: 'Token price', value: 'token-price' },
- { label: 'Asset list', value: 'asset-list' },
- { label: 'Investor list', value: 'investor-list' },
- ]
-
return (
- {
- if (event.target.value) {
- navigate(`${basePath}/${pool.id}/reporting/${event.target.value}`)
- }
- }}
- />
-
- {!['investor-list', 'asset-list', 'balance-sheet', 'cash-flow-statement', 'profit-and-loss'].includes(report) && (
- <>
- setStartDate(e.target.value)} />
- setEndDate(e.target.value)} />
- >
- )}
-
- {['pool-balance', 'token-price'].includes(report) && (
- {
- if (event.target.value) {
- setGroupBy(event.target.value as GroupBy)
- }
- }}
- />
- )}
-
- {report === 'asset-list' && (
- <>
- {
- setLoanStatus(event.target.value)
- }}
- />
- setStartDate(e.target.value)} />
- >
- )}
-
- {(report === 'investor-list' || report === 'investor-tx') && (
- {
- return {
- label: token.currency.name,
- value: token.id,
- }
- }),
- ]}
- value={activeTranche}
- onChange={(event) => {
- if (event.target.value) {
- setActiveTranche(event.target.value)
- }
- }}
- />
- )}
- {report === 'asset-tx' && (
- {
- setLoan(event.target.value)
- }}
- value={loan}
- options={[
- { label: 'All', value: 'all' },
- ...(loans?.map((l) => ({ value: l.id, label: })) ?? []),
- ]}
- />
- )}
+
+ }
+ onClick={() => navigate(`${basePath}/${pool.id}/reporting/balance-sheet`)}
+ >
+ Balance sheet
+
+ }
+ onClick={() => navigate(`${basePath}/${pool.id}/reporting/profit-and-loss`)}
+ >
+ Profit & loss
+
+ }
+ onClick={() => navigate(`${basePath}/${pool.id}/reporting/cash-flow-statement`)}
+ >
+ Cash flow
+
+
- {['balance-sheet', 'cash-flow-statement', 'profit-and-loss'].includes(report) && (
- <>
+
+
{
setGroupBy(event.target.value as GroupBy)
}}
@@ -203,154 +102,42 @@ export function ReportFilter({ pool }: ReportFilterProps) {
{ label: 'Quarterly', value: 'quarter' },
{ label: 'Yearly', value: 'year' },
]}
+ hideBorder
/>
+
+
{groupBy === 'day' && (
- setStartDate(e.target.value)} />
+ setStartDate(e.target.value)} />
)}
- {groupBy === 'month' || groupBy === 'daily' ? (
- <>
- setStartDate(e.target.value)} />
- setEndDate(e.target.value)} />
- >
- ) : null}
- >
- )}
+
+ {groupBy === 'month' || groupBy === 'daily' ? (
+ <>
+
+ setStartDate(e.target.value)}
+ />
+
+ setEndDate(e.target.value)} />
+ >
+ ) : null}
+
- {['investor-tx', 'asset-tx', 'fee-tx'].includes(report) && (
- {
- if (event.target.value) {
- setTxType(event.target.value)
- }
- }}
- />
- )}
- {['investor-tx', 'investor-list'].includes(report) && (
- <>
- {
- return {
- label: getNetworkName(domain.chainId),
- value: String(domain.chainId),
- }
- }),
- ]}
- value={network}
- onChange={(e) => {
- const { value } = e.target
- if (value) {
- setNetwork(isNaN(Number(value)) ? value : Number(value))
- }
- }}
- />
- setAddress(e.target.value)}
- />
- >
- )}
-
-
- Export CSV
+
+ }
+ small
+ variant="inverted"
+ >
+ CSV
)
}
-
-function LoanOption({ loan }: { loan: Loan }) {
- const nft = useCentNFT(loan.asset.collectionId, loan.asset.nftId, false, false)
- const { data: metadata } = useMetadata(nft?.metadataUri, nftMetadataSchema)
- return (
-
- )
-}
diff --git a/fabric/src/components/InputUnit/index.tsx b/fabric/src/components/InputUnit/index.tsx
index 2a5d9c336..109ccd95e 100644
--- a/fabric/src/components/InputUnit/index.tsx
+++ b/fabric/src/components/InputUnit/index.tsx
@@ -15,15 +15,21 @@ export type InputUnitProps = {
errorMessage?: string
inputElement?: React.ReactNode
disabled?: boolean
+ row?: boolean
}
-export function InputUnit({ id, label, secondaryLabel, errorMessage, inputElement, disabled }: InputUnitProps) {
+export function InputUnit({ id, label, secondaryLabel, errorMessage, inputElement, disabled, row }: InputUnitProps) {
const defaultId = React.useId()
id ??= defaultId
+
return (
-
- {label && {label}}
+
+ {label && (
+
+ {row ? `${label}:` : ''}
+
+ )}
+
{children}
)
diff --git a/fabric/src/components/TextInput/index.tsx b/fabric/src/components/TextInput/index.tsx
index 49d98d7ca..9c12220b7 100644
--- a/fabric/src/components/TextInput/index.tsx
+++ b/fabric/src/components/TextInput/index.tsx
@@ -11,6 +11,7 @@ export type TextInputProps = React.InputHTMLAttributes &
InputUnitProps & {
action?: React.ReactNode
symbol?: React.ReactNode
+ row?: boolean
}
export type TextAreaInputProps = React.InputHTMLAttributes &
InputUnitProps & {
@@ -113,11 +114,12 @@ export function TextInputBox(
props: Omit & {
error?: boolean
inputRef?: React.Ref
+ row?: boolean
}
) {
- const { error, disabled, action, symbol, inputRef, inputElement, ...inputProps } = props
+ const { error, disabled, action, symbol, inputRef, inputElement, row, ...inputProps } = props
return (
-
+
{inputElement ?? }
{symbol && (
@@ -167,9 +169,10 @@ export function SearchInput({ label, secondaryLabel, disabled, errorMessage, id,
)
}
-export function DateInput({ label, secondaryLabel, disabled, errorMessage, id, ...inputProps }: TextInputProps) {
+export function DateInput({ label, secondaryLabel, disabled, errorMessage, id, row, ...inputProps }: TextInputProps) {
const defaultId = React.useId()
id ??= defaultId
+
return (
}
diff --git a/fabric/src/icon-svg/IconBalanceSheet.svg b/fabric/src/icon-svg/IconBalanceSheet.svg
index 89a2407fc..ec8f772b9 100644
--- a/fabric/src/icon-svg/IconBalanceSheet.svg
+++ b/fabric/src/icon-svg/IconBalanceSheet.svg
@@ -1,3 +1,3 @@
diff --git a/fabric/src/icon-svg/IconCashflow.svg b/fabric/src/icon-svg/IconCashflow.svg
index 798a162bc..4a8ff3024 100644
--- a/fabric/src/icon-svg/IconCashflow.svg
+++ b/fabric/src/icon-svg/IconCashflow.svg
@@ -1,3 +1,3 @@
diff --git a/fabric/src/icon-svg/IconProfitAndLoss.svg b/fabric/src/icon-svg/IconProfitAndLoss.svg
index 5223d3810..601971402 100644
--- a/fabric/src/icon-svg/IconProfitAndLoss.svg
+++ b/fabric/src/icon-svg/IconProfitAndLoss.svg
@@ -1,3 +1,3 @@
diff --git a/fabric/src/theme/tokens/theme.ts b/fabric/src/theme/tokens/theme.ts
index ebb7bf98a..d10a5d692 100644
--- a/fabric/src/theme/tokens/theme.ts
+++ b/fabric/src/theme/tokens/theme.ts
@@ -1,4 +1,4 @@
-import { black, blackScale, blueScale, gold, grayScale, yellowScale } from './colors'
+import { black, blueScale, gold, grayScale, yellowScale } from './colors'
const statusDefault = grayScale[800]
const statusInfo = blueScale[500]
@@ -65,19 +65,19 @@ const colors = {
shadowButtonPrimary: 'transparent',
backgroundButtonSecondary: black,
- backgroundButtonSecondaryFocus: blackScale[500],
- backgroundButtonSecondaryHover: blackScale[500],
- backgroundButtonSecondaryPressed: blackScale[500],
+ backgroundButtonSecondaryFocus: black,
+ backgroundButtonSecondaryHover: black,
+ backgroundButtonSecondaryPressed: black,
backgroundButtonSecondaryDisabled: grayScale[300],
textButtonSecondary: 'white',
- textButtonSecondaryFocus: gold,
- textButtonSecondaryHover: gold,
- textButtonSecondaryPressed: gold,
+ textButtonSecondaryFocus: 'white',
+ textButtonSecondaryHover: 'white',
+ textButtonSecondaryPressed: 'white',
textButtonSecondaryDisabled: grayScale[500],
- borderButtonSecondary: grayScale[300],
- borderButtonSecondaryFocus: gold,
- borderButtonSecondaryHover: gold,
- borderButtonSecondaryPressed: gold,
+ borderButtonSecondary: black,
+ borderButtonSecondaryFocus: black,
+ borderButtonSecondaryHover: black,
+ borderButtonSecondaryPressed: black,
borderButtonSecondaryDisabled: 'transparent',
shadowButtonSecondary: 'transparent',
@@ -103,9 +103,9 @@ const colors = {
backgroundButtonInvertedPressed: grayScale[100],
backgroundButtonInvertedDisabled: grayScale[100],
textButtonInverted: black,
- textButtonInvertedFocus: grayScale[600],
- textButtonInvertedHover: grayScale[600],
- textButtonInvertedPressed: grayScale[600],
+ textButtonInvertedFocus: black,
+ textButtonInvertedHover: black,
+ textButtonInvertedPressed: black,
textButtonInvertedDisabled: grayScale[500],
borderButtonInverted: grayScale[100],
borderButtonInvertedFocus: black,