diff --git a/apps/dcellar-web-ui/next.config.js b/apps/dcellar-web-ui/next.config.js index f7180b99..9216ebdd 100644 --- a/apps/dcellar-web-ui/next.config.js +++ b/apps/dcellar-web-ui/next.config.js @@ -55,7 +55,7 @@ const nextConfig = { headers: async () => [ { // cache public folder assets (default max-age: 0). - source: `${assetPrefix}/:public(fonts|images|wasm|zk-main)/:path*`, + source: `${assetPrefix}/:public(fonts|images|wasm|zk-crypto)/:path*`, locale: false, headers: [ { diff --git a/apps/dcellar-web-ui/package.json b/apps/dcellar-web-ui/package.json index 4c2f892c..547b3939 100644 --- a/apps/dcellar-web-ui/package.json +++ b/apps/dcellar-web-ui/package.json @@ -18,8 +18,8 @@ "ahooks": "3.7.7", "hash-wasm": "4.9.0", "@babel/core": "^7.20.12", - "@bnb-chain/greenfield-js-sdk": "0.2.4-alpha.5", - "@bnb-chain/greenfield-cosmos-types": "0.4.0-alpha.18", + "@bnb-chain/greenfield-js-sdk": "0.2.4-alpha.26", + "@bnb-chain/greenfield-cosmos-types": "0.4.0-alpha.22", "@emotion/react": "^11.10.5", "@emotion/styled": "^11.10.5", "@next/bundle-analyzer": "^13.1.6", @@ -49,7 +49,8 @@ "react-redux": "^8.1.1", "next-redux-wrapper": "^8.1.0", "redux-persist": "^6.0.0", - "@wagmi/core": "^0.10.13" + "@wagmi/core": "^0.10.13", + "fast-xml-parser": "~4.2.7" }, "devDependencies": { "@babel/plugin-syntax-flow": "^7.14.5", diff --git a/apps/dcellar-web-ui/public/images/accounts/disable-account.svg b/apps/dcellar-web-ui/public/images/accounts/disable-account.svg new file mode 100644 index 00000000..8b75fba2 --- /dev/null +++ b/apps/dcellar-web-ui/public/images/accounts/disable-account.svg @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/dcellar-web-ui/public/images/accounts/empty-account.svg b/apps/dcellar-web-ui/public/images/accounts/empty-account.svg new file mode 100644 index 00000000..45bc128b --- /dev/null +++ b/apps/dcellar-web-ui/public/images/accounts/empty-account.svg @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/dcellar-web-ui/public/images/accounts/filled-account.svg b/apps/dcellar-web-ui/public/images/accounts/filled-account.svg new file mode 100644 index 00000000..b14ca3bb --- /dev/null +++ b/apps/dcellar-web-ui/public/images/accounts/filled-account.svg @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/dcellar-web-ui/public/images/accounts/logo-bsc.svg b/apps/dcellar-web-ui/public/images/accounts/logo-bsc.svg new file mode 100644 index 00000000..1fddc819 --- /dev/null +++ b/apps/dcellar-web-ui/public/images/accounts/logo-bsc.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/apps/dcellar-web-ui/public/images/icons/accounts.svg b/apps/dcellar-web-ui/public/images/icons/accounts.svg new file mode 100644 index 00000000..87cc1966 --- /dev/null +++ b/apps/dcellar-web-ui/public/images/icons/accounts.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/apps/dcellar-web-ui/public/images/icons/accounts_filled.svg b/apps/dcellar-web-ui/public/images/icons/accounts_filled.svg new file mode 100644 index 00000000..5dc04f87 --- /dev/null +++ b/apps/dcellar-web-ui/public/images/icons/accounts_filled.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/apps/dcellar-web-ui/public/images/icons/deposit.svg b/apps/dcellar-web-ui/public/images/icons/deposit.svg new file mode 100644 index 00000000..f7a7ad0f --- /dev/null +++ b/apps/dcellar-web-ui/public/images/icons/deposit.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/apps/dcellar-web-ui/public/images/icons/send.svg b/apps/dcellar-web-ui/public/images/icons/send.svg new file mode 100644 index 00000000..365b4ffb --- /dev/null +++ b/apps/dcellar-web-ui/public/images/icons/send.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/apps/dcellar-web-ui/public/images/icons/transfer-in.svg b/apps/dcellar-web-ui/public/images/icons/transfer-in.svg new file mode 100644 index 00000000..f1c4fc90 --- /dev/null +++ b/apps/dcellar-web-ui/public/images/icons/transfer-in.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/apps/dcellar-web-ui/public/images/icons/transfer-out.svg b/apps/dcellar-web-ui/public/images/icons/transfer-out.svg new file mode 100644 index 00000000..5562892b --- /dev/null +++ b/apps/dcellar-web-ui/public/images/icons/transfer-out.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/apps/dcellar-web-ui/public/images/icons/withdraw.svg b/apps/dcellar-web-ui/public/images/icons/withdraw.svg new file mode 100644 index 00000000..fb94f22f --- /dev/null +++ b/apps/dcellar-web-ui/public/images/icons/withdraw.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/apps/dcellar-web-ui/public/wasm/tinygo_init.js b/apps/dcellar-web-ui/public/wasm/tinygo_init.js index e47dbf76..ca1ecb43 100644 --- a/apps/dcellar-web-ui/public/wasm/tinygo_init.js +++ b/apps/dcellar-web-ui/public/wasm/tinygo_init.js @@ -8,7 +8,7 @@ if (!WebAssembly.instantiateStreaming) { (async () => { const go = new Go(); - const moduleBytes = fetch(`${window.__ASSET_PREFIX}/wasm/zk.wasm`); + const moduleBytes = fetch(`${window.__ASSET_PREFIX}/wasm/zk-crypto.wasm`); const module = await WebAssembly.instantiateStreaming(moduleBytes, go.importObject); go.run(module.instance); diff --git a/apps/dcellar-web-ui/public/wasm/zk.wasm b/apps/dcellar-web-ui/public/wasm/zk-crypto.wasm similarity index 61% rename from apps/dcellar-web-ui/public/wasm/zk.wasm rename to apps/dcellar-web-ui/public/wasm/zk-crypto.wasm index 1ce7b035..f45033bd 100755 Binary files a/apps/dcellar-web-ui/public/wasm/zk.wasm and b/apps/dcellar-web-ui/public/wasm/zk-crypto.wasm differ diff --git a/apps/dcellar-web-ui/src/base/theme/antd.ts b/apps/dcellar-web-ui/src/base/theme/antd.ts index 9725aef6..14696ead 100644 --- a/apps/dcellar-web-ui/src/base/theme/antd.ts +++ b/apps/dcellar-web-ui/src/base/theme/antd.ts @@ -11,4 +11,9 @@ export const theme: ThemeConfig = { colorTextHeading: '#76808F', fontFamily: 'Inter, sans-serif', }, + components: { + Tooltip: { + zIndexPopup: 1600, + }, + }, }; diff --git a/apps/dcellar-web-ui/src/base/theme/index.ts b/apps/dcellar-web-ui/src/base/theme/index.ts index 8378a92a..e4620cd1 100644 --- a/apps/dcellar-web-ui/src/base/theme/index.ts +++ b/apps/dcellar-web-ui/src/base/theme/index.ts @@ -22,6 +22,11 @@ export const theme = { top: 65, maxW: '500px', }, + '.ui-drawer .ui-drawer-body': { + width: 'calc(100% + 48px)', + marginLeft: -24, + padding: '0 24px', + }, }, }, }, diff --git a/apps/dcellar-web-ui/src/components/ConnectWallet/WalletConnectModal.tsx b/apps/dcellar-web-ui/src/components/ConnectWallet/WalletConnectModal.tsx index 70d1b9fb..a9efa193 100644 --- a/apps/dcellar-web-ui/src/components/ConnectWallet/WalletConnectModal.tsx +++ b/apps/dcellar-web-ui/src/components/ConnectWallet/WalletConnectModal.tsx @@ -9,8 +9,6 @@ import { useWallet } from '@/context/WalletConnectContext/hooks/useWallet'; import { GREENFIELD_CHAIN_ID } from '@/base/env'; import { useCallback, useEffect, useState } from 'react'; import { ConnectorNotFoundError } from 'wagmi'; -import { InjectedConnector } from 'wagmi/connectors/injected'; -import { MetaMaskConnector } from 'wagmi/connectors/metaMask'; import { useAppLogin } from '@/modules/welcome/hooks/useAppLogin'; import { useAppSelector } from '@/store'; @@ -32,10 +30,10 @@ export function WalletConnectModal(props: WalletConnectModalProps) { if (err instanceof ConnectorNotFoundError) { const { connector } = args; - if (connector instanceof MetaMaskConnector) { - window.open(METAMASK_DOWNLOAD_URL, '_blank'); - } else if (connector instanceof InjectedConnector && connector.name === 'Trust Wallet') { + if (connector.id === 'trust') { window.open(TRUST_WALLET_DOWNLOAD_URL, '_blank'); + } else if (connector.id === 'metaMask') { + window.open(METAMASK_DOWNLOAD_URL, '_blank'); } } }, []); diff --git a/apps/dcellar-web-ui/src/components/common/CopyText/index.tsx b/apps/dcellar-web-ui/src/components/common/CopyText/index.tsx index 72bf7f0c..e241427a 100644 --- a/apps/dcellar-web-ui/src/components/common/CopyText/index.tsx +++ b/apps/dcellar-web-ui/src/components/common/CopyText/index.tsx @@ -36,9 +36,11 @@ export function CopyText(props: CopyTextProps) { lineHeight="20px" fontWeight={500} {...restProps} + onClick={(e) => { + e.stopPropagation(); + }} > {children} - ; gaClickCloseName?: string; + showCloseBtn?: boolean; } export const DCDrawer = (props: DCDrawerProps) => { - const { children, gaShowName, gaShowData, gaClickCloseName, onClose, ...restProps } = props; + const { + children, + gaShowName, + gaShowData, + gaClickCloseName, + onClose, + showCloseBtn = true, + ...restProps + } = props; const onBeforeClose = () => { if (gaClickCloseName) { @@ -30,6 +39,7 @@ export const DCDrawer = (props: DCDrawerProps) => { rootProps={{ top: 64.5 }} {...restProps} > + {showCloseBtn && } {children} diff --git a/apps/dcellar-web-ui/src/components/common/DCInputSelect/index.tsx b/apps/dcellar-web-ui/src/components/common/DCInputSelect/index.tsx new file mode 100644 index 00000000..7ddfc9de --- /dev/null +++ b/apps/dcellar-web-ui/src/components/common/DCInputSelect/index.tsx @@ -0,0 +1,231 @@ +import { MenuCloseIcon, SearchIcon } from '@totejs/icons'; +import { + Box, + BoxProps, + Input, + InputGroup, + InputRightElement, + Menu, + MenuButton, + MenuItem, + MenuItemProps, + MenuList, + MenuListProps, + MenuProps, + rgba, + useDisclosure, + InputProps, +} from '@totejs/uikit'; +import React, { useEffect, useRef, useState } from 'react'; + +import { useKeyDown } from '@/hooks/useKeyDown'; +import { useSaveFuncRef } from '@/hooks/useSaveFuncRef'; +import { GAClick } from '@/components/common/GATracker'; + +interface ListItemProps extends MenuItemProps { + gaClickName?: string; +} + +export interface IDCSelectOption { + label: React.ReactNode; + value: any; + [x: string]: any; +} + +export interface DCSelectProps extends MenuProps { + header?: React.ReactNode; + Footer?: () => JSX.Element; + value?: string; + text: string; + placeholder?: string; + options?: Array; + headerProps?: BoxProps; + listProps?: MenuListProps; + itemProps?: ListItemProps; + onChange?: (value: any) => void; + onSearchFilter?: (value: string, item: IDCSelectOption) => boolean; + onSearch?: (result: Array) => void; +} + +export function DCInputSelect(props: DCSelectProps) { + const { + value, + text, + placeholder, + options = [], + listProps, + itemProps, + headerProps, + header, + Footer, + onChange, + onSearchFilter, + onSearch, + children, + isDisabled, + ...restProps + } = props; + + const { isOpen, onClose, onOpen } = useDisclosure(); + const [resultOptions, setResultOptions] = useState>(); + + const saveOnSearchRef = useSaveFuncRef(onSearch); + useEffect(() => { + if (isOpen) { + setResultOptions(options); + saveOnSearchRef.current?.(options); + } + }, [isOpen, options, saveOnSearchRef]); + + const onEnter = () => { + if (resultOptions?.length) { + onSelectItem(resultOptions[0]); + onClose(); + } + }; + + const onSelectItem = (item: IDCSelectOption) => { + onChange?.(item.value); + }; + + const onChangeKeyword = (value: string) => { + const result: Array = value ? [] : options; + if (value) { + options.forEach((item) => { + if (onSearchFilter?.(value, item)) { + result.push(item); + } + }); + } + onChange?.(value); + setResultOptions(result); + onSearch?.(result); + }; + + return ( + + + {!!resultOptions?.length && ( + + {header && ( + + {header} + + )} + + {resultOptions?.map((item) => { + const isSelected = value === item.value; + const { gaClickName, ...restItemProps } = itemProps ?? {}; + + return ( + + onSelectItem(item)} + // _last={{ + // mb: 8, + // }} + {...restItemProps} + > + {item.label} + + + ); + })} + + {/* {!resultOptions?.length && } */} + + {Footer &&
} + + )} +
+ ); +} + +interface SelectInputProps extends InputProps { + onChangeKeyword: (value: string) => void; + requestFocus: boolean; + text: string; + placeholder: string; + onEnter: () => void; +} + +const SelectInput = React.forwardRef((props: SelectInputProps, ref: any) => { + const { + requestFocus, + placeholder = '', + text = '', + onChangeKeyword, + onEnter, + disabled, + ...restProps + } = props; + + const onChange = (event: React.ChangeEvent) => { + const trimValue = event.target.value.trim(); + onChangeKeyword?.(trimValue); + }; + + return ( + + + + {requestFocus ? : } + + + ); +}); diff --git a/apps/dcellar-web-ui/src/components/common/DCSelect/index.tsx b/apps/dcellar-web-ui/src/components/common/DCSelect/index.tsx index 2bc3da34..413be57a 100644 --- a/apps/dcellar-web-ui/src/components/common/DCSelect/index.tsx +++ b/apps/dcellar-web-ui/src/components/common/DCSelect/index.tsx @@ -20,11 +20,13 @@ import { InputProps, } from '@totejs/uikit'; import React, { useEffect, useRef, useState } from 'react'; +import TickIcon from '@/components/common/SvgIcon/TickIcon.svg'; import noResultImage from '@/public/images/common/no-result.png'; import { useKeyDown } from '@/hooks/useKeyDown'; import { useSaveFuncRef } from '@/hooks/useSaveFuncRef'; import { GAClick } from '@/components/common/GATracker'; +import styled from '@emotion/styled'; interface ListItemProps extends MenuItemProps { gaClickName?: string; @@ -38,6 +40,7 @@ export interface IDCSelectOption { export interface DCSelectProps extends MenuProps { header?: React.ReactNode; + Footer?: () => JSX.Element; value?: string; text: string; options?: Array; @@ -49,7 +52,7 @@ export interface DCSelectProps extends MenuProps { onSearch?: (result: Array) => void; } -export function Select(props: DCSelectProps) { +export function DCSelect(props: DCSelectProps) { const { value, text, @@ -58,6 +61,7 @@ export function Select(props: DCSelectProps) { itemProps, headerProps, header, + Footer, onChange, onSearchFilter, onSearch, @@ -124,7 +128,6 @@ export function Select(props: DCSelectProps) { {header && ( {resultOptions?.map((item) => { const isSelected = value === item.value; + // not disabled + const { access = true } = item; const { gaClickName, ...restItemProps } = itemProps ?? {}; return ( item.access && onSelectItem(item)} - _last={{ - mb: 8, + bg: isSelected || !access ? undefined : 'bg.bottom', }} + onClick={() => access && onSelectItem(item)} + // _last={{ + // mb: 8, + // }} {...restItemProps} > - {item.label} + {isSelected && } {item.label} ); @@ -181,6 +188,7 @@ export function Select(props: DCSelectProps) { {!resultOptions?.length && } + {Footer &&