@huma-finance/widgets 0.0.6-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (203) hide show
  1. package/.env.example +3 -0
  2. package/.eslintignore +2 -0
  3. package/.eslintrc.js +64 -0
  4. package/.prettierignore +4 -0
  5. package/.prettierrc.js +16 -0
  6. package/API.md +331 -0
  7. package/LICENSE +661 -0
  8. package/README.md +48 -0
  9. package/babel.config.js +15 -0
  10. package/config-overrides.js +9 -0
  11. package/cosmos.config.json +7 -0
  12. package/cypress/e2e/01-invoice-factoring-borrow.test.ts +62 -0
  13. package/cypress/support/e2e.ts +76 -0
  14. package/cypress/support/ethereum.ts +142 -0
  15. package/cypress/tsconfig.json +9 -0
  16. package/cypress/utils/index.ts +54 -0
  17. package/cypress.config.ts +20 -0
  18. package/dist/assets/output-15e10f9f.css +44 -0
  19. package/dist/cjs/assets/output-15e10f9f.css +44 -0
  20. package/dist/cjs/index.cjs +17576 -0
  21. package/dist/cjs/index.cjs.map +1 -0
  22. package/dist/index.d.ts +211 -0
  23. package/dist/index.js +17529 -0
  24. package/dist/index.js.map +1 -0
  25. package/jsdoc2md.json +20 -0
  26. package/package.json +193 -0
  27. package/public/favicon.ico +0 -0
  28. package/public/index.html +40 -0
  29. package/public/logo192.png +0 -0
  30. package/public/logo512.png +0 -0
  31. package/public/manifest.json +25 -0
  32. package/public/robots.txt +3 -0
  33. package/rollup.config.js +81 -0
  34. package/src/components/Activity.tsx +123 -0
  35. package/src/components/AllowListModal.tsx +113 -0
  36. package/src/components/ApolloWrapper.tsx +15 -0
  37. package/src/components/ApproveAllowanceModal.tsx +118 -0
  38. package/src/components/BottomButton.tsx +31 -0
  39. package/src/components/ChooseAmountModal.tsx +315 -0
  40. package/src/components/CreditLine/borrow/1-Evaluation.tsx +159 -0
  41. package/src/components/CreditLine/borrow/2-AllowList.tsx +34 -0
  42. package/src/components/CreditLine/borrow/3-ChooseAmount.tsx +74 -0
  43. package/src/components/CreditLine/borrow/4-ApproveAllowance.tsx +29 -0
  44. package/src/components/CreditLine/borrow/5-Transfer.tsx +30 -0
  45. package/src/components/CreditLine/borrow/6-Success.tsx +30 -0
  46. package/src/components/CreditLine/borrow/index.tsx +119 -0
  47. package/src/components/CreditLine/payment/1-ChooseAmount.tsx +67 -0
  48. package/src/components/CreditLine/payment/2-ApproveAllowance.tsx +23 -0
  49. package/src/components/CreditLine/payment/3-Transfer.tsx +34 -0
  50. package/src/components/CreditLine/payment/4-Success.tsx +39 -0
  51. package/src/components/CreditLine/payment/index.tsx +94 -0
  52. package/src/components/ErrorModal.tsx +132 -0
  53. package/src/components/Factoring/FactoredList.tsx +143 -0
  54. package/src/components/Factoring/UpcomingList.tsx +90 -0
  55. package/src/components/Factoring/index.ts +2 -0
  56. package/src/components/HumaLoading.tsx +68 -0
  57. package/src/components/HumaTable.tsx +158 -0
  58. package/src/components/InvoiceFactoring/borrow/1-Evaluation.tsx +46 -0
  59. package/src/components/InvoiceFactoring/borrow/2-AllowList.tsx +34 -0
  60. package/src/components/InvoiceFactoring/borrow/3-ChooseAmount.tsx +92 -0
  61. package/src/components/InvoiceFactoring/borrow/4-ConfirmTransfer.tsx +104 -0
  62. package/src/components/InvoiceFactoring/borrow/5-ApproveNFT.tsx +55 -0
  63. package/src/components/InvoiceFactoring/borrow/6-Transfer.tsx +34 -0
  64. package/src/components/InvoiceFactoring/borrow/7-Success.tsx +20 -0
  65. package/src/components/InvoiceFactoring/borrow/index.tsx +96 -0
  66. package/src/components/InvoiceFactoring/payment/1-ChooseAmount.tsx +67 -0
  67. package/src/components/InvoiceFactoring/payment/2-ApproveAllowance.tsx +23 -0
  68. package/src/components/InvoiceFactoring/payment/3-Transfer.tsx +34 -0
  69. package/src/components/InvoiceFactoring/payment/4-Success.tsx +23 -0
  70. package/src/components/InvoiceFactoring/payment/index.tsx +86 -0
  71. package/src/components/Lend/supply/1-Evaluation.tsx +86 -0
  72. package/src/components/Lend/supply/2-ChooseAmount.tsx +70 -0
  73. package/src/components/Lend/supply/3-ApproveAllowance.tsx +25 -0
  74. package/src/components/Lend/supply/4-ConfirmTransfer.tsx +104 -0
  75. package/src/components/Lend/supply/6-Transfer.tsx +32 -0
  76. package/src/components/Lend/supply/7-Success.tsx +49 -0
  77. package/src/components/Lend/supply/index.tsx +144 -0
  78. package/src/components/Lend/withdraw/1-CheckWithdrawble.tsx +73 -0
  79. package/src/components/Lend/withdraw/2-ChooseAmount.tsx +50 -0
  80. package/src/components/Lend/withdraw/3-Transfer.tsx +32 -0
  81. package/src/components/Lend/withdraw/4-Success.tsx +49 -0
  82. package/src/components/Lend/withdraw/index.tsx +101 -0
  83. package/src/components/LoadingModal.tsx +49 -0
  84. package/src/components/StreamFactoring/borrow/1-Evaluation.tsx +57 -0
  85. package/src/components/StreamFactoring/borrow/2-ChooseAmount.tsx +124 -0
  86. package/src/components/StreamFactoring/borrow/3-ConfirmTransfer.tsx +104 -0
  87. package/src/components/StreamFactoring/borrow/4-ApproveAllowance.tsx +65 -0
  88. package/src/components/StreamFactoring/borrow/5-Permit.tsx +144 -0
  89. package/src/components/StreamFactoring/borrow/6-Transfer.tsx +37 -0
  90. package/src/components/StreamFactoring/borrow/7-Success.tsx +20 -0
  91. package/src/components/StreamFactoring/borrow/index.tsx +95 -0
  92. package/src/components/StreamFactoring/payment/ChooseAmount.tsx +54 -0
  93. package/src/components/StreamFactoring/payment/Success.tsx +23 -0
  94. package/src/components/StreamFactoring/payment/Transfer.tsx +34 -0
  95. package/src/components/StreamFactoring/payment/index.tsx +66 -0
  96. package/src/components/SuperfluidFactoring/SuperfluidFactoredList.tsx +61 -0
  97. package/src/components/SuperfluidFactoring/SuperfluidUpcomingList.tsx +185 -0
  98. package/src/components/SuperfluidFactoring/index.tsx +85 -0
  99. package/src/components/TxDoneModal.tsx +83 -0
  100. package/src/components/TxSendModal.tsx +59 -0
  101. package/src/components/ViewOnExplorer.tsx +26 -0
  102. package/src/components/WidgetWrapper.tsx +74 -0
  103. package/src/components/WrapperModal.tsx +54 -0
  104. package/src/components/buttons/TableActionButton.tsx +36 -0
  105. package/src/components/buttons/index.ts +1 -0
  106. package/src/components/humaModal/HumaModal.tsx +68 -0
  107. package/src/components/humaModal/HumaModalHeader.tsx +70 -0
  108. package/src/components/humaModal/index.tsx +2 -0
  109. package/src/components/icons/approve-lender.svg +30 -0
  110. package/src/components/icons/auto-payback.svg +40 -0
  111. package/src/components/icons/check-circle.svg +3 -0
  112. package/src/components/icons/check-green.svg +3 -0
  113. package/src/components/icons/check.svg +10 -0
  114. package/src/components/icons/donut.svg +904 -0
  115. package/src/components/icons/ellipse.svg +3 -0
  116. package/src/components/icons/ethereum.svg +1 -0
  117. package/src/components/icons/huma-full.svg +22 -0
  118. package/src/components/icons/huma.svg +15 -0
  119. package/src/components/icons/index.tsx +93 -0
  120. package/src/components/icons/loader.svg +229 -0
  121. package/src/components/icons/metamask.svg +31 -0
  122. package/src/components/icons/polygon.svg +16 -0
  123. package/src/components/icons/receipt.svg +3 -0
  124. package/src/components/icons/separator.svg +3 -0
  125. package/src/components/icons/sorry.svg +31 -0
  126. package/src/components/icons/spinner.gif +0 -0
  127. package/src/components/icons/usdc.svg +5 -0
  128. package/src/components/icons/wallet-connect.svg +12 -0
  129. package/src/cosmos/CreditLineBorrow.fixture.tsx +85 -0
  130. package/src/cosmos/CreditLinePayment.fixture.tsx +49 -0
  131. package/src/cosmos/InvoiceFactoringBorrow.fixture.tsx +111 -0
  132. package/src/cosmos/InvoiceFactoringPayment.fixture.tsx +67 -0
  133. package/src/cosmos/LendSupply.fixture.tsx +75 -0
  134. package/src/cosmos/LendWithdraw.fixture.tsx +43 -0
  135. package/src/cosmos/SDKTesting.fixture.tsx +507 -0
  136. package/src/cosmos/SuperfluidFactoringBorrow.fixture.tsx +12 -0
  137. package/src/cosmos/WalletWrapper.tsx +52 -0
  138. package/src/cosmos/abis/InvoiceNFT.json +644 -0
  139. package/src/cosmos/abis/ReceivableFactoringPool.json +1529 -0
  140. package/src/cosmos/utils/index.ts +169 -0
  141. package/src/fonts/Inter/Inter-Black.ttf +0 -0
  142. package/src/fonts/Inter/Inter-Bold.ttf +0 -0
  143. package/src/fonts/Inter/Inter-ExtraBold.ttf +0 -0
  144. package/src/fonts/Inter/Inter-ExtraLight.ttf +0 -0
  145. package/src/fonts/Inter/Inter-Light.ttf +0 -0
  146. package/src/fonts/Inter/Inter-Medium.ttf +0 -0
  147. package/src/fonts/Inter/Inter-Regular.ttf +0 -0
  148. package/src/fonts/Inter/Inter-SemiBold.ttf +0 -0
  149. package/src/fonts/Inter/Inter-Thin.ttf +0 -0
  150. package/src/fonts/Recoleta/Recoleta-Black.otf +0 -0
  151. package/src/fonts/Recoleta/Recoleta-Bold.otf +0 -0
  152. package/src/fonts/Recoleta/Recoleta-Light.otf +0 -0
  153. package/src/fonts/Recoleta/Recoleta-Medium.otf +0 -0
  154. package/src/fonts/Recoleta/Recoleta-Regular.otf +0 -0
  155. package/src/fonts/Recoleta/Recoleta-RegularDEMO.otf +0 -0
  156. package/src/fonts/Recoleta/Recoleta-SemiBold.otf +0 -0
  157. package/src/fonts/Recoleta/Recoleta-Thin.otf +0 -0
  158. package/src/fonts/Roboto/LICENSE.txt +202 -0
  159. package/src/fonts/Roboto/Roboto-Black.ttf +0 -0
  160. package/src/fonts/Roboto/Roboto-BlackItalic.ttf +0 -0
  161. package/src/fonts/Roboto/Roboto-Bold.ttf +0 -0
  162. package/src/fonts/Roboto/Roboto-BoldItalic.ttf +0 -0
  163. package/src/fonts/Roboto/Roboto-Italic.ttf +0 -0
  164. package/src/fonts/Roboto/Roboto-Light.ttf +0 -0
  165. package/src/fonts/Roboto/Roboto-LightItalic.ttf +0 -0
  166. package/src/fonts/Roboto/Roboto-Medium.ttf +0 -0
  167. package/src/fonts/Roboto/Roboto-MediumItalic.ttf +0 -0
  168. package/src/fonts/Roboto/Roboto-Regular.ttf +0 -0
  169. package/src/fonts/Roboto/Roboto-Thin.ttf +0 -0
  170. package/src/fonts/Roboto/Roboto-ThinItalic.ttf +0 -0
  171. package/src/fonts/UniNeue/UniNeue-Black.ttf +0 -0
  172. package/src/fonts/UniNeue/UniNeue-Bold.ttf +0 -0
  173. package/src/fonts/UniNeue/UniNeue-Book.ttf +0 -0
  174. package/src/fonts/UniNeue/UniNeue-Heavy.ttf +0 -0
  175. package/src/fonts/UniNeue/UniNeue-Light.ttf +0 -0
  176. package/src/fonts/UniNeue/UniNeue-Regular.ttf +0 -0
  177. package/src/fonts/UniNeue/UniNeue-Thin.ttf +0 -0
  178. package/src/hooks/useEA.ts +70 -0
  179. package/src/hooks/useRedux.ts +6 -0
  180. package/src/index.css +61 -0
  181. package/src/index.tsx +219 -0
  182. package/src/react-app-env.d.ts +1 -0
  183. package/src/reportWebVitals.ts +15 -0
  184. package/src/setupTests.ts +6 -0
  185. package/src/store/index.ts +27 -0
  186. package/src/store/widgets.reducers.ts +120 -0
  187. package/src/store/widgets.selectors.ts +3 -0
  188. package/src/store/widgets.store.ts +55 -0
  189. package/src/theme/breakpoints.ts +10 -0
  190. package/src/theme/components.ts +70 -0
  191. package/src/theme/coreThemeConstants.ts +29 -0
  192. package/src/theme/cssMixins.ts +92 -0
  193. package/src/theme/hooks/useGetSizes.ts +34 -0
  194. package/src/theme/index.ts +24 -0
  195. package/src/theme/palette.ts +150 -0
  196. package/src/theme/shape.ts +7 -0
  197. package/src/theme/theme.types.ts +80 -0
  198. package/src/theme/typography.ts +117 -0
  199. package/src/utilTypes.d.ts +29 -0
  200. package/src/utils/env.ts +9 -0
  201. package/tsconfig.build.json +7 -0
  202. package/tsconfig.json +32 -0
  203. package/webpack.cosmos.js +54 -0
