diff --git a/.gitignore b/.gitignore index 8131f50..09b63ac 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ +.env + # Logs logs *.log @@ -35,6 +37,8 @@ out/ # Docs docs/ +broadcast/ + # Dotenv file .env diff --git a/frontend/index.html b/frontend/index.html index b3a18a5..460ff8e 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -2,7 +2,6 @@ - diff --git a/frontend/package.json b/frontend/package.json index 9d99dc7..7298487 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -20,10 +20,15 @@ "dependencies": { "@rainbow-me/rainbowkit": "^1.1.1", "@vitejs/plugin-react-refresh": "^1.3.6", + "axios": "^1.5.1", "classnames": "^2.3.2", + "localforage": "^1.10.0", + "match-sorter": "^6.3.1", "react": "^18.2.0", "react-dom": "^18.2.0", + "react-router-dom": "^6.16.0", "react-transition-group": "^4.4.5", + "sort-by": "^1.2.0", "viem": "^1.15.4", "wagmi": "^1.4.3" }, diff --git a/frontend/public/assets/Logo.avif b/frontend/public/assets/Logo.avif new file mode 100644 index 0000000..7c8cbc6 Binary files /dev/null and b/frontend/public/assets/Logo.avif differ diff --git a/frontend/public/vite.svg b/frontend/public/vite.svg deleted file mode 100644 index e7b8dfb..0000000 --- a/frontend/public/vite.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 5ce2f1f..44f34c7 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -1,22 +1,17 @@ +import { createBrowserRouter, RouterProvider } from 'react-router-dom'; +import { PoolsPage } from 'Pages'; +import './index.scss'; import '@rainbow-me/rainbowkit/styles.css'; -import { ConnectButton } from '@rainbow-me/rainbowkit'; -import VersionInfo from './components/versionInfo/VersionInfo'; -import CreatePool from './components/createPool/CreatePool'; -function App() { - const versionGitTag = import.meta.env.VITE_REACT_APP_GIT_TAG; - const gitDate = import.meta.env.VITE_REACT_APP_GIT_DATE; - - console.log('VITE_REACT_APP_GIT_TAG - ', versionGitTag); - console.log('VITE_REACT_APP_GIT_DATE - ', gitDate); +const router = createBrowserRouter([ + { + path: '/', + element: , + }, +]); - return ( -
- - - {versionGitTag && gitDate && } -
- ); +function App() { + return ; } export default App; diff --git a/frontend/src/components/dateCell/dateCell.tsx b/frontend/src/components/dateCell/dateCell.tsx new file mode 100644 index 0000000..3f1f99f --- /dev/null +++ b/frontend/src/components/dateCell/dateCell.tsx @@ -0,0 +1,8 @@ +import { FC } from 'react'; +import { DateCellPropsI } from './dateCellProps'; +import { dateFromTimestamp } from 'Utils/dateFromTimestamp'; + +export const DateCell: FC = ({ cellValue }) => { + const formattedDate = dateFromTimestamp(cellValue); + return
{formattedDate}
; +}; diff --git a/frontend/src/components/dateCell/dateCellProps.ts b/frontend/src/components/dateCell/dateCellProps.ts new file mode 100644 index 0000000..6db5bef --- /dev/null +++ b/frontend/src/components/dateCell/dateCellProps.ts @@ -0,0 +1,3 @@ +export interface DateCellPropsI { + cellValue: number; +} diff --git a/frontend/src/components/dateCell/index.ts b/frontend/src/components/dateCell/index.ts new file mode 100644 index 0000000..e6db39c --- /dev/null +++ b/frontend/src/components/dateCell/index.ts @@ -0,0 +1 @@ +export * from './dateCell'; diff --git a/frontend/src/components/header/Header.module.scss b/frontend/src/components/header/Header.module.scss new file mode 100644 index 0000000..455db9e --- /dev/null +++ b/frontend/src/components/header/Header.module.scss @@ -0,0 +1,29 @@ +.header { + display: flex; + padding: 24px; + align-items: center; + align-self: stretch; + background: #1b1b1f; + box-shadow: + 0px 1px 2px 0px rgba(0, 0, 0, 0.3), + 0px 2px 6px 2px rgba(0, 0, 0, 0.15); + nav { + display: flex; + align-items: center; + gap: 10px; + margin-left: 96px; + margin-right: auto; + a { + padding: 8px; + border-radius: 4px; + background: var(--m-3-sys-dark-surface-container-high, #1b1b1f); + padding: 8px; + color: #c3c6cf; + + &.active { + background-color: #292a2d; + color: #a3cddc; + } + } + } +} diff --git a/frontend/src/components/header/Header.tsx b/frontend/src/components/header/Header.tsx new file mode 100644 index 0000000..2a4377b --- /dev/null +++ b/frontend/src/components/header/Header.tsx @@ -0,0 +1,23 @@ +import { FC } from 'react'; +import styles from './Header.module.scss'; +import { Link, useLocation } from 'react-router-dom'; +import { ConnectButton } from '@rainbow-me/rainbowkit'; + +export const Header: FC = () => { + const location = useLocation(); + const currentPath = location.pathname; + + return ( +
+ + + + + +
+ ); +}; diff --git a/frontend/src/components/header/index.ts b/frontend/src/components/header/index.ts new file mode 100644 index 0000000..266dec8 --- /dev/null +++ b/frontend/src/components/header/index.ts @@ -0,0 +1 @@ +export * from './Header'; diff --git a/frontend/src/components/icons/NavigateFirst/NavigateFirst.module.scss b/frontend/src/components/icons/NavigateFirst/NavigateFirst.module.scss new file mode 100644 index 0000000..3727aa1 --- /dev/null +++ b/frontend/src/components/icons/NavigateFirst/NavigateFirst.module.scss @@ -0,0 +1,8 @@ +.icon { + cursor: pointer; + &:hover { + path { + fill: #808080; + } + } +} diff --git a/frontend/src/components/icons/NavigateFirst/NavigateFirst.tsx b/frontend/src/components/icons/NavigateFirst/NavigateFirst.tsx new file mode 100644 index 0000000..854cdfa --- /dev/null +++ b/frontend/src/components/icons/NavigateFirst/NavigateFirst.tsx @@ -0,0 +1,20 @@ +import { FC } from 'react'; +import styles from './NavigateFirst.module.scss'; + +export const NavigateFirst: FC = () => { + return ( + + + + ); +}; diff --git a/frontend/src/components/icons/NavigateFirst/index.ts b/frontend/src/components/icons/NavigateFirst/index.ts new file mode 100644 index 0000000..ce4425d --- /dev/null +++ b/frontend/src/components/icons/NavigateFirst/index.ts @@ -0,0 +1 @@ +export * from './NavigateFirst'; diff --git a/frontend/src/components/icons/NavigatePrevious/NavigatePrevious.module.scss b/frontend/src/components/icons/NavigatePrevious/NavigatePrevious.module.scss new file mode 100644 index 0000000..3727aa1 --- /dev/null +++ b/frontend/src/components/icons/NavigatePrevious/NavigatePrevious.module.scss @@ -0,0 +1,8 @@ +.icon { + cursor: pointer; + &:hover { + path { + fill: #808080; + } + } +} diff --git a/frontend/src/components/icons/NavigatePrevious/NavigatePrevious.tsx b/frontend/src/components/icons/NavigatePrevious/NavigatePrevious.tsx new file mode 100644 index 0000000..4d87a6a --- /dev/null +++ b/frontend/src/components/icons/NavigatePrevious/NavigatePrevious.tsx @@ -0,0 +1,20 @@ +import { FC } from 'react'; +import styles from './NavigatePrevious.module.scss'; + +export const NavigatePrevious: FC = () => { + return ( + + + + ); +}; diff --git a/frontend/src/components/icons/NavigatePrevious/index.ts b/frontend/src/components/icons/NavigatePrevious/index.ts new file mode 100644 index 0000000..5fe1060 --- /dev/null +++ b/frontend/src/components/icons/NavigatePrevious/index.ts @@ -0,0 +1 @@ +export * from './NavigatePrevious'; diff --git a/frontend/src/components/icons/index.ts b/frontend/src/components/icons/index.ts new file mode 100644 index 0000000..88dfe17 --- /dev/null +++ b/frontend/src/components/icons/index.ts @@ -0,0 +1,2 @@ +export * from './NavigateFirst'; +export * from './NavigatePrevious'; diff --git a/frontend/src/components/index.ts b/frontend/src/components/index.ts new file mode 100644 index 0000000..935b4ff --- /dev/null +++ b/frontend/src/components/index.ts @@ -0,0 +1,4 @@ +export * from 'Components/table'; +export * from 'Components/pagination'; +export * from 'Components/header'; +export * from 'Components/dateCell'; diff --git a/frontend/src/components/pagination/Pagination.module.scss b/frontend/src/components/pagination/Pagination.module.scss new file mode 100644 index 0000000..1ddcd2a --- /dev/null +++ b/frontend/src/components/pagination/Pagination.module.scss @@ -0,0 +1,29 @@ +.pagination { + display: flex; + gap: 24px; + padding: 16px 20px; + justify-content: flex-end; + align-items: center; + .rowsCount { + display: flex; + gap: 8px; + align-items: center; + } + .pages { + display: flex; + gap: 4px; + align-items: center; + span { + font-size: 16px; + } + } + .icons { + display: flex; + gap: 24px; + align-items: center; + + .rotateRight { + transform: rotate(180deg); + } + } +} diff --git a/frontend/src/components/pagination/Pagination.tsx b/frontend/src/components/pagination/Pagination.tsx new file mode 100644 index 0000000..6270f92 --- /dev/null +++ b/frontend/src/components/pagination/Pagination.tsx @@ -0,0 +1,36 @@ +import { FC } from 'react'; +import styles from './Pagination.module.scss'; +import { PaginationPropsI } from './PaginationPropsI'; +import { NavigateFirst, NavigatePrevious } from 'Components/icons'; + +export const Pagination: FC = () => { + return ( +
+
+ Rows per page: + {/* todo: add drop down menu */} + + 10 + +
+
+ {/* todo: display current page and pages length */} + 1 + of + 1 +
+
+ + +
+ +
+
+ +
+
+
+ ); +}; diff --git a/frontend/src/components/pagination/PaginationPropsI.ts b/frontend/src/components/pagination/PaginationPropsI.ts new file mode 100644 index 0000000..469e211 --- /dev/null +++ b/frontend/src/components/pagination/PaginationPropsI.ts @@ -0,0 +1 @@ +export interface PaginationPropsI {} diff --git a/frontend/src/components/pagination/index.ts b/frontend/src/components/pagination/index.ts new file mode 100644 index 0000000..e016c96 --- /dev/null +++ b/frontend/src/components/pagination/index.ts @@ -0,0 +1 @@ +export * from './Pagination'; diff --git a/frontend/src/components/table/Table.module.scss b/frontend/src/components/table/Table.module.scss new file mode 100644 index 0000000..2a37fad --- /dev/null +++ b/frontend/src/components/table/Table.module.scss @@ -0,0 +1,80 @@ +@mixin dimmedText { + color: #c3c6cf; + font-family: Noto Sans; + font-size: 16px; + font-style: normal; + font-weight: 400; + line-height: 24px; + letter-spacing: 0.25px; +} + +@mixin text { + color: #fff; + text-align: right; + font-family: Noto Sans; + font-size: 16px; + font-style: normal; + font-weight: 600; + line-height: 24px; + letter-spacing: 0.25px; +} + +.tableContainer { + display: flex; + flex-direction: column; + padding: 0 24px; + width: 100%; + border-radius: 16px; + background: #1b1b1f; + box-shadow: + 0px 1px 3px 0px rgba(0, 0, 0, 0.3), + 0px 4px 8px 3px rgba(0, 0, 0, 0.15); + table { + width: 100%; + border-collapse: collapse; + border: none; + + thead, + tbody { + padding: 24px; + } + + thead { + tr { + border-bottom: 1px solid #a3cddc; + } + } + tbody { + tr:not(:last-child) { + border-bottom: 1px solid #43474e; + } + } + + th { + border: none; + padding: 22px 8px 22px; + text-align: left; + @include dimmedText; + } + td { + border: none; + padding: 22px 8px; + @include dimmedText; + } + + .center { + text-align: center; + } + .left { + text-align: left; + } + .right { + text-align: right; + } + + .tableFooter { + display: flex; + width: 100%; + } + } +} diff --git a/frontend/src/components/table/Table.tsx b/frontend/src/components/table/Table.tsx new file mode 100644 index 0000000..fece28c --- /dev/null +++ b/frontend/src/components/table/Table.tsx @@ -0,0 +1,35 @@ +import { TablePropsI } from './TableProps.ts'; +import styles from './Table.module.scss'; +import { FC } from 'react'; +// import axios from 'axios'; +// import { DateCell } from 'Components'; +// import { TPool } from 'src/pages/index.ts'; + +export const Table: FC = ({ tableData }) => { + return ( +
+ + + + {/* */} + + + + + + + {tableData.map((pool) => ( + + {/* */} + + + + + ))} + +
DateOperator feeanchor currencyAllowed Tokens
todo + + {String(pool.operatorFee) + '%'}{String(pool.anchorCurrency)}{String(pool.allowedTokens)}
+
+ ); +}; diff --git a/frontend/src/components/table/TableProps.ts b/frontend/src/components/table/TableProps.ts new file mode 100644 index 0000000..636c9ed --- /dev/null +++ b/frontend/src/components/table/TableProps.ts @@ -0,0 +1,8 @@ +export interface TablePropsI { + tableData: { + address: string; + operatorFee: number; + anchorCurrency: string; + allowedTokens: string[]; + }[]; +} diff --git a/frontend/src/components/table/index.ts b/frontend/src/components/table/index.ts new file mode 100644 index 0000000..75193ad --- /dev/null +++ b/frontend/src/components/table/index.ts @@ -0,0 +1 @@ +export * from './Table'; diff --git a/frontend/src/data/abi.ts b/frontend/src/data/abi.ts new file mode 100644 index 0000000..243d2a0 --- /dev/null +++ b/frontend/src/data/abi.ts @@ -0,0 +1,407 @@ +export const abi = [ + { + inputs: [ + { internalType: 'contract IERC20', name: 'anchorCurrency_', type: 'address' }, + { internalType: 'contract IERC20[]', name: 'tokens', type: 'address[]' }, + { internalType: 'uint256', name: 'operatorFee_', type: 'uint256' }, + { internalType: 'string', name: 'name_', type: 'string' }, + { internalType: 'string', name: 'symbol_', type: 'string' }, + ], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + inputs: [{ internalType: 'address', name: 'target', type: 'address' }], + name: 'AddressEmptyCode', + type: 'error', + }, + { + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'AddressInsufficientBalance', + type: 'error', + }, + { + inputs: [ + { internalType: 'address', name: 'spender', type: 'address' }, + { internalType: 'uint256', name: 'allowance', type: 'uint256' }, + { internalType: 'uint256', name: 'needed', type: 'uint256' }, + ], + name: 'ERC20InsufficientAllowance', + type: 'error', + }, + { + inputs: [ + { internalType: 'address', name: 'sender', type: 'address' }, + { internalType: 'uint256', name: 'balance', type: 'uint256' }, + { internalType: 'uint256', name: 'needed', type: 'uint256' }, + ], + name: 'ERC20InsufficientBalance', + type: 'error', + }, + { + inputs: [{ internalType: 'address', name: 'approver', type: 'address' }], + name: 'ERC20InvalidApprover', + type: 'error', + }, + { + inputs: [{ internalType: 'address', name: 'receiver', type: 'address' }], + name: 'ERC20InvalidReceiver', + type: 'error', + }, + { + inputs: [{ internalType: 'address', name: 'sender', type: 'address' }], + name: 'ERC20InvalidSender', + type: 'error', + }, + { + inputs: [{ internalType: 'address', name: 'spender', type: 'address' }], + name: 'ERC20InvalidSpender', + type: 'error', + }, + { + inputs: [ + { internalType: 'address', name: 'receiver', type: 'address' }, + { internalType: 'uint256', name: 'assets', type: 'uint256' }, + { internalType: 'uint256', name: 'max', type: 'uint256' }, + ], + name: 'ERC4626ExceededMaxDeposit', + type: 'error', + }, + { + inputs: [ + { internalType: 'address', name: 'receiver', type: 'address' }, + { internalType: 'uint256', name: 'shares', type: 'uint256' }, + { internalType: 'uint256', name: 'max', type: 'uint256' }, + ], + name: 'ERC4626ExceededMaxMint', + type: 'error', + }, + { + inputs: [ + { internalType: 'address', name: 'owner', type: 'address' }, + { internalType: 'uint256', name: 'shares', type: 'uint256' }, + { internalType: 'uint256', name: 'max', type: 'uint256' }, + ], + name: 'ERC4626ExceededMaxRedeem', + type: 'error', + }, + { + inputs: [ + { internalType: 'address', name: 'owner', type: 'address' }, + { internalType: 'uint256', name: 'assets', type: 'uint256' }, + { internalType: 'uint256', name: 'max', type: 'uint256' }, + ], + name: 'ERC4626ExceededMaxWithdraw', + type: 'error', + }, + { inputs: [], name: 'FailedInnerCall', type: 'error' }, + { inputs: [], name: 'MathOverflowedMulDiv', type: 'error' }, + { + inputs: [{ internalType: 'address', name: 'token', type: 'address' }], + name: 'SafeERC20FailedOperation', + type: 'error', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'owner', type: 'address' }, + { indexed: true, internalType: 'address', name: 'spender', type: 'address' }, + { indexed: false, internalType: 'uint256', name: 'value', type: 'uint256' }, + ], + name: 'Approval', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'sender', type: 'address' }, + { indexed: true, internalType: 'address', name: 'owner', type: 'address' }, + { indexed: false, internalType: 'uint256', name: 'assets', type: 'uint256' }, + { indexed: false, internalType: 'uint256', name: 'shares', type: 'uint256' }, + ], + name: 'Deposit', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'from', type: 'address' }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + { indexed: false, internalType: 'uint256', name: 'value', type: 'uint256' }, + ], + name: 'Transfer', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'sender', type: 'address' }, + { indexed: true, internalType: 'address', name: 'receiver', type: 'address' }, + { indexed: true, internalType: 'address', name: 'owner', type: 'address' }, + { indexed: false, internalType: 'uint256', name: 'assets', type: 'uint256' }, + { indexed: false, internalType: 'uint256', name: 'shares', type: 'uint256' }, + ], + name: 'Withdraw', + type: 'event', + }, + { + inputs: [ + { internalType: 'address', name: 'owner', type: 'address' }, + { internalType: 'address', name: 'spender', type: 'address' }, + ], + name: 'allowance', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + name: 'allowedTokens', + outputs: [{ internalType: 'contract IERC20', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'allowedTokensCount', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'allowedTokensList', + outputs: [{ internalType: 'contract IERC20[]', name: '', type: 'address[]' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'anchorCurrency', + outputs: [{ internalType: 'contract IERC20', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'spender', type: 'address' }, + { internalType: 'uint256', name: 'value', type: 'uint256' }, + ], + name: 'approve', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'asset', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'balanceOf', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'shares', type: 'uint256' }], + name: 'convertToAssets', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'assets', type: 'uint256' }], + name: 'convertToShares', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'decimals', + outputs: [{ internalType: 'uint8', name: '', type: 'uint8' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'assets', type: 'uint256' }, + { internalType: 'address', name: 'receiver', type: 'address' }, + ], + name: 'deposit', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'amount', type: 'uint256' }], + name: 'deposit', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'maxDeposit', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'maxMint', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'owner', type: 'address' }], + name: 'maxRedeem', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'owner', type: 'address' }], + name: 'maxWithdraw', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'shares', type: 'uint256' }, + { internalType: 'address', name: 'receiver', type: 'address' }, + ], + name: 'mint', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'name', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'operator', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'operatorFee', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { inputs: [], name: 'pause', outputs: [], stateMutability: 'nonpayable', type: 'function' }, + { + inputs: [{ internalType: 'uint256', name: 'assets', type: 'uint256' }], + name: 'previewDeposit', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'shares', type: 'uint256' }], + name: 'previewMint', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'shares', type: 'uint256' }], + name: 'previewRedeem', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'assets', type: 'uint256' }], + name: 'previewWithdraw', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'shares', type: 'uint256' }, + { internalType: 'address', name: 'receiver', type: 'address' }, + { internalType: 'address', name: 'owner', type: 'address' }, + ], + name: 'redeem', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'symbol', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalAssets', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalSupply', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'uint256', name: 'value', type: 'uint256' }, + ], + name: 'transfer', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'from', type: 'address' }, + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'uint256', name: 'value', type: 'uint256' }, + ], + name: 'transferFrom', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { inputs: [], name: 'unpause', outputs: [], stateMutability: 'nonpayable', type: 'function' }, + { + inputs: [{ internalType: 'uint256', name: 'amount', type: 'uint256' }], + name: 'withdraw', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'assets', type: 'uint256' }, + { internalType: 'address', name: 'receiver', type: 'address' }, + { internalType: 'address', name: 'owner', type: 'address' }, + ], + name: 'withdraw', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, +]; diff --git a/frontend/src/data/mockAvailablePools.json b/frontend/src/data/mockAvailablePools.json new file mode 100644 index 0000000..615801b --- /dev/null +++ b/frontend/src/data/mockAvailablePools.json @@ -0,0 +1,32 @@ +[ + { + "address": "0x4681de1e080e889fad73853fa7adaa0be39e433f", + "date":1696954119482, + "anchorCurrency" : "0x6265617665726275696c642e6f7267", + "tokens": ["0x6265617665726275696c642e6f7267","0x6265617665726275696c642e6f7267", "0x6265617665726275696c642e6f7267"], + "operatorFee": 12, + "total": 234500, + "profitPercent": 10, + "profit": 3453453 + }, + { + "address": "0x4681de1e080e889fad73853fa7adaa0be39e433f", + "date":1696954119482, + "anchorCurrency" : "0x6265617665726275696c642e6f7267", + "tokens": ["0x6265617665726275696c642e6f7267","0x6265617665726275696c642e6f7267", "0x6265617665726275696c642e6f7267"], + "operatorFee": 12, + "total": 234500, + "profitPercent": 10, + "profit" : 120000 + }, + { + "address": "0x4681de1e080e889fad73853fa7adaa0be39e433f", + "date":1696954119482, + "anchorCurrency" : "0x6265617665726275696c642e6f7267", + "tokens": ["0x6265617665726275696c642e6f7267","0x6265617665726275696c642e6f7267", "0x6265617665726275696c642e6f7267"], + "operatorFee": 12, + "total": 234500, + "profitPercent": 10, + "profit" : 30000 + } +] \ No newline at end of file diff --git a/frontend/src/index.scss b/frontend/src/index.scss index 684f2e9..8101b0d 100644 --- a/frontend/src/index.scss +++ b/frontend/src/index.scss @@ -30,7 +30,7 @@ body { font-weight: 400; line-height: 1.5; font-size: 16px; - background-color: var(--main-bg); + background-color: #131316; } #root { diff --git a/frontend/src/pages/PoolsPage/PoolsPage.module.scss b/frontend/src/pages/PoolsPage/PoolsPage.module.scss new file mode 100644 index 0000000..7f5d052 --- /dev/null +++ b/frontend/src/pages/PoolsPage/PoolsPage.module.scss @@ -0,0 +1,22 @@ +.poolPageContainer { + display: flex; + padding: 0 122px; + + .poolsPage { + display: flex; + flex-direction: column; + align-items: flex-start; + width: 100%; + + h1 { + margin-top: 32px; + margin-bottom: 24px; + color: #c7c6ca; + font-size: 16px; + font-style: normal; + font-weight: 600; + line-height: 24px; + letter-spacing: 0.25px; + } + } +} diff --git a/frontend/src/pages/PoolsPage/PoolsPage.tsx b/frontend/src/pages/PoolsPage/PoolsPage.tsx new file mode 100644 index 0000000..cdff087 --- /dev/null +++ b/frontend/src/pages/PoolsPage/PoolsPage.tsx @@ -0,0 +1,90 @@ +import { PoolsPagePropsI } from './PoolsPageProps.ts'; +import styles from './PoolsPage.module.scss'; +import { FC } from 'react'; +import { Header, Table } from 'Components'; +// import { abi } from '../../data/abi.ts'; +// import { publicClientViem } from '../../wagmiConfig.ts'; +// import { useContractRead } from 'wagmi'; + +export type TPool = { + address: string; + allowedTokens: string[]; + anchorCurrency: string; + operatorFee: number; +}; + +export const PoolsPage: FC = ({ poolsType }) => { + const tableData: TPool[] = [ + { + address: '0', + allowedTokens: ['0x606279b2c388ed37d0e5e52ea0d75eb2b539a57e'], + anchorCurrency: '0x606279b2c388ed37d0e5e52ea0d75eb2b539a57e', + operatorFee: 10, + }, + { + address: '1', + allowedTokens: ['0x606279b2c388ed37d0e5e52ea0d75eb2b539a57e'], + anchorCurrency: '0x606279b2c388ed37d0e5e52ea0d75eb2b539a57e', + operatorFee: 15, + }, + ]; + + //todo: improve the acquisition of contract data + // const contract = '0x606279b2c388ed37d0e5e52ea0d75eb2b539a57e'; + // const contractsList = [contract]; + + // useEffect(() => { + // // eslint-disable-next-line react-hooks/exhaustive-deps + // }, []); + + // const abi2 = [ + // 'function allowedTokensList() view returns (IERC20[] memory)', + // 'function anchorCurrency() view returns (IERC20)', + // 'function operatorFee() view returns (uint256);', + // ]; + // const wagmiContract = { + // address: contract, + // abi: abi2, + // } as const; + + // const [tableData, setTableData] = useState(null); + + // const getAllowedTokens = async () => { + // const { data } = useContractRead({ + // address: contract, + // abi: abi2, + // functionName: 'allowedTokensList', + // }); + // // return result[0].address; + // }; + + // const getAnchorCurrency = async () => { + // const result = contractsList.map((contract: string) => ({ + // address: contract, + // abi: abi2, + // functionName: 'anchorCurrency', + // })); + // return result[0].address; + // }; + + // const getOperatorFee = async () => { + // const result = contractsList.map((contract: string) => ({ + // address: contract, + // abi: abi2, + // functionName: 'operatorFee', + // })); + // }; + // const getPools = async () => {}; + + return ( + <> +
+
+
+

{poolsType}

+ {tableData && } + + + + ); +}; diff --git a/frontend/src/pages/PoolsPage/PoolsPageProps.ts b/frontend/src/pages/PoolsPage/PoolsPageProps.ts new file mode 100644 index 0000000..68c7ba0 --- /dev/null +++ b/frontend/src/pages/PoolsPage/PoolsPageProps.ts @@ -0,0 +1,3 @@ +export interface PoolsPagePropsI { + poolsType: string; +} diff --git a/frontend/src/pages/PoolsPage/index.ts b/frontend/src/pages/PoolsPage/index.ts new file mode 100644 index 0000000..f74905b --- /dev/null +++ b/frontend/src/pages/PoolsPage/index.ts @@ -0,0 +1 @@ +export * from './PoolsPage'; diff --git a/frontend/src/pages/index.ts b/frontend/src/pages/index.ts new file mode 100644 index 0000000..5f65636 --- /dev/null +++ b/frontend/src/pages/index.ts @@ -0,0 +1 @@ +export * from 'Pages/PoolsPage'; diff --git a/frontend/src/utils/dateFromTimestamp.ts b/frontend/src/utils/dateFromTimestamp.ts new file mode 100644 index 0000000..37639bc --- /dev/null +++ b/frontend/src/utils/dateFromTimestamp.ts @@ -0,0 +1,7 @@ +export const dateFromTimestamp = (timestamp: number) => { + const date = new Date(timestamp); + const day = date.getDate().toString().padStart(2, '0'); + const month = (date.getMonth() + 1).toString().padStart(2, '0'); + const year = date.getFullYear().toString().slice(-2); + return `${day}/${month}/${year}`; +}; diff --git a/frontend/src/wagmiConfig.ts b/frontend/src/wagmiConfig.ts index 8fb2803..5e7fd3b 100644 --- a/frontend/src/wagmiConfig.ts +++ b/frontend/src/wagmiConfig.ts @@ -1,16 +1,17 @@ import { publicProvider } from 'wagmi/providers/public'; -import { configureChains, createConfig, mainnet } from 'wagmi'; +import { configureChains, createConfig } from 'wagmi'; import { polygon } from '@wagmi/core/chains'; import { getDefaultWallets } from '@rainbow-me/rainbowkit'; -import { arbitrum, base, optimism, zora } from 'viem/chains'; import { PROJECT_ID } from './constants/constants'; +import { createPublicClient, http } from 'viem'; console.log('walletConnect PROJECT_ID: ', PROJECT_ID); -export const { chains, publicClient } = configureChains( - [mainnet, polygon, optimism, arbitrum, base, zora], - [publicProvider()] -); +export const { chains, publicClient } = configureChains([polygon], [publicProvider()]); +export const publicClientViem = createPublicClient({ + chain: polygon, + transport: http(), +}); const { connectors } = getDefaultWallets({ appName: 'profitpals', diff --git a/frontend/tsconfig.json b/frontend/tsconfig.json index 9995662..f42ed05 100644 --- a/frontend/tsconfig.json +++ b/frontend/tsconfig.json @@ -16,7 +16,19 @@ /* Linting */ "strict": true, - "noFallthroughCasesInSwitch": true + "noFallthroughCasesInSwitch": true, + "baseUrl": "./", + "paths": { + "src/*": [ "./src/*" ], + "Components/*": [ "./src/components/*" ], + "Components": [ "./src/components" ], + "Pages/*": [ "./src/pages/*" ], + "Pages": [ "./src/pages" ], + "Utils/*": [ "./src/utils/*" ], + "Utils": [ "./src/utils" ], + "Icons/*": [ "./src/icons/*" ], + "Icons": [ "./src/icons" ], + } }, "include": ["src"], "references": [{ "path": "./tsconfig.node.json" }] diff --git a/frontend/vite.config.ts b/frontend/vite.config.ts index 6f02fbe..116610d 100644 --- a/frontend/vite.config.ts +++ b/frontend/vite.config.ts @@ -1,5 +1,6 @@ import { defineConfig } from 'vite'; import react from '@vitejs/plugin-react'; +import * as path from 'path'; // https://vitejs.dev/config/ export default defineConfig({ @@ -8,5 +9,15 @@ export default defineConfig({ outDir: 'dist', assetsDir: 'assets', }, + + // base: './', + resolve: { + alias: { + Components: path.resolve(__dirname, './src/components'), + Pages: path.resolve(__dirname, './src/pages'), + Utils: path.resolve(__dirname, './src/utils'), + Icons: path.resolve(__dirname, './src/icons'), + }, + }, plugins: [react()], }); diff --git a/frontend/yarn.lock b/frontend/yarn.lock index 7aa20a6..94829dd 100644 --- a/frontend/yarn.lock +++ b/frontend/yarn.lock @@ -593,9 +593,9 @@ tslib "^2.6.0" "@rainbow-me/rainbowkit@^1.1.1": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@rainbow-me/rainbowkit/-/rainbowkit-1.1.1.tgz#be2b4ed95943d9d0ec1af4bb780bbb2663203d9e" - integrity sha512-6NGeH2SpJYolstt9RXU6XwmvyL29XKc6OYZtctvdM83F/WNkRX+ywwBrfNNES9BAS6QNdOnPa7nIu+ghtFBgnQ== + version "1.1.2" + resolved "https://registry.yarnpkg.com/@rainbow-me/rainbowkit/-/rainbowkit-1.1.2.tgz#733a2c864dd7dd3625ed54440a1ccb18b0636c72" + integrity sha512-yWxKDfHL4xDZJW34APGkmO2SkxjHwrEeAfvx6+137hWLttQwHcalG9nj4II8roYV2/2XJPmQsbEs7TM0rC0fOg== dependencies: "@vanilla-extract/css" "1.9.1" "@vanilla-extract/dynamic" "2.0.2" @@ -605,6 +605,11 @@ qrcode "1.5.0" react-remove-scroll "2.5.4" +"@remix-run/router@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@remix-run/router/-/router-1.9.0.tgz#9033238b41c4cbe1e961eccb3f79e2c588328cf6" + integrity sha512-bV63itrKBC0zdT27qYm6SDZHlkXwFL1xMBuhkn+X7l0+IIhNaH5wuuvZKp6eKhCD4KFhujhfhCT1YxXW6esUIA== + "@rollup/pluginutils@^4.1.1": version "4.2.1" resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-4.2.1.tgz#e6c6c3aba0744edce3fb2074922d3776c0af2a6d" @@ -931,9 +936,9 @@ integrity sha512-xPSg0jm4mqgEkNhowKgZFBNtwoEwF6gJ4Dhww+GFpm3IgtNseHQZ5IqdNwnquZEoANxyDAKDRAdVo4Z72VvD/g== "@types/node@*": - version "20.8.5" - resolved "https://registry.yarnpkg.com/@types/node/-/node-20.8.5.tgz#13352ae1f80032171616910e8aba2e3e52e57d96" - integrity sha512-SPlobFgbidfIeOYlzXiEjSYeIJiOCthv+9tSQVpvk4PAdIIc+2SmjNVzWXk9t0Y7dl73Zdf+OgXKHX9XtkqUpw== + version "20.8.6" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.8.6.tgz#0dbd4ebcc82ad0128df05d0e6f57e05359ee47fa" + integrity sha512-eWO4K2Ji70QzKUqRy6oyJWUeB7+g2cRagT3T/nxYibYcT4y2BDL8lqolRXjTHmkZCdJfIPaY73KbJAZmcryxTQ== dependencies: undici-types "~5.25.1" @@ -1690,6 +1695,11 @@ async-mutex@^0.2.6: dependencies: tslib "^2.0.0" +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== + atomic-sleep@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/atomic-sleep/-/atomic-sleep-1.0.0.tgz#eb85b77a601fc932cfe432c5acd364a9e2c9075b" @@ -1700,6 +1710,15 @@ available-typed-arrays@^1.0.5: resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7" integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== +axios@^1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/axios/-/axios-1.5.1.tgz#11fbaa11fc35f431193a9564109c88c1f27b585f" + integrity sha512-Q28iYCWzNHjAm+yEAot5QaAMxhMghWLFVf7rRdwhUI+c2jix2DUXjAHXVi+s1ibs3mjPO/cCgbA++3BjD0vP/A== + dependencies: + follow-redirects "^1.15.0" + form-data "^4.0.0" + proxy-from-env "^1.1.0" + balanced-match@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" @@ -1813,9 +1832,9 @@ buffer@6.0.3, buffer@^6.0.3, buffer@~6.0.3: ieee754 "^1.2.1" bufferutil@^4.0.1: - version "4.0.7" - resolved "https://registry.yarnpkg.com/bufferutil/-/bufferutil-4.0.7.tgz#60c0d19ba2c992dd8273d3f73772ffc894c153ad" - integrity sha512-kukuqc39WOHtdxtw4UScxF/WVnMFVSQVKhtx3AjZJzhd0RGZZldcrfSEbVsWWe6KNH253574cq5F+wpv0G9pJw== + version "4.0.8" + resolved "https://registry.yarnpkg.com/bufferutil/-/bufferutil-4.0.8.tgz#1de6a71092d65d7766c4d8a522b261a6e787e8ea" + integrity sha512-4T53u4PdgsXqKaIctwF8ifXlRTTmEPJ8iEPWFdGZvcf7sbwYo6FKFEX9eNNAnzFZ7EzJAQ3CJeOtCRA4rDp7Pw== dependencies: node-gyp-build "^4.3.0" @@ -1845,9 +1864,9 @@ camelcase@^5.0.0: integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== caniuse-lite@^1.0.30001541: - version "1.0.30001547" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001547.tgz#d4f92efc488aab3c7f92c738d3977c2a3180472b" - integrity sha512-W7CrtIModMAxobGhz8iXmDfuJiiKg1WADMO/9x7/CLNin5cpSbuBjooyoIUVB5eyCc36QuTVlkVa1iB2S5+/eA== + version "1.0.30001549" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001549.tgz#7d1a3dce7ea78c06ed72c32c2743ea364b3615aa" + integrity sha512-qRp48dPYSCYaP+KurZLhDYdVE+yEyht/3NlmcJgVQ2VMGt6JL36ndQ/7rgspdZsJuxDPFIo/OzBT2+GmIJ53BA== chalk@5.3.0: version "5.3.0" @@ -1965,6 +1984,13 @@ colorette@^2.0.20: resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.20.tgz#9eb793e6833067f7235902fcd3b09917a000a95a" integrity sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w== +combined-stream@^1.0.8: + version "1.0.8" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" + integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== + dependencies: + delayed-stream "~1.0.0" + commander@11.0.0: version "11.0.0" resolved "https://registry.yarnpkg.com/commander/-/commander-11.0.0.tgz#43e19c25dbedc8256203538e8d7e9346877a6f67" @@ -2088,6 +2114,11 @@ delay@^5.0.0: resolved "https://registry.yarnpkg.com/delay/-/delay-5.0.0.tgz#137045ef1b96e5071060dd5be60bf9334436bd1d" integrity sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw== +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== + detect-browser@5.3.0, detect-browser@^5.3.0: version "5.3.0" resolved "https://registry.yarnpkg.com/detect-browser/-/detect-browser-5.3.0.tgz#9705ef2bddf46072d0f7265a1fe300e36fe7ceca" @@ -2146,9 +2177,9 @@ eastasianwidth@^0.2.0: integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== electron-to-chromium@^1.4.535: - version "1.4.553" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.553.tgz#56fd65afddbd713c52f0e95d0223b3368f520865" - integrity sha512-HiRdtyKS2+VhiXvjhMvvxiMC33FJJqTA5EB2YHgFZW6v7HkK4Q9Ahv2V7O2ZPgAjw+MyCJVMQvigj13H8t+wvA== + version "1.4.554" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.554.tgz#04e09c2ee31dc0f1546174033809b54cc372740b" + integrity sha512-Q0umzPJjfBrrj8unkONTgbKQXzXRrH7sVV7D9ea2yBV3Oaogz991yhbpfvo2LMNkJItmruXTEzVpP9cp7vaIiQ== emoji-regex@^8.0.0: version "8.0.0" @@ -2544,6 +2575,11 @@ flatted@^3.2.9: resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.9.tgz#7eb4c67ca1ba34232ca9d2d93e9886e611ad7daf" integrity sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ== +follow-redirects@^1.15.0: + version "1.15.3" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.3.tgz#fe2f3ef2690afce7e82ed0b44db08165b207123a" + integrity sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q== + for-each@^0.3.3: version "0.3.3" resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e" @@ -2551,6 +2587,15 @@ for-each@^0.3.3: dependencies: is-callable "^1.1.3" +form-data@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" + integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.8" + mime-types "^2.1.12" + fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" @@ -2746,6 +2791,11 @@ ignore@^5.2.0, ignore@^5.2.4: resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324" integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== +immediate@~3.0.5: + version "3.0.6" + resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.0.6.tgz#9db1dbd0faf8de6fbe0f5dd5e56bb606280de69b" + integrity sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ== + immutable@^4.0.0: version "4.3.4" resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.3.4.tgz#2e07b33837b4bb7662f288c244d1ced1ef65a78f" @@ -3016,6 +3066,13 @@ levn@^0.4.1: prelude-ls "^1.2.1" type-check "~0.4.0" +lie@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/lie/-/lie-3.1.1.tgz#9a436b2cc7746ca59de7a41fa469b3efb76bd87e" + integrity sha512-RiNhHysUjhrDQntfYSfY4MU24coXXdEOgw9WGcKHNeEwffDYbF//u87M1EWaMGzuFoSbqW0C9C6lEEhDOAswfw== + dependencies: + immediate "~3.0.5" + lilconfig@2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-2.1.0.tgz#78e23ac89ebb7e1bfbf25b18043de756548e7f52" @@ -3074,6 +3131,13 @@ lit@2.8.0: lit-element "^3.3.0" lit-html "^2.8.0" +localforage@^1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/localforage/-/localforage-1.10.0.tgz#5c465dc5f62b2807c3a84c0c6a1b1b3212781dd4" + integrity sha512-14/H1aX7hzBBmmh7sGPd+AOMkkIrHM3Z1PAyGgZigA1H1p5O5ANnMyWzvpAETtG68/dC4pC0ncy3+PPGzXZHPg== + dependencies: + lie "3.1.1" + locate-path@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" @@ -3153,6 +3217,14 @@ make-plural@*: resolved "https://registry.yarnpkg.com/make-plural/-/make-plural-7.3.0.tgz#2889dbafca2fb097037c47967d3e3afa7e48a52c" integrity sha512-/K3BC0KIsO+WK2i94LkMPv3wslMrazrQhfi5We9fMbLlLjzoOSJWr7TAdupLlDWaJcWxwoNosBkhFDejiu5VDw== +match-sorter@^6.3.1: + version "6.3.1" + resolved "https://registry.yarnpkg.com/match-sorter/-/match-sorter-6.3.1.tgz#98cc37fda756093424ddf3cbc62bfe9c75b92bda" + integrity sha512-mxybbo3pPNuA+ZuCUhm5bwNkXrJTbsk5VWbR5wiwz/GC6LIiegBGn2w3O08UG/jdbYLinw51fSQ5xNU1U3MgBw== + dependencies: + "@babel/runtime" "^7.12.5" + remove-accents "0.4.2" + media-query-parser@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/media-query-parser/-/media-query-parser-2.0.2.tgz#ff79e56cee92615a304a1c2fa4f2bd056c0a1d29" @@ -3178,6 +3250,18 @@ micromatch@4.0.5, micromatch@^4.0.4: braces "^3.0.2" picomatch "^2.3.1" +mime-db@1.52.0: + version "1.52.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" + integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== + +mime-types@^2.1.12: + version "2.1.35" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" + integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== + dependencies: + mime-db "1.52.0" + mimic-fn@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" @@ -3284,9 +3368,14 @@ object-assign@^4.1.1: integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== object-inspect@^1.9.0: - version "1.12.3" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.3.tgz#ba62dffd67ee256c8c086dfae69e016cd1f198b9" - integrity sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g== + version "1.13.0" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.0.tgz#42695d3879e1cd5bda6df5062164d80c996e23e2" + integrity sha512-HQ4J+ic8hKrgIt3mqk6cVOVrW2ozL4KdvHlqpBv9vDYWx9ysAgENAdvy4FoGF+KFdhR7nQTNm5J0ctAeOwn+3g== + +object-path@0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/object-path/-/object-path-0.6.0.tgz#b69a7d110937934f336ca561fd9be1ad7b7e0cb7" + integrity sha512-fxrwsCFi3/p+LeLOAwo/wyRMODZxdGBtUlWRzsEpsUVrisZbEfZ21arxLGfaWfcnqb8oHPNihIb4XPE8CQPN5A== on-exit-leak-free@^0.2.0: version "0.2.0" @@ -3549,6 +3638,11 @@ proxy-compare@2.5.1: resolved "https://registry.yarnpkg.com/proxy-compare/-/proxy-compare-2.5.1.tgz#17818e33d1653fbac8c2ec31406bce8a2966f600" integrity sha512-oyfc0Tx87Cpwva5ZXezSp5V9vht1c7dZBhvuV/y3ctkgMVUmiAGDVeeB0dKhGSyT0v1ZTEQYpe/RXlBVBNuCLA== +proxy-from-env@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" + integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== + punycode@^2.1.0: version "2.3.0" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.0.tgz#f67fa67c94da8f4d0cfff981aee4118064199b8f" @@ -3660,6 +3754,21 @@ react-remove-scroll@2.5.4: use-callback-ref "^1.3.0" use-sidecar "^1.1.2" +react-router-dom@^6.16.0: + version "6.16.0" + resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-6.16.0.tgz#86f24658da35eb66727e75ecbb1a029e33ee39d9" + integrity sha512-aTfBLv3mk/gaKLxgRDUPbPw+s4Y/O+ma3rEN1u8EgEpLpPe6gNjIsWt9rxushMHHMb7mSwxRGdGlGdvmFsyPIg== + dependencies: + "@remix-run/router" "1.9.0" + react-router "6.16.0" + +react-router@6.16.0: + version "6.16.0" + resolved "https://registry.yarnpkg.com/react-router/-/react-router-6.16.0.tgz#abbf3d5bdc9c108c9b822a18be10ee004096fb81" + integrity sha512-VT4Mmc4jj5YyjpOi5jOf0I+TYzGpvzERy4ckNSvSh2RArv8LLoCxlsZ2D+tc7zgjxcY34oTz2hZaeX5RVprKqA== + dependencies: + "@remix-run/router" "1.9.0" + react-style-singleton@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/react-style-singleton/-/react-style-singleton-2.2.1.tgz#f99e420492b2d8f34d38308ff660b60d0b1205b4" @@ -3712,6 +3821,11 @@ regenerator-runtime@^0.14.0: resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz#5e19d68eb12d486f797e15a3c6a918f7cec5eb45" integrity sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA== +remove-accents@0.4.2: + version "0.4.2" + resolved "https://registry.yarnpkg.com/remove-accents/-/remove-accents-0.4.2.tgz#0a43d3aaae1e80db919e07ae254b285d9e1c7bb5" + integrity sha512-7pXIJqJOq5tFgG1A2Zxti3Ht8jJF337m4sowbuHsW30ZnkQFnDzy9qBNhgzX8ZLW4+UBcXiiR7SwR6pokHsxiA== + require-directory@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" @@ -3900,6 +4014,13 @@ sonic-boom@^2.2.1: dependencies: atomic-sleep "^1.0.0" +sort-by@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/sort-by/-/sort-by-1.2.0.tgz#ed92bbff9fd2284b41f6503e38496607b225fe6f" + integrity sha512-aRyW65r3xMnf4nxJRluCg0H/woJpksU1dQxRtXYzau30sNBOmf5HACpDd9MZDhKh7ALQ5FgSOfMPwZEtUmMqcg== + dependencies: + object-path "0.6.0" + "source-map-js@>=0.6.2 <2.0.0", source-map-js@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c"