@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,118 @@
1
+ import { MaxUint256 } from '@ethersproject/constants'
2
+ import { Box, css, useTheme } from '@mui/material'
3
+ import { useWeb3React } from '@web3-react/core'
4
+ import { BigNumber } from 'ethers'
5
+ import {
6
+ PoolInfoType,
7
+ sendTxAtom,
8
+ txAtom,
9
+ TxStateType,
10
+ useMount,
11
+ usePoolUnderlyingTokenContract,
12
+ } from '@huma-finance/shared'
13
+ import { useAtom } from 'jotai'
14
+ import { useResetAtom } from 'jotai/utils'
15
+ import React, { useCallback, useEffect } from 'react'
16
+
17
+ import { BottomButton } from './BottomButton'
18
+ import { AutoPaybackIcon } from './icons'
19
+ import { LoadingModal } from './LoadingModal'
20
+ import { ViewOnExplorer } from './ViewOnExplorer'
21
+ import { WrapperModal } from './WrapperModal'
22
+
23
+ type Props = {
24
+ poolInfo: PoolInfoType
25
+ showAutoPayback?: boolean
26
+ allowanceAmount?: BigNumber
27
+ handleSuccess: () => void
28
+ }
29
+
30
+ export function ApproveAllowanceModal({
31
+ poolInfo,
32
+ showAutoPayback = false,
33
+ allowanceAmount,
34
+ handleSuccess,
35
+ }: Props): React.ReactElement | null {
36
+ const theme = useTheme()
37
+ const { provider } = useWeb3React()
38
+ const { poolUnderlyingToken } = poolInfo
39
+ const { symbol } = poolUnderlyingToken
40
+ const poolUnderlyingTokenContract = usePoolUnderlyingTokenContract(
41
+ poolInfo.poolName,
42
+ poolInfo.poolType,
43
+ )
44
+ const reset = useResetAtom(txAtom)
45
+ const [{ state, txHash }, send] = useAtom(sendTxAtom)
46
+ const waitingForAccept = state === TxStateType.New
47
+
48
+ useEffect(() => {
49
+ if (state === TxStateType.Success) {
50
+ reset()
51
+ handleSuccess()
52
+ }
53
+ }, [handleSuccess, reset, state, symbol])
54
+
55
+ const styles = {
56
+ iconWrapper: css`
57
+ ${theme.cssMixins.rowCentered};
58
+ margin-top: 30px;
59
+ `,
60
+ description: css`
61
+ margin-top: 14px;
62
+ font-family: 'Uni-Neue-Regular';
63
+ font-size: 16px;
64
+ color: #a8a1b2;
65
+ padding: 0 12px;
66
+ `,
67
+ }
68
+
69
+ const sendApprove = useCallback(() => {
70
+ send({
71
+ contract: poolUnderlyingTokenContract!,
72
+ method: 'approve',
73
+ params: [poolInfo.pool, allowanceAmount ?? MaxUint256],
74
+ provider,
75
+ })
76
+ }, [
77
+ allowanceAmount,
78
+ poolInfo.pool,
79
+ poolUnderlyingTokenContract,
80
+ provider,
81
+ send,
82
+ ])
83
+
84
+ useMount(() => {
85
+ if (!showAutoPayback) {
86
+ sendApprove()
87
+ }
88
+ })
89
+
90
+ if (showAutoPayback && waitingForAccept) {
91
+ return (
92
+ <WrapperModal
93
+ title='Auto Payback'
94
+ subTitle='Enable auto payback and never miss payments. You only need to do it once.'
95
+ >
96
+ <Box css={styles.iconWrapper}>
97
+ <AutoPaybackIcon />
98
+ </Box>
99
+ <Box css={styles.description}>
100
+ This allowance transaction removes the need to confirm follow up{' '}
101
+ {symbol} transactions. Gas is on us.
102
+ </Box>
103
+ <BottomButton variant='contained' onClick={sendApprove}>
104
+ APPROVE {symbol} PAYMENTS
105
+ </BottomButton>
106
+ </WrapperModal>
107
+ )
108
+ }
109
+
110
+ return (
111
+ <LoadingModal
112
+ title={`Approve ${symbol}`}
113
+ description='Waiting for approval confirmation...'
114
+ >
115
+ <ViewOnExplorer txHash={txHash} />
116
+ </LoadingModal>
117
+ )
118
+ }
@@ -0,0 +1,31 @@
1
+ import { Box, Button, css } from '@mui/material'
2
+ import React from 'react'
3
+
4
+ import { WCProps } from '../utilTypes'
5
+
6
+ type Props = {
7
+ variant: 'contained' | 'outlined'
8
+ onClick?: () => void
9
+ }
10
+
11
+ export function BottomButton({
12
+ variant,
13
+ onClick,
14
+ children,
15
+ }: WCProps<Props>): React.ReactElement {
16
+ const styles = css`
17
+ & .MuiButtonBase-root {
18
+ width: 100%;
19
+ position: absolute;
20
+ bottom: 0;
21
+ }
22
+ `
23
+
24
+ return (
25
+ <Box css={styles}>
26
+ <Button variant={variant} onClick={onClick}>
27
+ {children}
28
+ </Button>
29
+ </Box>
30
+ )
31
+ }
@@ -0,0 +1,315 @@
1
+ import ArrowDropDownIcon from '@mui/icons-material/ArrowDropDown'
2
+ import ArrowDropUpIcon from '@mui/icons-material/ArrowDropUp'
3
+ import {
4
+ Box,
5
+ Button,
6
+ css,
7
+ Divider,
8
+ Input,
9
+ Slider,
10
+ useTheme,
11
+ } from '@mui/material'
12
+ import { useMQ } from '@huma-finance/shared'
13
+ import React from 'react'
14
+
15
+ import { IconType } from '../utilTypes'
16
+ import { WrapperModal } from './WrapperModal'
17
+
18
+ type Props = {
19
+ title: string
20
+ tokenIcon?: IconType
21
+ description1?: string
22
+ description2?: string
23
+ currentAmount: number
24
+ sliderMax: number
25
+ tokenSymbol: string
26
+ topLeft?: string
27
+ topRight?: string
28
+ downLeft?: string
29
+ downRight?: string
30
+ actionText?: string
31
+ hideTerms?: boolean
32
+ payoffAmount?: number
33
+ type?: 'slider' | 'input'
34
+ handleChangeAmount: (amount: number) => void
35
+ handleAction: () => void
36
+ }
37
+
38
+ export function ChooseAmountModal({
39
+ title,
40
+ tokenIcon,
41
+ description1,
42
+ description2,
43
+ currentAmount,
44
+ sliderMax,
45
+ tokenSymbol,
46
+ topLeft,
47
+ topRight,
48
+ downLeft,
49
+ downRight,
50
+ actionText = 'accept terms',
51
+ payoffAmount,
52
+ hideTerms = false,
53
+ type = 'slider',
54
+ handleChangeAmount,
55
+ handleAction,
56
+ }: Props): React.ReactElement {
57
+ const theme = useTheme()
58
+ const { isXsSize } = useMQ()
59
+
60
+ const styles = {
61
+ subTitle: css`
62
+ font-family: 'Uni-Neue-Regular';
63
+ `,
64
+ description2: css`
65
+ ${theme.cssMixins.rowCentered};
66
+ font-family: 'Uni-Neue-Regular';
67
+ font-size: 16px;
68
+ color: #a8a1b2;
69
+ margin-top: 16px;
70
+ `,
71
+ chosenAmountWrapper: css`
72
+ ${theme.cssMixins.rowCentered};
73
+ background: linear-gradient(232.71deg, #a363f4 4.17%, #ff6a8a 178.69%);
74
+ background-clip: text;
75
+ -webkit-text-fill-color: transparent;
76
+ font-weight: 700;
77
+ font-size: 32px;
78
+ margin-bottom: 10px;
79
+ margin-top: 30px;
80
+ `,
81
+ chosenAmount: css`
82
+ font-family: 'Inter-Bold';
83
+ font-size: 32px;
84
+ `,
85
+ chosenAmountSymbol: css`
86
+ font-size: 75%;
87
+ margin-left: 5px;
88
+ letter-spacing: 0.1px;
89
+ `,
90
+ inputAmountWrapper: css`
91
+ margin-bottom: 10px;
92
+ margin-top: 30px;
93
+ `,
94
+ inputAmount: css`
95
+ ${theme.cssMixins.rowSpaceBetweened};
96
+ `,
97
+ inputField: css`
98
+ width: 100%;
99
+ `,
100
+ maxButton: css`
101
+ width: 80px;
102
+ `,
103
+ amountAvailable: css`
104
+ ${theme.cssMixins.rowVCentered};
105
+ margin-top: 5px;
106
+ margin-bottom: 100px;
107
+ font-size: 16px;
108
+ & > svg {
109
+ margin-right: 5px;
110
+ }
111
+ `,
112
+ tokenIcon: {
113
+ width: '16px',
114
+ height: '16px',
115
+ },
116
+ editIcon: css`
117
+ color: ${theme.palette.primary.main};
118
+ cursor: pointer;
119
+ display: inline-grid;
120
+ vertical-align: middle;
121
+ & > svg {
122
+ font-size: 24px;
123
+ }
124
+ & > svg:first-of-type {
125
+ margin-bottom: -10px;
126
+ }
127
+ `,
128
+ input: css`
129
+ font-size: 18px;
130
+ -webkit-text-fill-color: ${theme.palette.primary.main};
131
+ `,
132
+ slider: css`
133
+ margin-bottom: 54px;
134
+ &.MuiSlider-root {
135
+ height: 8px !important;
136
+ color: #e9e9e9;
137
+ }
138
+ & .MuiSlider-track {
139
+ height: 8px !important;
140
+ background: linear-gradient(232.71deg, #a363f4 4.17%, #ff6a8a 178.69%);
141
+ border-radius: 8px;
142
+ }
143
+ & .MuiSlider-thumb::before {
144
+ background: #ffffff;
145
+ border: 1px solid #f9f9f9;
146
+ box-shadow: 1px 1px 12px 2px rgba(163, 100, 244, 0.6);
147
+ border-radius: 50px;
148
+ width: 24px;
149
+ height: 24px;
150
+ }
151
+ `,
152
+ info: css`
153
+ font-family: 'Uni-Neue-Regular';
154
+ ${theme.cssMixins.rowSpaceBetweened};
155
+ font-weight: 400;
156
+ font-size: 16px;
157
+ color: #423b46;
158
+ `,
159
+ divider: css`
160
+ margin: 16px 0;
161
+ background: #49505b;
162
+ border-color: #e9e3f1;
163
+ `,
164
+ okButton: css`
165
+ font-family: 'Uni-Neue-Bold';
166
+ width: 100%;
167
+ position: absolute;
168
+ bottom: ${isXsSize ? 20 : 0}px;
169
+ `,
170
+ terms: css`
171
+ ${theme.cssMixins.rowHCentered};
172
+ font-weight: 400;
173
+ font-size: 12px;
174
+ color: #a8a1b2;
175
+ margin-top: 8px;
176
+ letter-spacing: 0px;
177
+ width: 100%;
178
+ position: absolute;
179
+ bottom: -22px;
180
+ `,
181
+ }
182
+
183
+ const handleSliderChange = (event: Event, newValue: number | number[]) => {
184
+ handleChangeAmount(newValue as number)
185
+ }
186
+
187
+ const handleInputChange = (
188
+ event: React.ChangeEvent<HTMLTextAreaElement | HTMLInputElement>,
189
+ ) => {
190
+ // @ts-ignore
191
+ handleChangeAmount(event.target.value)
192
+ }
193
+
194
+ const handleSetMax = () => {
195
+ handleChangeAmount(sliderMax)
196
+ }
197
+
198
+ const handleIncrement = () => {
199
+ const newAmount = currentAmount + 1
200
+ if (newAmount <= sliderMax) {
201
+ handleChangeAmount(newAmount)
202
+ }
203
+ }
204
+
205
+ const handleDecrement = () => {
206
+ const newAmount = currentAmount - 1
207
+ if (newAmount >= 0) {
208
+ handleChangeAmount(newAmount)
209
+ }
210
+ }
211
+
212
+ const handlePayoff = () => {
213
+ if (payoffAmount) {
214
+ handleChangeAmount(payoffAmount)
215
+ }
216
+ }
217
+
218
+ const subTitle = (
219
+ <Box component='span'>
220
+ <Box component='span' css={styles.subTitle}>
221
+ {description1}
222
+ </Box>
223
+ {payoffAmount && (
224
+ <Button
225
+ sx={{ fontSize: '12px' }}
226
+ variant='text'
227
+ size='small'
228
+ onClick={handlePayoff}
229
+ className='choose-amount-modal-select-payoff-btn'
230
+ >
231
+ Pay Off
232
+ </Button>
233
+ )}
234
+ </Box>
235
+ )
236
+
237
+ return (
238
+ <WrapperModal title={title} subTitle={subTitle}>
239
+ {type === 'slider' && (
240
+ <>
241
+ <Box css={styles.chosenAmountWrapper}>
242
+ <Box css={styles.chosenAmount}>
243
+ {Number(currentAmount).toFixed(2)}
244
+ <Box component='span' css={styles.chosenAmountSymbol}>
245
+ {tokenSymbol}
246
+ </Box>
247
+ <Box component='span' css={styles.editIcon}>
248
+ <ArrowDropUpIcon
249
+ onClick={handleIncrement}
250
+ className='choose-amount-modal-increment-icon'
251
+ />
252
+ <ArrowDropDownIcon onClick={handleDecrement} />
253
+ </Box>
254
+ </Box>
255
+ </Box>
256
+ <Slider
257
+ max={sliderMax}
258
+ min={0}
259
+ css={styles.slider}
260
+ aria-label='Amount'
261
+ value={currentAmount}
262
+ onChange={handleSliderChange}
263
+ />
264
+ </>
265
+ )}
266
+ {type === 'input' && (
267
+ <Box css={styles.inputAmountWrapper}>
268
+ <Box css={styles.inputAmount}>
269
+ <Input
270
+ css={styles.inputField}
271
+ type='number'
272
+ value={currentAmount}
273
+ onChange={handleInputChange}
274
+ />
275
+ <Button
276
+ variant='contained'
277
+ css={styles.maxButton}
278
+ onClick={handleSetMax}
279
+ >
280
+ Max
281
+ </Button>
282
+ </Box>
283
+ <Box css={styles.amountAvailable}>
284
+ {tokenIcon && React.createElement(tokenIcon, styles.tokenIcon)}
285
+ <Box>{Number(sliderMax).toFixed(2)} Available</Box>
286
+ </Box>
287
+ </Box>
288
+ )}
289
+ <Box css={styles.info}>
290
+ <Box>{topLeft}</Box>
291
+ <Box>{topRight}</Box>
292
+ </Box>
293
+ {topLeft && downLeft && <Divider css={styles.divider} />}
294
+ <Box css={styles.info}>
295
+ <Box>{downLeft}</Box>
296
+ <Box>{downRight}</Box>
297
+ </Box>
298
+ <Box css={styles.description2}>{description2}</Box>
299
+ <Button
300
+ className='choose-amount-modal-action-btn'
301
+ variant='contained'
302
+ css={styles.okButton}
303
+ onClick={handleAction}
304
+ disabled={currentAmount === 0 || currentAmount > sliderMax}
305
+ >
306
+ {actionText.toUpperCase()}
307
+ </Button>
308
+ {!hideTerms && (
309
+ <Box css={styles.terms}>
310
+ By clicking {actionText}, you agree to Huma’s Terms of Service.
311
+ </Box>
312
+ )}
313
+ </WrapperModal>
314
+ )
315
+ }
@@ -0,0 +1,159 @@
1
+ import { Box, Button, css, Typography, useTheme } from '@mui/material'
2
+ import { useWeb3React } from '@web3-react/core'
3
+ import { ChainEnum, PoolInfoType } from '@huma-finance/shared'
4
+ import React, { useEffect, useState } from 'react'
5
+
6
+ import useEA from '../../../hooks/useEA'
7
+ import { useAppDispatch } from '../../../hooks/useRedux'
8
+ import { setStep } from '../../../store/widgets.reducers'
9
+ import { WIDGET_STEP } from '../../../store/widgets.store'
10
+ import { CheckCircleIcon, CheckGreenIcon } from '../../icons'
11
+ import spinner from '../../icons/spinner.gif'
12
+
13
+ type Props = {
14
+ poolInfo: PoolInfoType
15
+ handleApprove: () => void
16
+ }
17
+
18
+ export function Evaluation({
19
+ poolInfo,
20
+ handleApprove,
21
+ }: Props): React.ReactElement {
22
+ const theme = useTheme()
23
+ const { checkingEA } = useEA()
24
+ const dispatch = useAppDispatch()
25
+ const { account, chainId } = useWeb3React()
26
+ const [status, setStatus] = useState<'checking' | 'success'>('checking')
27
+
28
+ useEffect(() => {
29
+ const fetchData = async () => {
30
+ if (account && chainId) {
31
+ await checkingEA(
32
+ {
33
+ poolAddress: poolInfo.pool,
34
+ borrowerWalletAddress: account,
35
+ receivableAddress: poolInfo.assetAddress,
36
+ },
37
+ WIDGET_STEP.Evaluation,
38
+ chainId === ChainEnum.Goerli,
39
+ )
40
+ handleApprove()
41
+ setStatus('success')
42
+ }
43
+ }
44
+ fetchData()
45
+ }, [
46
+ account,
47
+ chainId,
48
+ checkingEA,
49
+ handleApprove,
50
+ poolInfo.assetAddress,
51
+ poolInfo.pool,
52
+ ])
53
+
54
+ const styles = {
55
+ wrapper: css`
56
+ height: 518px;
57
+ position: relative;
58
+ `,
59
+ header: css`
60
+ ${theme.cssMixins.rowHCentered};
61
+ margin-top: -5px;
62
+ `,
63
+ content: css`
64
+ ${theme.cssMixins.rowHCentered};
65
+ margin-top: 30px;
66
+ font-family: 'Uni-Neue-Regular';
67
+ font-size: 16px;
68
+ line-height: 24px;
69
+ color: #49505b;
70
+ margin-bottom: 65px;
71
+ `,
72
+ checkWrapper: css`
73
+ ${theme.cssMixins.rowVCentered}
74
+ width: 100%;
75
+ height: 72px;
76
+ background: #f9f8fa;
77
+ border-radius: 4px;
78
+ font-family: 'Uni-Neue-Regular';
79
+ font-size: 16px;
80
+ color: #49505b;
81
+ `,
82
+ checkIcon: css`
83
+ ${theme.cssMixins.rowCentered}
84
+ width: 105px;
85
+ height: 100%;
86
+
87
+ & > img {
88
+ max-width: 100%;
89
+ max-height: 100%;
90
+ }
91
+ `,
92
+ congratsWrapper: css`
93
+ font-family: 'Uni-Neue-Regular';
94
+ font-size: 16px;
95
+ padding: 0 16px;
96
+ ${theme.cssMixins.rowVCentered}
97
+ margin-top: 60px;
98
+ height: 52px;
99
+ background: linear-gradient(
100
+ 0deg,
101
+ rgba(255, 255, 255, 0.9),
102
+ rgba(255, 255, 255, 0.9)
103
+ ),
104
+ #2e7d32;
105
+ border-radius: 4px;
106
+ `,
107
+ bottom: css`
108
+ & .MuiButtonBase-root {
109
+ width: 100%;
110
+ position: absolute;
111
+ bottom: 0;
112
+ }
113
+ `,
114
+ }
115
+
116
+ const goToNextStep = () => {
117
+ dispatch(setStep(WIDGET_STEP.ChooseAmount))
118
+ }
119
+
120
+ return (
121
+ <Box css={styles.wrapper}>
122
+ <Typography variant='h6' css={styles.header}>
123
+ Borrow
124
+ </Typography>
125
+ <Box css={styles.content}>
126
+ Looks like it’s your first time around here. Let’s see if you qualify...
127
+ </Box>
128
+ <Box css={styles.checkWrapper} sx={{ marginBottom: '16px' }}>
129
+ <Box css={styles.checkIcon}>
130
+ {status === 'checking' && <img src={spinner} alt='loading...' />}
131
+ {status === 'success' && <CheckGreenIcon />}
132
+ </Box>
133
+ <Box>Checking your income</Box>
134
+ </Box>
135
+ <Box css={styles.checkWrapper}>
136
+ <Box css={styles.checkIcon}>
137
+ {status === 'checking' && <img src={spinner} alt='loading...' />}
138
+ {status === 'success' && <CheckGreenIcon />}
139
+ </Box>
140
+ <Box>Checking other qualifications</Box>
141
+ </Box>
142
+ {status === 'success' && (
143
+ <>
144
+ <Box css={styles.congratsWrapper}>
145
+ <CheckCircleIcon />
146
+ <Box sx={{ marginLeft: '16px' }}>
147
+ Congrats, you are qualified to borrow
148
+ </Box>
149
+ </Box>
150
+ <Box css={styles.bottom}>
151
+ <Button variant='contained' onClick={goToNextStep}>
152
+ CONTINUE TO BORROW
153
+ </Button>
154
+ </Box>
155
+ </>
156
+ )}
157
+ </Box>
158
+ )
159
+ }
@@ -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
+ }