Skip to content

Commit

Permalink
feat: add comments
Browse files Browse the repository at this point in the history
  • Loading branch information
Karlen9 committed Aug 23, 2024
1 parent 403b9bd commit ec46d82
Show file tree
Hide file tree
Showing 10 changed files with 97 additions and 57 deletions.
5 changes: 1 addition & 4 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,9 @@ module.exports = {
plugins: ['@typescript-eslint', 'react', 'tailwindcss', 'unused-imports', 'simple-import-sort', 'import'],
settings: {
react: {version: 'detect'},
next: {
rootDir: 'packages'
},
'import/resolver': {typescript: {}}
},
ignorePatterns: ['public/sw*', 'public/workbox*', 'ipfs'],
ignorePatterns: ['public/sw*', 'public/workbox*', 'ipfs/*'],
rules: {
'import/default': 0,
'react/prop-types': 0,
Expand Down
7 changes: 7 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"editor.codeActionsOnSave": {
"source.fixAll": "explicit"
},
"eslint.format.enable": true,
"editor.formatOnSave": true
}
20 changes: 13 additions & 7 deletions components/ActionSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,18 @@ export function ActionSection(): ReactElement | null {
const {configuration} = useDisperse();

/**********************************************************************************************
** TODO: write comment of what it does
** totalToDisperse function calculates the total amount to disperse by summing the normalized
** values of all input rows in the configuration. It is memoized with useMemo to optimize
** performance and only recalculates when the inputs change.
*********************************************************************************************/
const totalToDisperse = useMemo((): bigint => {
return configuration.inputs.reduce((acc, row): bigint => acc + row.value.normalizedBigAmount.raw, 0n) ?? 0;
}, [configuration.inputs]);

/**********************************************************************************************
** TODO: write comment of what it does
** isButtonDisabled function determines whether the button should be disabled based on the
** presence of a selected token address and the total amount to disperse. It returns true if
** either condition is not met and is memoized to optimize performance.
*********************************************************************************************/
const isButtonDisabled = useMemo((): boolean => {
if (!configuration.tokenToSend?.address || totalToDisperse === BigInt(0)) {
Expand All @@ -26,7 +30,10 @@ export function ActionSection(): ReactElement | null {
}, [configuration.tokenToSend?.address, totalToDisperse]);

/**********************************************************************************************
** TODO: write comment of what it does
** getTotalToDisperse function returns a formatted string representing the total amount to
** disperse. It checks if the wallet is connected and if a token is selected, and formats
** the total amount with the appropriate number of decimals. It uses useCallback to avoid
** unnecessary recalculations.
*********************************************************************************************/
const getTotalToDisperse = useCallback((): string => {
if (!address) {
Expand All @@ -49,7 +56,9 @@ export function ActionSection(): ReactElement | null {
]);

/**********************************************************************************************
** TODO: write comment of what it does
** getButtonTitle function returns a string for the button's title based on whether the wallet
** is connected. It returns 'Connect wallet' if the wallet is not connected, and 'Approve
** and Disperse' otherwise.
*********************************************************************************************/
const getButtonTitle = (): string => {
if (!address) {
Expand All @@ -67,9 +76,6 @@ export function ActionSection(): ReactElement | null {
}
};

/**********************************************************************************************
** TODO: write comment of what it does
*********************************************************************************************/
if (configuration.inputs.length < 1) {
return null;
}
Expand Down
6 changes: 3 additions & 3 deletions components/common/AddReceiverCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ import {newDisperseVoidRow} from '../disperse/useDisperse.helpers';
import {useDisperse} from './contexts/useDisperse';
import {IconPlus} from './icons/IconPlus';

// type TAddReceiverCardProps = {};

export function AddReceiverCard({className}: {className?: string}): ReactElement {
const {dispatchConfiguration} = useDisperse();

/**********************************************************************************************
** TODO: write comment of what it does
** onAddReceivers function adds a specified number of new receiver entries to the configuration.
** It dispatches an 'ADD_RECEIVERS' action with a payload containing an array of new
** disperse void rows, generated by the newDisperseVoidRow function.
*********************************************************************************************/
const onAddReceivers = (amount: number): void => {
dispatchConfiguration({
Expand Down
43 changes: 30 additions & 13 deletions components/common/AddressInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,25 @@ import {useAsyncAbortable} from '@react-hookz/web';

import {TextTruncate} from './TextTruncate';
import {useValidateAddressInput} from './hooks/useValidateAddressInput';
import {type TInputAddressLike} from './utils/tools.address';
import {type TInputAddressLike} from './utils/tools.address';

export function AddressInput({
value,
onSetValue,
onSetValue,
inputRef
}: {
value: TInputAddressLike;
onSetValue: (value: Partial<TInputAddressLike>) => void;
onSetValue: (value: Partial<TInputAddressLike>) => void;
inputRef: RefObject<HTMLInputElement>;
}): ReactElement {
const [isFocused, set_isFocused] = useState(false);
const [isTouched, set_isTouched] = useState(false);
const {validate} = useValidateAddressInput();
const [{result}, actions] = useAsyncAbortable(validate, undefined);


/**********************************************************************************************
** TODO: write comment of what it does
** onChange function handles input changes by aborting any ongoing actions, setting the new
** value with the provided input, and then executing the necessary actions based on the updated input.
*********************************************************************************************/
const onChange = (input: string): void => {
actions.abort();
Expand All @@ -31,7 +31,9 @@ export function AddressInput({
};

/**********************************************************************************************
** TODO: write comment of what it does
** getInputValue function returns the appropriate input value based on the focus state and
** the format of the input. If focused, it returns the full input label. If the input is an
** address, it returns a truncated version of the address. Otherwise, it returns the label as is.
*********************************************************************************************/
const getInputValue = useCallback((): string | undefined => {
if (isFocused) {
Expand All @@ -45,9 +47,10 @@ export function AddressInput({
return value.label;
}, [isFocused, value.label]);


/**********************************************************************************************
** TODO: write comment of what it does
** useEffect hook updates the component's value when the result changes. If a valid result is
** present, it triggers the onSetValue function with the new result. The effect only runs
** when the result dependency changes.
*********************************************************************************************/
useEffect(() => {
if (!result) {
Expand All @@ -58,7 +61,10 @@ export function AddressInput({
}, [result]);

/**********************************************************************************************
** TODO: write comment of what it does
** onFocusInput function manages the focus state of an input element. If the input is not
** already focused, it sets the focus state to true and, after a brief delay, selects the
** entire input text and scrolls to the end of the input. If the input is already focused,
** it simply ensures the focus state remains true.
*********************************************************************************************/
const onFocusInput = useCallback(() => {
if (!isFocused) {
Expand All @@ -77,7 +83,13 @@ export function AddressInput({
}, [inputRef, isFocused, value.label.length]);

return (
<label className={cl('h-14 rounded-2xl border px-4 py-2', isTouched && value.label && (value.error || !value.isValid || value.isValid === 'undetermined') ? 'border-fail' : 'border-primary/10')}>
<label
className={cl(
'h-14 rounded-2xl border px-4 py-2',
isTouched && value.label && (value.error || !value.isValid || value.isValid === 'undetermined')
? 'border-fail'
: 'border-primary/10'
)}>
<input
// ref={inputRef}
className={cl(
Expand All @@ -103,16 +115,21 @@ export function AddressInput({
}}
/>
<TextTruncate
value={(isAddress(value?.address)) && toAddress(value.address) ? truncateHex(value.address, 6) : value.error || ''}
value={
isAddress(value?.address) && toAddress(value.address)
? truncateHex(value.address, 6)
: value.error || ''
}
className={cl(
'text-primary/40',
isFocused ? 'hidden' : 'block',
isFocused ? 'translate-y-8' : 'translate-y-0',
'pointer-events-none',
value.error || !value.isValid || value.isValid === 'undetermined' ? '!text-fail' : 'text-neutral-600'
value.error || !value.isValid || value.isValid === 'undetermined'
? '!text-fail'
: 'text-neutral-600'
)}
/>

</label>
);
}
6 changes: 5 additions & 1 deletion components/common/DownloadTemplateButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ import type {ReactElement} from 'react';

export function DownloadTemplateButton({className}: {className?: string}): ReactElement {
/**********************************************************************************************
** TODO: write comment of what it does
** downloadTemplate function generates a CSV file from the receiverEntries array and triggers
** a download of the file. It creates a Blob from the CSV string, generates a URL for the
** Blob, and then creates an anchor element to download the file with a name based on the
** current date.
*********************************************************************************************/
const downloadTemplate = async (): Promise<void> => {
const receiverEntries = [{receiverAddress: '0x10001192576E8079f12d6695b0948C2F41320040', value: '4.20'}];
Expand All @@ -24,6 +27,7 @@ export function DownloadTemplateButton({className}: {className?: string}): React
a.click();
document.body.removeChild(a);
};

return (
<button
onClick={downloadTemplate}
Expand Down
9 changes: 7 additions & 2 deletions components/common/ExportConfigurationButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@ export function ExportConfigurationButton({className}: {className?: string}): Re
const {configuration} = useDisperse();

/**********************************************************************************************
** TODO: write comment of what it does
** downloadConfiguration function generates a CSV file from the configuration inputs and
** triggers a download of the file. It maps over the inputs to extract receiver addresses and
** values, filters out any invalid entries, and then creates a Blob from the CSV string.
** Finally, it generates a URL for the Blob and creates an anchor element to download the file
** with a name based on the current date.
*********************************************************************************************/
const downloadConfiguration = useCallback(async () => {
const receiverEntries = configuration.inputs
Expand All @@ -31,13 +35,14 @@ export function ExportConfigurationButton({className}: {className?: string}): Re
a.click();
document.body.removeChild(a);
}, [configuration.inputs]);

return (
<button
onClick={downloadConfiguration}
className={cl(
'flex text-xs md:text-base items-center gap-2 rounded-lg bg-primary p-2 font-bold text-secondary',
className
)}>
)}>
<IconImport className={'rotate-180'} />
{'Export configuration'}
</button>
Expand Down
5 changes: 4 additions & 1 deletion components/common/ImportConfigurationButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@ export function ImportConfigurationButton({className}: {className?: string}): Re
const {validate: validateAmount} = useValidateAmountInput();

/**********************************************************************************************
** TODO: write comment of what it does
** handleFileUpload function manages the CSV file upload process. It reads the file, parses
** the CSV data using Papa Parse, and validates the file's structure and content. Each row is
** processed to create records, ensuring addresses and amounts are valid. Valid records are
** dispatched to update the state with new receiver entries.
*********************************************************************************************/
const handleFileUpload = (e: ChangeEvent<HTMLInputElement>): void => {
if (!e.target.files) {
Expand Down
12 changes: 9 additions & 3 deletions components/common/SelectTokenModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,9 @@ function TokenList({
const tokensWithBalance = listTokensWithBalance();

/**********************************************************************************************
** TODO: Add a comment of what it does
** tokensDict function creates a memoized dictionary of tokens categorized by type. It maps
** 'your_tokens' to tokensWithBalance and 'popular' to popularTokens, updating only when
** dependencies change.
*********************************************************************************************/
const tokensDict: {[key: string]: TToken[]} = useMemo(() => {
return {
Expand All @@ -173,7 +175,10 @@ function TokenList({
const prices = getPrices(tokensDict[currentTab]);

/**********************************************************************************************
** TODO: Add a comment of what it does
** searchFilteredTokens function computes a filtered list of tokens based on the current tab
** and search value. It returns a slice of popular tokens, tokens with a balance, or filters
** tokens by address, symbol, or name according to the search value. It is memoized with
** useMemo to optimize performance.
*********************************************************************************************/
const searchFilteredTokens = useMemo(() => {
if (!searchValue && currentTab === 'popular') {
Expand All @@ -191,7 +196,8 @@ function TokenList({
}, [currentTab, popularTokens, searchValue, tokensDict, tokensWithBalance]);

/**********************************************************************************************
** TODO: Add a comment of what it does
** onSelectToken function dispatches an action to update the selected token in the state and
** then closes the modal. It is memoized using useCallback to avoid unnecessary re-renders.
*********************************************************************************************/
const onSelectToken = useCallback(
(token: TToken) => {
Expand Down
41 changes: 18 additions & 23 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,17 @@
"baseUrl": ".",
"paths": {
"@/*": ["./*"],
"@lib/*": ["packages/lib/*"],
"@smolDesignSystem/*": ["packages/smol/components/designSystem/*"],
"@smolContexts/*": ["packages/smol/contexts/*"],
"@smolHooks/*": ["packages/smol/hooks/*"],
"@smolLandingDesignSystem/*": ["packages/smol-landing/components/designSystem/*"]
"@common/*": ["components/common/*"],
"@icons/*": ["components/icons/*"],
"@utils/*": ["utils/*"],
"@types": ["utils/types"]
},
"types": ["bun-types"],
"target": "esnext",
"module": "esnext",
"lib": ["es6", "es7", "esnext", "dom"],
"allowImportingTsExtensions": true,
"moduleDetection": "force",
"moduleDetection": "force",
"allowJs": true,
"jsx": "preserve",
"removeComments": false,
Expand Down Expand Up @@ -43,31 +42,27 @@
"isolatedModules": true,
"composite": true,
"downlevelIteration": true,
"plugins": [{"name": "next"}]
"plugins": [
{
"name": "next"
}
]
},
"exclude": ["node_modules", "_app"],
"exclude": ["node_modules"],
"include": [
"**/*.css",
"**/*.ts",
"**/*.tsx",
"**/*.d.tsx",
"packages",
"public",
"public/manifest.json",
"stylelint.config.js",
"commitlint.config.js",
"**/next.config.js",
"**/postcss.config.js",
"**/tailwind.config.js",
"packages/*/postcss.config.js",
"packages/*/tailwind.config.js",
"packages/*/next.config.js",
"packages/*/stylelint.config.js",
"postcss.config.js",
"tailwind.config.js",
"next.config.js",
"theme.config.js",
".eslintrc.js",
".next/types/**/*.ts",
"jest.config.js",
"vitest.config.ts",
"worker/index.js",
"utils/*/*.json"
"stylelint.config",
"commitlint.config"
]
}
}

0 comments on commit ec46d82

Please sign in to comment.