Skip to content

refactor #1

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
175 changes: 0 additions & 175 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,6 @@ Open [http://localhost:3010](http://localhost:3010) to view it in the browser.
The page will reload if you make edits.\
You will also see any lint errors in the console.

### `yarn start-home`

Start in development mode and show the home page.

### `yarn start-app`

Start in development mode and show the main app.

### `yarn test`

Launches the test runner in the interactive watch mode.\
Expand All @@ -54,184 +46,17 @@ See the section about [deployment](https://facebook.github.io/create-react-app/d

- `lib/` - Infrastructure code independent of business logic (widely used in the project base modules and functions for interaction with data sources, common utils, etc.)

- `contracts`
- `callContract.ts` - e.g. base function for requesting contracts
- `chains`
- `utils.ts`
- `constants.ts`
- `request.js` - example base function for http requests
- `useLockBodyScroll.ts` - common ui hook
- `legacy.js` - Unstructured legacy code (moved from Helpers.js)

- `domain/` - Project specific domain logic separated by entities and features, may contain
data fetching, formatting, types and constants

- `orders/` - Example entity folder

- `types.ts` - Entity related types
- `utils.ts` - Functions for calculations and formatting, can be split into several files
- `contracts.ts` - Contracts calls
- `backend.ts` - Http requests
- `graph.ts` - Subgraph queries
- `useActiveOrders.ts` - some complex hook with aggregation logic
- `constants.ts`
- `hooks.ts`

- `legacy.js` - Unstructured legacy code (moved from Api/index.js)

- `config/` - Often manually changed or environment-dependent global configs and constants, can contain simple getter functions
- `styles/` - Global styles
- `img/` - Images
- `abis/` - Contract abis
- `fonts/`

## Architecture guides

### React components

- Try to keep it simple and modular - only one component per file, Child components should be put separately

- Keep a **flat** components folder structure - do not nest components inside other components folders

- Keep styles and components together in the same folder

- Code, independent of state and props should be moved outside component body

- In general components should countain only ui logic, all resusable data processing code should be moved to the `domain` or `lib` folder, component-specific calculations
can be wrapped in custom hooks or functions and placed near component

- Try to keep definition order inside component body:
1. State - useState, useFetchedData, etc.
2. Calculated variables from state and props
3. Functions reused in the component, e.g. event handlers
4. useEffect
5. Render

<details>
<summary>Example component structure</summary>

- `components/`
- `SwapBox`
- `SwapBox.js`
- `SwapBox.css`
- `getErrorMessage.js` - only a component-specific logic

</details>

<details>
<summary>Example component body</summary>

```(javascript)
// components/SwapComponent/SwapComponent.tsx

import {useInfoTokens} from 'domain/tokens/contracts'
import {processSwap} from 'domain/exchange/contracts'
...

export function SwapComponent(props: Props) {
const infoTokens = useInfoTokens(props.chainId, ...);
const [selectedTokenAddress, setSelectedTokenAddress] = useState()
const [amount, setAmount] = useState()
const {tokenAmount, swapLimits, fees, ...} = useSwapState(
props, {infoTokens, selectedTokenAddress, amount}
)

...

useEffect(..., []);

async function onButtonClick() {
...
await processSwap(...)
}

return (
<div>
....
</div>

}

```

Optional separating component state evaluation if it contains a lot of logic which is highly
dependent on props or a state of the component.

```(javascript)
components/SwapComponent/useSwapState.ts

import {getTokenAmount} from 'domain/tokens/apiContracts'
import {getSwapLimits} from 'domain/exchange/swap-utils'


function useSwapState(props, {selectedTokenAddress, infoTokens, amount}) {
const infoTokens = useInfoTokens(props.chainId, ...);

const tokenAmount = getTokenAmount(infoTokens, selectedTokenAddress, ...)
const swapLimits = getSwapLimits(infoTokens, amount)

const swapFee = ...
const fees = ...

...some calculations

return {...}
}
```

</details>

---

### DataFlow

Divide a code into appropriate areas of responsibility and keep the dependencies flow:

```
config -> lib (infrastructure) -> domain -> components -> pages
```

Each layer can use code from itself or from the left side. For example `lib`-modules can require `config` and other `lib`-modules, but not `domain`-modules or `components`.
Also `pages` can depend on `components`, but not vice versa.

### Typescript

- Write a new code in Typescript as far as possible
- Components should have `.tsx` exstension
- While migration, there are some issues when using
js components inside tsx - all props are considered as required.
To solve this, define default values for unused props or put
jsDoc description when this is difficult

<details>
<summary>Example</summary>

```(javascript)
/**
* @param {any} props
*/
function Button(props) {...}
```

</details>

---

### Translation

- The language code should be a valid [BCP-47](https://unicode-org.github.io/cldr-staging/charts/latest/supplemental/language_plural_rules.html) code like `es` for `Spanish`.
- The formatting used in `.po` files for each language is know as ICU MessageFormat. To understand it please refer to this [GUIDE](https://lingui.js.org/ref/message-format.html)

### SCSS

Use the following syntax to import scss modules:

```
@use "src/styles/colors";

.ClassName {
background: colors.$color-red;
}
```

---
24 changes: 11 additions & 13 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,8 @@
"private": true,
"dependencies": {
"@apollo/client": "3.5.6",
"@ethersproject/providers": "5.5.1",
"@ethersproject/units": "5.5.0",
"@lingui/core": "3.13.3",
"@lingui/react": "3.13.3",
"@testing-library/jest-dom": "5.16.1",
"@testing-library/react": "11.2.7",
"@testing-library/user-event": "12.8.3",
"@types/node": "18.7.13",
"@types/react": "18.0.17",
"@types/react-dom": "18.0.6",
"@types/react-router-dom": "5.3.3",
"@uniswap/sdk-core": "3.0.1",
"@uniswap/v3-sdk": "3.9.0",
"classnames": "2.3.1",
Expand All @@ -33,10 +24,7 @@
"react-router-dom": "5.3.0",
"react-scripts": "5.0.1",
"react-use": "17.3.1",
"sass": "1.55.0",
"swr": "2.2.1",
"typescript": "4.7.4",
"web-vitals": "1.1.2"
"swr": "2.2.1"
},
"resolutions": {
"react-error-overlay": "6.0.9"
Expand Down Expand Up @@ -92,13 +80,23 @@
"@lingui/cli": "3.13.3",
"@lingui/loader": "3.13.3",
"@lingui/macro": "3.13.3",
"@testing-library/jest-dom": "5.16.1",
"@testing-library/react": "11.2.7",
"@testing-library/user-event": "12.8.3",
"@types/node": "18.7.13",
"@types/react": "18.0.17",
"@types/react-dom": "18.0.6",
"@types/react-router-dom": "5.3.3",
"buffer": "6.0.3",
"eslint": "^8.41.0",
"eslint-config-react-app": "^7.0.1",
"husky": "7.0.4",
"lint-staged": "12.3.4",
"prettier": "2.5.1",
"react-app-rewired": "2.2.1",
"sass": "1.55.0",
"typescript": "4.7.4",
"web-vitals": "1.1.2",
"webpack-bundle-analyzer": "^4.9.1"
},
"lint-staged": {
Expand Down
2 changes: 1 addition & 1 deletion src/App/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import "styles/Shared.css";
import "./App.scss";

import Home from "pages/Home/Home";
import SEO from "components/Common/SEO";
import EventToastContainer from "components/EventToast/EventToastContainer";
import useEventToast from "components/EventToast/useEventToast";

Expand All @@ -31,6 +30,7 @@ import ReferralTerms from "pages/ReferralTerms/ReferralTerms";
import TermsAndConditions from "pages/TermsAndConditions/TermsAndConditions";

import { Header } from "components/Header/Header";
import SEO from "components/SEO/SEO";

function FullApp() {
const location = useLocation();
Expand Down
Loading