From 4faffd77a4fbdf5e0dd5da71f6d2bf023705542a Mon Sep 17 00:00:00 2001 From: Hemanth Sai Date: Tue, 23 Apr 2024 21:28:49 +0530 Subject: [PATCH] feat: allow user to enter multisend data in csv format (#1205) * feat: allow user to enter data manually * chore: ui change --- .../transfers/components/Messages.tsx | 2 +- .../transfers/components/MultiTransfer.tsx | 2 +- .../transfers/components/MultiTxUpload.tsx | 251 ++++++++++++++---- frontend/src/app/(routes)/transfers/styles.ts | 19 ++ .../src/app/(routes)/transfers/transfers.css | 19 ++ frontend/src/components/CustomButton.tsx | 2 +- frontend/src/utils/constants.ts | 4 +- 7 files changed, 236 insertions(+), 63 deletions(-) diff --git a/frontend/src/app/(routes)/transfers/components/Messages.tsx b/frontend/src/app/(routes)/transfers/components/Messages.tsx index 52bf5eb26..95899aeb4 100644 --- a/frontend/src/app/(routes)/transfers/components/Messages.tsx +++ b/frontend/src/app/(routes)/transfers/components/Messages.tsx @@ -25,7 +25,7 @@ const Messages = ({ return (
-
+
Messages
diff --git a/frontend/src/app/(routes)/transfers/components/MultiTransfer.tsx b/frontend/src/app/(routes)/transfers/components/MultiTransfer.tsx index 63adcc420..b1f8bb38f 100644 --- a/frontend/src/app/(routes)/transfers/components/MultiTransfer.tsx +++ b/frontend/src/app/(routes)/transfers/components/MultiTransfer.tsx @@ -134,7 +134,7 @@ const MultiTransfer = ({
diff --git a/frontend/src/app/(routes)/transfers/components/MultiTxUpload.tsx b/frontend/src/app/(routes)/transfers/components/MultiTxUpload.tsx index 78223a576..46dc4b6a3 100644 --- a/frontend/src/app/(routes)/transfers/components/MultiTxUpload.tsx +++ b/frontend/src/app/(routes)/transfers/components/MultiTxUpload.tsx @@ -2,7 +2,10 @@ import Image from 'next/image'; import { parseSendMsgsFromContent } from '@/utils/parseMsgs'; import { useAppDispatch, useAppSelector } from '@/custom-hooks/StateHooks'; import { setError } from '@/store/features/common/commonSlice'; -import { SEND_TEMPLATE } from '@/utils/constants'; +import { MULTISEND_PLACEHOLDER, SEND_TEMPLATE } from '@/utils/constants'; +import { ChangeEvent, useEffect, useState } from 'react'; +import { TextField } from '@mui/material'; +import { multiSendInputFieldStyles } from '../styles'; const MultiTxUpload = ({ chainID, @@ -33,12 +36,76 @@ const MultiTxUpload = ({ } }; + const [isFileUpload, setIsFileUpload] = useState(true); + const [inputs, setInputs] = useState(''); + const handleInputChange = ( + e: ChangeEvent + ) => { + setInputs(e.target.value); + }; + + const addInputs = () => { + const [parsedTxns, error] = parseSendMsgsFromContent( + address, + '\n' + inputs + ); + if (error) { + dispatch( + setError({ + type: 'error', + message: error, + }) + ); + } else { + addMsgs(parsedTxns); + if (parsedTxns?.length) { + setInputs(''); + } else { + dispatch( + setError({ + type: 'error', + message: 'Invalid input', + }) + ); + } + } + }; + + const handleToggle = (value: boolean) => { + addMsgs([]); + setIsFileUpload(value); + }; + + const getInputRowsCountWithScreenSize = () => { + const divElement = document.getElementById('multisend-inputs'); + const height = divElement?.offsetHeight || 500; + const rows = Math.min((height - 46) / 23, 18); + return parseInt(rows.toString()); + }; + + const [inputRows, setInputRows] = useState(getInputRowsCountWithScreenSize()); + + const resetInputsRowsCount = () => { + setInputRows(getInputRowsCountWithScreenSize()); + }; + + useEffect(() => { + window.addEventListener('resize', resetInputsRowsCount); + return () => { + window.removeEventListener('resize', resetInputsRowsCount); + }; + }, []); + + useEffect(() => { + if (!isFileUpload) { + resetInputsRowsCount(); + } + }, [isFileUpload]); + return ( -
+
-
- File Upload -
+
Download Sample{' '} @@ -56,64 +123,132 @@ const MultiTxUpload = ({
-
{ - const element = document.getElementById('multiTxns_file'); - if (element) element.click(); - }} - > -
-
- Upload file -
- Upload CSV File, Each line must contain “Recipient Amount” + {isFileUpload ? ( +
{ + const element = document.getElementById('multiTxns_file'); + if (element) element.click(); + }} + > +
+
+ Upload file +
+ Upload CSV File, Each line must contain “Recipient Amount” +
+
-
-
- { - if (!e?.target?.files) return; - const file = e.target.files[0]; - if (!file) { - return; - } + { + if (!e?.target?.files) return; + const file = e.target.files[0]; + if (!file) { + return; + } - const reader = new FileReader(); - reader.onload = (e) => { - if (!e.target) return null; - const contents = e.target.result; - onFileContents(contents); - }; - reader.onerror = (e) => { - dispatch( - setError({ - type: 'error', - message: '' + (e.target?.error || 'Something went wrong. '), - }) - ); - }; - reader.readAsText(file); - e.target.value = ''; - }} - /> + const reader = new FileReader(); + reader.onload = (e) => { + if (!e.target) return null; + const contents = e.target.result; + onFileContents(contents); + }; + reader.onerror = (e) => { + dispatch( + setError({ + type: 'error', + message: + '' + (e.target?.error || 'Something went wrong. '), + }) + ); + }; + reader.readAsText(file); + e.target.value = ''; + }} + /> +
-
+ ) : ( +
{ + const element = document.getElementById('multiTxns_file'); + if (element) element.click(); + }} + > +
+ +
+ +
+ )}
); }; export default MultiTxUpload; + +const ButtonGroup = ({ + handleToggle, + isFileUpload, +}: { + isFileUpload: boolean; + handleToggle: (value: boolean) => void; +}) => { + return ( +
+ + +
+ ); +}; diff --git a/frontend/src/app/(routes)/transfers/styles.ts b/frontend/src/app/(routes)/transfers/styles.ts index dfa0fa0ce..88d96b8d8 100644 --- a/frontend/src/app/(routes)/transfers/styles.ts +++ b/frontend/src/app/(routes)/transfers/styles.ts @@ -3,6 +3,25 @@ export const customDialogPaper = { background: 'linear-gradient(90deg, #704290 0.11%, #241b61 70.28%)', }; +export const multiSendInputFieldStyles = { + '& .MuiInputBase-input': { + color: 'white', + fontSize: '14px', + fontWeight: 200, + }, + '& .MuiOutlinedInput-notchedOutline': { + border: 'none', + }, + '& .MuiOutlinedInput-root': { + border: '1px solid #ffffff1a', + borderRadius: '16px', + }, + '& .Mui-focused': { + border: '1px solid #ffffff4a', + borderRadius: '16px', + }, +}; + export const swapTextFieldStyles = { '& .MuiTypography-body1': { color: 'white', diff --git a/frontend/src/app/(routes)/transfers/transfers.css b/frontend/src/app/(routes)/transfers/transfers.css index c4d9f4836..35574e09c 100644 --- a/frontend/src/app/(routes)/transfers/transfers.css +++ b/frontend/src/app/(routes)/transfers/transfers.css @@ -64,3 +64,22 @@ .drop-down { box-shadow: 0px 4px 4px 0px rgba(0, 0, 0, 0.25); } + +.multisend-input-box { + @apply flex justify-center items-center px-4 py-4 bg-[#FFFFFF1A] min-h-[152px] rounded-3xl w-full cursor-pointer; +} + +.multisend-toggle-btn-group { + @apply bg-[#FFFFFF1A] rounded-2xl flex h-[34px]; + box-shadow: 0px 4px 4px 0px rgba(0, 0, 0, 0.25) inset; +} + +.multisend-btn { + @apply text-[#FFFFFF80] text-[12px] text-center px-4 min-w-[127px]; +} + +.multisend-btn-active { + @apply text-white rounded-2xl; + background: linear-gradient(180deg, #4aa29c 0%, #8b3da7 100%); + box-shadow: 0px 4px 4px 0px #100; +} diff --git a/frontend/src/components/CustomButton.tsx b/frontend/src/components/CustomButton.tsx index 3cf642465..924024334 100644 --- a/frontend/src/components/CustomButton.tsx +++ b/frontend/src/components/CustomButton.tsx @@ -26,7 +26,7 @@ const CustomSubmitButton = ({