From 242c32699f4190cfb8c55da2b350afd54054d1ff Mon Sep 17 00:00:00 2001 From: Manuel Gellfart Date: Fri, 1 Dec 2023 17:21:05 +0100 Subject: [PATCH] feat: redesign app (#43) - new theme - remove safe-react-components - update to MUI 5 - Use craco instead of react-rewired --- config-overrides.js | 34 - craco.config.ts | 24 + package.json | 50 +- src/App.tsx | 67 +- src/AppWrapper.tsx | 31 + src/GlobalStyle.ts | 38 - src/actions/allowance.tsx | 2 +- src/actions/approvals.tsx | 2 +- src/components/AppHeader.tsx | 31 + src/components/ApprovalDialog.tsx | 54 +- src/components/ApprovalLoader.tsx | 21 +- src/components/DateDisplay.tsx | 22 +- src/components/EthHashInfo.tsx | 59 + src/components/Footer.tsx | 17 +- src/components/Identicon.tsx | 30 + src/components/approvallist/ApprovalEntry.tsx | 110 +- .../approvallist/ApprovalHeader.tsx | 55 +- src/components/approvallist/ApprovalList.tsx | 19 +- .../ApprovalTransactionHistory.tsx | 64 - src/components/approvallist/Container.tsx | 5 +- src/components/approvallist/FAQSection.tsx | 169 +- src/components/header/Settings.tsx | 78 +- src/components/header/SettingsButton.tsx | 25 +- src/contracts/ERC20.ts | 30 +- src/contracts/factories/ERC20__factory.ts | 8 +- src/hooks/useDarkMode.ts | 17 + src/hooks/useSafeCoreSdk.ts | 10 +- src/index.tsx | 20 +- src/networks.ts | 45 +- src/static/github.svg | 1 + src/stores/StoreContextProvider.tsx | 35 +- src/stores/tokens/BalanceStore.ts | 26 + src/stores/tokens/TokenService.ts | 2 +- src/stores/tokens/TokenStore.ts | 2 +- .../transactions/TransactionService.test.ts | 55 +- src/stores/transactions/TransactionService.ts | 31 +- src/stores/transactions/TransactionStore.ts | 5 +- src/stores/ui/UIStore.ts | 37 +- src/styles/globals.css | 9 + src/testutils/utils.ts | 40 +- src/utils/formatAmount.ts | 210 + src/utils/wei.tsx | 2 +- yarn.lock | 8117 ++++++++--------- 43 files changed, 4728 insertions(+), 4981 deletions(-) delete mode 100644 config-overrides.js create mode 100644 craco.config.ts create mode 100644 src/AppWrapper.tsx delete mode 100644 src/GlobalStyle.ts create mode 100644 src/components/AppHeader.tsx create mode 100644 src/components/EthHashInfo.tsx create mode 100644 src/components/Identicon.tsx delete mode 100644 src/components/approvallist/ApprovalTransactionHistory.tsx create mode 100644 src/hooks/useDarkMode.ts create mode 100644 src/static/github.svg create mode 100644 src/stores/tokens/BalanceStore.ts create mode 100644 src/styles/globals.css create mode 100644 src/utils/formatAmount.ts diff --git a/config-overrides.js b/config-overrides.js deleted file mode 100644 index c6ce0f8..0000000 --- a/config-overrides.js +++ /dev/null @@ -1,34 +0,0 @@ -const webpack = require('webpack'); - -module.exports = { - webpack: function (config, env) { - const fallback = config.resolve.fallback || {}; - - // https://github.com/ChainSafe/web3.js#web3-and-create-react-app - Object.assign(fallback, { - crypto: require.resolve('crypto-browserify'), - stream: require.resolve('stream-browserify'), - assert: require.resolve('assert'), - http: require.resolve('stream-http'), - https: require.resolve('https-browserify'), - os: require.resolve('os-browserify'), - url: require.resolve('url'), - // https://stackoverflow.com/questions/68707553/uncaught-referenceerror-buffer-is-not-defined - buffer: require.resolve('buffer'), - }); - - config.resolve.fallback = fallback; - - config.plugins = (config.plugins || []).concat([ - new webpack.ProvidePlugin({ - process: 'process/browser', - Buffer: ['buffer', 'Buffer'], - }), - ]); - - return config; - }, - jest: function (config) { - return config; - }, -}; diff --git a/craco.config.ts b/craco.config.ts new file mode 100644 index 0000000..c4cb58d --- /dev/null +++ b/craco.config.ts @@ -0,0 +1,24 @@ +import NodePolyfillPlugin from 'node-polyfill-webpack-plugin'; +import { Configuration } from 'webpack/types.d'; + +const ModuleScopePlugin = require('react-dev-utils/ModuleScopePlugin'); + +const config = { + babel: { + plugins: ['@emotion/babel-plugin'], + }, + webpack: { + plugins: [new NodePolyfillPlugin()], + configure: (webpackConfig: Configuration) => { + if (!webpackConfig?.resolve?.plugins) return webpackConfig; + + // Allow imports outside of src/ + webpackConfig.resolve.plugins = webpackConfig.resolve.plugins.filter( + ({ constructor }: InstanceType) => constructor?.name !== 'ModuleScopePlugin', + ); + return webpackConfig; + }, + }, +}; + +export default config; diff --git a/package.json b/package.json index 6e26730..811dfc2 100644 --- a/package.json +++ b/package.json @@ -1,33 +1,37 @@ { "name": "token-approval-manager", - "version": "1.1.1", + "version": "1.3.0", "private": true, "dependencies": { - "@gnosis.pm/safe-apps-provider": "0.10.1", - "@gnosis.pm/safe-apps-react-sdk": "4.2.1", - "@gnosis.pm/safe-apps-sdk": "7.0.0", - "@gnosis.pm/safe-core-sdk": "^2.1.0", - "@gnosis.pm/safe-ethers-lib": "^1.1.0", - "@gnosis.pm/safe-react-components": "^0.9.7", - "@gnosis.pm/safe-service-client": "^1.1.2", - "@material-ui/core": "4.X.X", - "@material-ui/styles": "^4.11.4", + "@emotion/babel-plugin": "^11.10.5", + "@emotion/react": "^11.10.5", + "@emotion/styled": "^11.10.5", + "@mui/icons-material": "^5.10.16", + "@mui/material": "^5.10.15", "@mui/x-data-grid": "^4.X.X", + "@safe-global/safe-apps-provider": "^0.18.0", + "@safe-global/safe-apps-react-sdk": "^4.7.0", + "@safe-global/safe-apps-sdk": "^8.1.0", + "@safe-global/safe-core-sdk": "^3.2.1", + "@safe-global/safe-ethers-lib": "^1.1.0", + "@safe-global/safe-react-components": "^2.0.6", + "@safe-global/safe-service-client": "^1.1.2", "bignumber.js": "^9.0.2", + "ethereum-blockies-base64": "^1.0.2", "ethers": "^5.6.6", "mobx": "^6.5.0", "mobx-react": "^7.3.0", "react": "^17.0.2", "react-dom": "^17.0.2", - "react-is": "^17.0.2", - "styled-components": "5.x.x" + "react-is": "^17.0.2" }, "scripts": { - "start": "react-app-rewired start", - "build": "react-app-rewired build", + "start": "craco start", + "build": "craco build", "lint": "eslint --max-warnings 0 .", - "test": "react-app-rewired test", - "eject": "react-scripts eject", + "lint:fix": "eslint --fix .", + "test": "craco test", + "eject": "craco eject", "generate-types": "typechain --target=ethers-v5 --out-dir src/contracts './node_modules/@openzeppelin/contracts/build/contracts/ERC20.json'", "postinstall": "yarn generate-types" }, @@ -45,8 +49,9 @@ }, "homepage": "./", "devDependencies": { - "@openzeppelin/contracts": "^4.7.3", - "@testing-library/jest-dom": "^5.11.4", + "@craco/craco": "^7.0.0", + "@openzeppelin/contracts": "^4.8.3", + "@testing-library/jest-dom": "^5.16.5", "@testing-library/react": "^12.1.2", "@testing-library/user-event": "^13.1.9", "@typechain/ethers-v5": "^9.0.0", @@ -67,11 +72,12 @@ "eslint-plugin-react": "^7.28.0", "eslint-plugin-react-hooks": "^4.3.0", "https-browserify": "^1.0.0", + "node-polyfill-webpack-plugin": "^2.0.1", "os-browserify": "^0.3.0", "prettier": "^2.4.1", "process": "^0.11.10", - "react-app-rewired": "^2.2.1", - "react-scripts": "^5.0.0", + "react-app-rewire-emotion": "^4.0.0", + "react-scripts": "^5.0.1", "stream-browserify": "^3.0.0", "stream-http": "^3.2.0", "typechain": "^7.0.0", @@ -79,6 +85,8 @@ "url": "^0.11.0" }, "resolutions": { - "react-scripts/**/async": ">=2.6.4" + "react-scripts/**/async": ">=2.6.4", + "react-scripts/**/@svgr/webpack": ">=6.5.1", + "react-scripts/**/terser": ">=5.14.2" } } diff --git a/src/App.tsx b/src/App.tsx index cff63c5..a4b931b 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,62 +1,51 @@ -import { Title, Text, Card } from '@gnosis.pm/safe-react-components'; +import { Box, Card } from '@mui/material'; import React from 'react'; -import styled from 'styled-components'; +import { AppHeader } from './components/AppHeader'; import { ApprovalLoader } from './components/ApprovalLoader'; import { Footer } from './components/Footer'; import { ApprovalList } from './components/approvallist/ApprovalList'; import { FAQSection } from './components/approvallist/FAQSection'; import { StoreContextProvider } from './stores/StoreContextProvider'; +import { BalanceStore } from './stores/tokens/BalanceStore'; import { TokenStore } from './stores/tokens/TokenStore'; import { TransactionStore } from './stores/transactions/TransactionStore'; import { UIStore } from './stores/ui/UIStore'; -const Container = styled.div` - padding: 1rem; - padding-top: 0rem; - height: 100%; - display: flex; - flex-direction: column; -`; - -const HeaderWrapper = styled.div` - padding: 1rem; - padding-top: 0rem; - display: flex; - flex-direction: column; -`; - -const Row = styled.div` - display: flex; - flex-direction: row; - align-items: center; -`; +import './styles/globals.css'; const tokenStore = new TokenStore(); +const balanceStore = new BalanceStore(); + const transactionStore = new TransactionStore(); const uiStore = new UIStore(); const SafeApp = (): React.ReactElement => { return ( - - - - Logo - Token Approval Manager - - ✅ Keep track of all your token approvals. - ✍️ Edit / Revoke multiple approvals in a single transaction. - - - }> - - - - -