@@ -0,0 +1,143 @@
1
+ import { Box, css, LinearProgress, useTheme } from '@mui/material'
2
+ import { useWeb3React } from '@web3-react/core'
3
+ import {
4
+ AccountStats,
5
+ downScale,
6
+ formatMoney,
7
+ hasRFActiveLoan,
8
+ PoolInfoType,
9
+ timestampToLL,
10
+ useMQ,
11
+ usePoolUnderlyingToken,
12
+ } from '@huma-finance/shared'
13
+ import React, { useEffect, useState } from 'react'
14
+
15
+ import { ColumnType } from '../../utilTypes'
16
+ import { HumaTable } from '../HumaTable'
17
+ import { ReceiptIcon } from '../icons'
18
+
19
+ type Props<T> = {
20
+ title: 'Streams' | 'Invoices'
21
+ poolInfo: PoolInfoType
22
+ loading: boolean
23
+ accountStats: AccountStats
24
+ handlePayManually: (item: T) => void
25
+ getColumns: (handlePayManually: (item: T) => void) => ColumnType<T>[]
26
+ setItem?: (
27
+ accountStats: AccountStats,
28
+ ) => Promise<{ name?: string; payer?: string }>
29
+ }
30
+
31
+ export function FactoredList<T>({
32
+ title,
33
+ poolInfo,
34
+ loading,
35
+ accountStats,
36
+ handlePayManually,
37
+ getColumns,
38
+ setItem,
39
+ }: Props<T>): React.ReactElement {
40
+ const theme = useTheme()
41
+ const { isMdSize } = useMQ()
42
+ const { isActive } = useWeb3React()
43
+ const { decimals } = usePoolUnderlyingToken(
44
+ poolInfo.poolName,
45
+ poolInfo.poolType,
46
+ )
47
+ const [factoredItem, setFactoredItem] = useState<Partial<T>>()
48
+ const { creditRecord, receivableInfo } = accountStats
49
+ const hasActiveLoan = hasRFActiveLoan(creditRecord, receivableInfo)
50
+
51
+ useEffect(() => {
52
+ const fetchData = async () => {
53
+ if (creditRecord && receivableInfo?.receivableParam.gt(0) && decimals) {
54
+ const id = receivableInfo.receivableParam.toString()
55
+ const dueDate = timestampToLL(creditRecord.dueDate.toNumber())
56
+ const { receivableAmount } = receivableInfo
57
+ const { totalDue } = creditRecord
58
+ let factoredItem = {
59
+ id,
60
+ due: dueDate,
61
+ icon: <ReceiptIcon css={{ width: '18px' }} />,
62
+ amount: formatMoney(downScale(receivableAmount.toString(), decimals)),
63
+ factored: formatMoney(downScale(totalDue.toString(), decimals)),
64
+ remained: formatMoney(
65
+ downScale(receivableAmount.sub(totalDue).toString(), decimals),
66
+ ),
67
+ } as T
68
+ if (setItem) {
69
+ const customProps = await setItem(accountStats)
70
+ factoredItem = { ...factoredItem, ...customProps }
71
+ }
72
+ setFactoredItem(factoredItem)
73
+ }
74
+ }
75
+ fetchData()
76
+ }, [accountStats, creditRecord, decimals, receivableInfo, setItem])
77
+
78
+ const getPadding = () => {
79
+ if (isMdSize) {
80
+ return '0 8px 8px 8px'
81
+ }
82
+ return '0 16px 16px 16px'
83
+ }
84
+
85
+ const styles = {
86
+ title: css`
87
+ font-family: 'Uni-Neue-Black';
88
+ color: ${theme.palette.text.primary};
89
+ font-size: 24px;
90
+ margin-bottom: 16px;
91
+ `,
92
+ description: css`
93
+ font-family: 'Uni-Neue-Regular';
94
+ color: ${theme.palette.text.primary};
95
+ font-size: 1rem;
96
+ `,
97
+ tableWrapper: css`
98
+ margin-top: 24px;
99
+ padding: ${getPadding()};
100
+ background: linear-gradient(180deg, #ffffff 0%, #ffffff 100%);
101
+ border: 1px solid #ffffff;
102
+ border-radius: 24px;
103
+ position: relative;
104
+ `,
105
+ progress: css`
106
+ width: calc(100% - 30px);
107
+ position: absolute;
108
+ top: 0;
109
+ left: 15px;
110
+ `,
111
+ }
112
+
113
+ return (
114
+ <Box>
115
+ <Box css={styles.title}>Factored {title}</Box>
116
+ <Box css={styles.description} marginBottom='47px'>
117
+ {!isActive && (
118
+ <Box component='span'>
119
+ Please connect wallet to check your factored {title.toLowerCase()}.
120
+ </Box>
121
+ )}
122
+ {isActive && !hasActiveLoan && (
123
+ <Box component='span'>
124
+ You don’t have any factored {title.toLowerCase()}.
125
+ </Box>
126
+ )}
127
+ {isActive && hasActiveLoan && factoredItem && (
128
+ <Box css={styles.tableWrapper}>
129
+ {loading && (
130
+ <Box css={styles.progress}>
131
+ <LinearProgress />
132
+ </Box>
133
+ )}
134
+ <HumaTable
135
+ columns={getColumns(handlePayManually)}
136
+ rows={[factoredItem]}
137
+ />
138
+ </Box>
139
+ )}
140
+ </Box>
141
+ </Box>
142
+ )
143
+ }
@@ -0,0 +1,90 @@
1
+ import { Box, css, LinearProgress, useTheme } from '@mui/material'
2
+ import { useWeb3React } from '@web3-react/core'
3
+ import { useMQ } from '@huma-finance/shared'
4
+ import React from 'react'
5
+
6
+ import { ColumnType, WCProps } from '../../utilTypes'
7
+ import { HumaTable } from '../HumaTable'
8
+
9
+ type Props<T> = {
10
+ items: T[] | undefined
11
+ loading: boolean
12
+ columns: ColumnType<T>[]
13
+ title: string
14
+ connectWalletDesc: string
15
+ noItemDesc: string
16
+ }
17
+
18
+ export function UpcomingList<T>({
19
+ items,
20
+ loading,
21
+ columns,
22
+ title,
23
+ connectWalletDesc,
24
+ noItemDesc,
25
+ children,
26
+ }: WCProps<Props<T>>): React.ReactElement {
27
+ const theme = useTheme()
28
+ const { isActive } = useWeb3React()
29
+ const { isMdSize, isSmSize } = useMQ()
30
+
31
+ const getPadding = () => {
32
+ if (isMdSize) {
33
+ return '0 8px 8px 8px'
34
+ }
35
+ return '0 16px 16px 16px'
36
+ }
37
+
38
+ const styles = {
39
+ title: css`
40
+ font-family: 'Uni-Neue-Black';
41
+ color: ${theme.palette.text.primary};
42
+ font-size: 24px;
43
+ margin-bottom: 16px;
44
+ `,
45
+ description: css`
46
+ font-family: 'Uni-Neue-Regular';
47
+ color: ${theme.palette.text.primary};
48
+ font-size: 1rem;
49
+ `,
50
+ tableWrapper: css`
51
+ margin-top: 24px;
52
+ padding: ${getPadding()};
53
+ background: linear-gradient(180deg, #ffffff 0%, #ffffff 100%);
54
+ border: 1px solid #ffffff;
55
+ border-radius: 24px;
56
+ position: relative;
57
+ `,
58
+ progress: css`
59
+ width: calc(100% - 30px);
60
+ position: absolute;
61
+ top: 0;
62
+ left: 15px;
63
+ `,
64
+ }
65
+
66
+ return (
67
+ <Box>
68
+ <Box css={styles.title}>{title}</Box>
69
+ <Box css={styles.description} marginBottom='47px'>
70
+ {!isActive && <Box component='span'>{connectWalletDesc}</Box>}
71
+ {isActive && !items?.length && <Box>{noItemDesc}</Box>}
72
+ {isActive && items?.length && (
73
+ <Box css={styles.tableWrapper}>
74
+ {loading && (
75
+ <Box css={styles.progress}>
76
+ <LinearProgress />
77
+ </Box>
78
+ )}
79
+ <HumaTable
80
+ columns={columns}
81
+ rows={items}
82
+ hideRowsPerPage={isSmSize}
83
+ />
84
+ </Box>
85
+ )}
86
+ {children}
87
+ </Box>
88
+ </Box>
89
+ )
90
+ }
@@ -0,0 +1,2 @@
1
+ export * from './UpcomingList'
2
+ export * from './FactoredList'
@@ -0,0 +1,68 @@
1
+ import { css } from '@emotion/react'
2
+ import { useTheme } from '@mui/material'
3
+ import React, { useEffect, useState } from 'react'
4
+
5
+ import { LoaderIcon } from './icons'
6
+
7
+ type Props = {
8
+ fullScreen?: boolean
9
+ minHeight?: string
10
+ }
11
+
12
+ export function HumaLoading({
13
+ fullScreen = false,
14
+ minHeight = '0px',
15
+ }: Props): React.ReactElement {
16
+ const theme = useTheme()
17
+ const pathLength = 45
18
+ const [count, setCount] = useState(1)
19
+ const intervalTime = 30
20
+
21
+ useEffect(() => {
22
+ const interval = setInterval(() => {
23
+ if (count <= pathLength) {
24
+ const element = document.querySelector(
25
+ `#huma-loader-wrapper > svg > path:nth-of-type(${count})`,
26
+ )
27
+ if (element) {
28
+ // @ts-ignore
29
+ element.style.visibility = 'visible'
30
+ setCount((pre) => pre + 1)
31
+ }
32
+ } else {
33
+ const elements = document.querySelectorAll(
34
+ `#huma-loader-wrapper > svg > path`,
35
+ )
36
+ if (elements) {
37
+ // @ts-ignore
38
+ elements.forEach((element) => {
39
+ // @ts-ignore
40
+ element.style.visibility = 'hidden'
41
+ })
42
+ setCount(1)
43
+ }
44
+ }
45
+ }, intervalTime)
46
+ return () => clearInterval(interval)
47
+ }, [count])
48
+
49
+ const styles = {
50
+ wrapper: css`
51
+ ${theme.cssMixins.rowCentered};
52
+ min-height: ${fullScreen ? '100vh' : minHeight};
53
+ width: 50px;
54
+ height: 50px;
55
+ `,
56
+ icon: css`
57
+ & > path {
58
+ visibility: hidden;
59
+ }
60
+ `,
61
+ }
62
+
63
+ return (
64
+ <div css={styles.wrapper} id='huma-loader-wrapper'>
65
+ <LoaderIcon css={styles.icon} />
66
+ </div>
67
+ )
68
+ }
@@ -0,0 +1,158 @@
1
+ import { Box, css, TablePagination, useTheme } from '@mui/material'
2
+ import Table from '@mui/material/Table'
3
+ import TableBody from '@mui/material/TableBody'
4
+ import TableCell from '@mui/material/TableCell'
5
+ import TableContainer from '@mui/material/TableContainer'
6
+ import TableHead from '@mui/material/TableHead'
7
+ import TableRow from '@mui/material/TableRow'
8
+ import * as React from 'react'
9
+
10
+ import { ColumnType } from '../utilTypes'
11
+ import { SeparatorIcon } from './icons'
12
+
13
+ type Props<T> = {
14
+ columns: ColumnType<T>[]
15
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
16
+ rows?: any[]
17
+ hideRowsPerPage?: boolean
18
+ }
19
+
20
+ export function HumaTable<T>({
21
+ columns,
22
+ rows,
23
+ hideRowsPerPage = false,
24
+ }: Props<T>): React.ReactElement | null {
25
+ const theme = useTheme()
26
+ const [page, setPage] = React.useState(0)
27
+ const [rowsPerPage, setRowsPerPage] = React.useState(5)
28
+ const noPagination = rows ? rows.length <= 5 : true
29
+ const rowperPageOptions = hideRowsPerPage ? [] : [5, 10, 25]
30
+
31
+ const styles = {
32
+ tableHeader: css`
33
+ font-family: 'Uni-Neue-Regular';
34
+ ${theme.cssMixins.rowVCentered}
35
+ font-size: 14px;
36
+ color: rgba(0, 0, 0, 0.87);
37
+ `,
38
+ tableBody: css`
39
+ font-family: 'Uni-Neue-Regular';
40
+ font-size: 14px;
41
+ color: rgba(0, 0, 0, 0.87);
42
+ `,
43
+ }
44
+
45
+ const handleChangePage = (event: unknown, newPage: number) => {
46
+ setPage(newPage)
47
+ }
48
+
49
+ const handleChangeRowsPerPage = (
50
+ event: React.ChangeEvent<HTMLInputElement>,
51
+ ) => {
52
+ setRowsPerPage(parseInt(event.target.value, 10))
53
+ setPage(0)
54
+ }
55
+
56
+ if (!columns) {
57
+ return null
58
+ }
59
+
60
+ return (
61
+ <>
62
+ <TableContainer>
63
+ <Table aria-label='simple table'>
64
+ <TableHead>
65
+ <TableRow>
66
+ {columns.map((column) => (
67
+ <TableCell key={column.title} width={column.width}>
68
+ <Box css={styles.tableHeader}>
69
+ {!column.noSeparator && <SeparatorIcon />}
70
+ <Box
71
+ component='span'
72
+ sx={{ marginLeft: column.noSeparator ? '0' : '12px' }}
73
+ >
74
+ {column.title}
75
+ </Box>
76
+ </Box>
77
+ </TableCell>
78
+ ))}
79
+ </TableRow>
80
+ </TableHead>
81
+ <TableBody>
82
+ {rows &&
83
+ rows
84
+ .slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage)
85
+ .map((row) => (
86
+ <TableRow key={row.id || row.name}>
87
+ {columns.map((column, index) => (
88
+ <TableCell
89
+ // eslint-disable-next-line react/no-array-index-key
90
+ key={`${column.dataIndex}-${index}`}
91
+ component='th'
92
+ scope='row'
93
+ css={styles.tableBody}
94
+ width={column.width}
95
+ sx={column.style}
96
+ >
97
+ {column.dataIndex && (
98
+ <Box
99
+ component='span'
100
+ sx={{
101
+ display: 'flex',
102
+ alignItems: 'center',
103
+ marginLeft: column.noSeparator ? '0' : '12px',
104
+ }}
105
+ >
106
+ {row[column.dataIndex]}
107
+ </Box>
108
+ )}
109
+ {column.action && (
110
+ <Box
111
+ component='span'
112
+ sx={{
113
+ display: 'flex',
114
+ alignItems: 'center',
115
+ marginLeft: column.noSeparator ? '0' : '12px',
116
+ lineHeight: 0,
117
+ height: 0,
118
+ }}
119
+ >
120
+ {column.action(row)}
121
+ </Box>
122
+ )}
123
+ </TableCell>
124
+ ))}
125
+ </TableRow>
126
+ ))}
127
+ </TableBody>
128
+ </Table>
129
+ </TableContainer>
130
+ {!noPagination && (
131
+ <TablePagination
132
+ size='small'
133
+ sx={{
134
+ '.MuiTablePagination-selectLabel': {
135
+ fontSize: '12px',
136
+ },
137
+ '.MuiTablePagination-select': {
138
+ fontSize: '12px',
139
+ },
140
+ '.MuiTablePagination-displayedRows': {
141
+ fontSize: '12px',
142
+ },
143
+ '.MuiTablePagination-menuItem': {
144
+ fontSize: '14px',
145
+ },
146
+ }}
147
+ rowsPerPageOptions={rowperPageOptions}
148
+ component='div'
149
+ count={rows ? rows.length : 0}
150
+ rowsPerPage={rowsPerPage}
151
+ page={page}
152
+ onPageChange={handleChangePage}
153
+ onRowsPerPageChange={handleChangeRowsPerPage}
154
+ />
155
+ )}
156
+ </>
157
+ )
158
+ }
@@ -0,0 +1,46 @@
1
+ import { useWeb3React } from '@web3-react/core'
2
+ import { ChainEnum, PoolInfoType, toBigNumber } from '@huma-finance/shared'
3
+ import React, { useEffect } from 'react'
4
+
5
+ import useEA from '../../../hooks/useEA'
6
+ import { LoadingModal } from '../../LoadingModal'
7
+ import { WIDGET_STEP } from '../../../store/widgets.store'
8
+
9
+ type Props = {
10
+ poolInfo: PoolInfoType
11
+ tokenId: string
12
+ }
13
+
14
+ export function Evaluation({ poolInfo, tokenId }: Props): React.ReactElement {
15
+ const { checkingEA } = useEA()
16
+ const { account, chainId } = useWeb3React()
17
+
18
+ useEffect(() => {
19
+ if (account && chainId) {
20
+ checkingEA(
21
+ {
22
+ poolAddress: poolInfo.pool,
23
+ borrowerWalletAddress: account,
24
+ receivableAddress: poolInfo.assetAddress,
25
+ receivableParam: toBigNumber(tokenId).toHexString(),
26
+ },
27
+ WIDGET_STEP.ChooseAmount,
28
+ chainId === ChainEnum.Goerli,
29
+ )
30
+ }
31
+ }, [
32
+ account,
33
+ chainId,
34
+ checkingEA,
35
+ poolInfo.assetAddress,
36
+ poolInfo.pool,
37
+ tokenId,
38
+ ])
39
+
40
+ return (
41
+ <LoadingModal
42
+ title='Checking Invoice'
43
+ description='Checking if the invoice qualifies for factoring...'
44
+ />
45
+ )
46
+ }
@@ -0,0 +1,34 @@
1
+ import { PoolInfoType } from '@huma-finance/shared'
2
+ import React, { useCallback } from 'react'
3
+
4
+ import { useAppDispatch } from '../../../hooks/useRedux'
5
+ import { setError, setStep } from '../../../store/widgets.reducers'
6
+ import { WIDGET_STEP } from '../../../store/widgets.store'
7
+ import { AllowListModal } from '../../AllowListModal'
8
+
9
+ type Props = {
10
+ poolInfo: PoolInfoType
11
+ }
12
+
13
+ export function AllowList({ poolInfo }: Props): React.ReactElement | null {
14
+ const dispatch = useAppDispatch()
15
+
16
+ const handleSuccess = useCallback(() => {
17
+ dispatch(setStep(WIDGET_STEP.Evaluation))
18
+ }, [dispatch])
19
+
20
+ const handleError = useCallback(
21
+ (errorMessage: string) => {
22
+ dispatch(setError({ errorMessage }))
23
+ },
24
+ [dispatch],
25
+ )
26
+
27
+ return (
28
+ <AllowListModal
29
+ poolInfo={poolInfo}
30
+ handleSuccess={handleSuccess}
31
+ handleError={handleError}
32
+ />
33
+ )
34
+ }
@@ -0,0 +1,92 @@
1
+ import {
2
+ AccountStats,
3
+ PoolInfoType,
4
+ upScale,
5
+ useFeeManager,
6
+ } from '@huma-finance/shared'
7
+ import React, { useCallback, useState } from 'react'
8
+
9
+ import { useAppDispatch, useAppSelector } from '../../../hooks/useRedux'
10
+ import { setBorrowInfo } from '../../../store/widgets.reducers'
11
+ import { selectWidgetState } from '../../../store/widgets.selectors'
12
+ import { WIDGET_STEP } from '../../../store/widgets.store'
13
+ import { ChooseAmountModal } from '../../ChooseAmountModal'
14
+
15
+ type Props = {
16
+ poolInfo: PoolInfoType
17
+ accountStats: AccountStats
18
+ }
19
+
20
+ export function ChooseAmount({
21
+ poolInfo,
22
+ accountStats,
23
+ }: Props): React.ReactElement | null {
24
+ const dispatch = useAppDispatch()
25
+ const { creditRecord } = accountStats
26
+ const [chargedFees, setChargedFees] = useState(0)
27
+ const [currentAmount, setCurrentAmount] = useState(0)
28
+ const { approveInfo } = useAppSelector(selectWidgetState)
29
+ const { getFeesCharged } = useFeeManager(poolInfo.poolName, poolInfo.poolType)
30
+ const [remainder, setRemainder] = useState(approveInfo!.receivableAmount)
31
+
32
+ const getAvailableCreditLimit = () => {
33
+ if (approveInfo && creditRecord) {
34
+ const principal = creditRecord.unbilledPrincipal
35
+ .add(creditRecord.totalDue)
36
+ .sub(creditRecord.feesAndInterestDue)
37
+ .toNumber()
38
+ return Number(approveInfo.creditLimit) - principal
39
+ }
40
+ return 0
41
+ }
42
+
43
+ const handleChangeAmount = useCallback(
44
+ (newAmount: number) => {
45
+ if (approveInfo) {
46
+ setCurrentAmount(newAmount)
47
+ setChargedFees(getFeesCharged(newAmount))
48
+ setRemainder(Number(approveInfo.receivableAmount) - newAmount)
49
+ }
50
+ },
51
+ [approveInfo, getFeesCharged],
52
+ )
53
+
54
+ const handleAction = useCallback(() => {
55
+ dispatch(
56
+ setBorrowInfo({
57
+ borrowAmount: currentAmount,
58
+ borrowAmountBN: upScale(currentAmount, approveInfo?.tokenDecimal),
59
+ chargedFees,
60
+ remainder: Number(remainder!),
61
+ nextStep: WIDGET_STEP.ConfirmTransfer,
62
+ }),
63
+ )
64
+ }, [
65
+ approveInfo?.tokenDecimal,
66
+ chargedFees,
67
+ currentAmount,
68
+ dispatch,
69
+ remainder,
70
+ ])
71
+
72
+ if (!approveInfo) {
73
+ return null
74
+ }
75
+
76
+ return (
77
+ <ChooseAmountModal
78
+ title='Choose Amount'
79
+ description1='Access up to 80% of your invoice value'
80
+ description2='The remainder will be sent to your wallet when the invoice is paid'
81
+ sliderMax={getAvailableCreditLimit()}
82
+ currentAmount={currentAmount}
83
+ tokenSymbol={approveInfo.tokenSymbol}
84
+ topLeft='Fees'
85
+ topRight={`${chargedFees} ${approveInfo.tokenSymbol}`}
86
+ downLeft='Remainder'
87
+ downRight={`${remainder} ${approveInfo.tokenSymbol}`}
88
+ handleChangeAmount={handleChangeAmount}
89
+ handleAction={handleAction}
90
+ />
91
+ )
92
+ }