Skip to content
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
1 change: 1 addition & 0 deletions packages/client/src/components/SafeContacts.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ function EditContactModal({
value={currentAddr}
isValid={addressValid}
onChange={onAddressChange}
className="mt-2"
/>
{!addressNew && (
<p className="has-text-red mt-2">
Expand Down
48 changes: 13 additions & 35 deletions packages/client/src/components/SafeOwners.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,18 @@
import React from 'react';
import { InputAddress } from 'library/components';
import Svg from 'library/Svg';

function SafeOwners({
address,
safeOwners,
safeOwnersValidByAddress,
setSafeOwners,
}) {
function SafeOwners({ address, safeOwners, setSafeOwners }) {
const onOwnerNameChange = (value, idx) => {
const newOwners = safeOwners.slice(0);
newOwners[idx].name = value;
setSafeOwners([...newOwners]);
};

const onOwnerAddressChange = (value, idx) => {
const onOwnerAddressChange = (value, isValid, idx) => {
const newOwners = safeOwners.slice(0);
newOwners[idx].address = value;
newOwners[idx].isValid = isValid;
setSafeOwners([...newOwners]);
};
Comment on lines +12 to 17
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prefer following the style guide

Suggested change
const onOwnerAddressChange = (value, isValid, idx) => {
const newOwners = safeOwners.slice(0);
newOwners[idx].address = value;
newOwners[idx].isValid = isValid;
setSafeOwners([...newOwners]);
};
const onOwnerAddressChange = (value, isValid, idx) => {
const newOwners = [...safeOwners]
newOwners[idx].address = value;
newOwners[idx].isValid = isValid;
setSafeOwners(newOwners);
};


Expand All @@ -33,18 +30,7 @@ function SafeOwners({
</div>
<div className="flex-1 is-flex is-flex-direction-column">
<label className="has-text-grey mb-2">Owner Address</label>
<div style={{ position: 'relative' }}>
<input
className="p-4 rounded-sm column is-full"
type="text"
placeholder="Enter user's FLOW address"
value={address}
disabled
/>
<div style={{ position: 'absolute', right: 17, top: 14 }}>
<Svg name="Check" />
</div>
</div>
<InputAddress value={address} isValid readOnly />
</div>
</div>,
];
Expand All @@ -70,22 +56,14 @@ function SafeOwners({
<span className="has-text-red">*</span>
</label>
<div className="is-flex">
<div className="flex-1" style={{ position: 'relative' }}>
<input
className="p-4 rounded-sm column is-full"
type="text"
placeholder="Enter user's FLOW address"
value={so?.address}
onChange={(e) =>
onOwnerAddressChange(e.target.value, idx + 1)
}
/>
{safeOwnersValidByAddress[so.address] && (
<div style={{ position: 'absolute', right: 17, top: 14 }}>
<Svg name="Check" />
</div>
)}
</div>
<InputAddress
className="flex-1"
value={so?.address}
onChange={({ value, isValid }) =>
onOwnerAddressChange(value, isValid, idx + 1)
}
isValid={so?.isValid}
/>
<button
className="button is-border ml-2 p-4"
onClick={() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ const AddCollection = ({ onCancel, onNext }) => {
<div className="p-5 flex-1 is-flex is-flex-direction-column">
<label className="has-text-grey mb-2">NFT Contract Address</label>
<InputAddress
className="mt-2"
value={address}
isValid={addressValid}
onChange={onAddressChange}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,34 +1,23 @@
import React, { useContext, useState } from 'react';
import React, { useState } from 'react';
import { useModalContext } from 'contexts';
import { Web3Context } from 'contexts/Web3';
import { useAddressValidation } from 'hooks';
import { formatAddress, isAddr } from 'utils';
import { InputAddress } from 'library/components';
import { formatAddress } from 'utils';
import Svg from 'library/Svg';
import EditThreshold from '../EditThreshold';

const AddSafeOwner = ({ treasury, safeOwners }) => {
const web3 = useContext(Web3Context);
const { openModal, closeModal } = useModalContext();
const { isAddressValid } = useAddressValidation(web3.injectedProvider);
const [name, setName] = useState('');
const [address, setAddress] = useState('');
const [addressValid, setAddressValid] = useState(false);

const addressValidClass = addressValid ? 'is-success' : 'is-error';
const addrInputClasses = `input p-4 rounded-sm column is-full is-size-6 ${
address.length > 0 ? addressValidClass : ''
}`;
const nextButtonClasses = `button flex-1 is-primary ${
addressValid ? 'has-text-weight-bold' : 'disabled'
}`;

const onAddressChange = async (newAddress) => {
setAddress(newAddress);
const isValid =
isAddr(newAddress) &&
(await isAddressValid(newAddress)) &&
!isAddressExisting(safeOwners, newAddress);
setAddressValid(isValid);
const onAddressChange = async ({ value, isValid }) => {
setAddress(value);
setAddressValid(isValid && !isAddressExisting(safeOwners, value));
};

const isAddressExisting = (safeOwners, newAddress) => {
Expand Down Expand Up @@ -57,20 +46,11 @@ const AddSafeOwner = ({ treasury, safeOwners }) => {
<span className="has-text-red">*</span>{' '}
<Svg name="QuestionMark" className="ml-1" />
</label>
<div style={{ position: 'relative' }}>
<input
className={addrInputClasses}
type="text"
placeholder=""
value={address}
onChange={(e) => onAddressChange(e.target.value)}
/>
{addressValid && (
<div style={{ position: 'absolute', right: 17, top: 19 }}>
<Svg name="Check" height="15" width="15" />
</div>
)}
</div>
<InputAddress
value={address}
onChange={onAddressChange}
isValid={addressValid}
/>
</div>
<div className="flex-1 is-flex is-flex-direction-column">
<label className="has-text-grey mb-2 is-flex is-align-items-center">
Expand Down
22 changes: 18 additions & 4 deletions packages/client/src/library/components/InputAddress.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,14 @@ import { useAddressValidation } from 'hooks';
import { formatAddress, isAddr } from 'utils';
import Svg from 'library/Svg';

const InputAddress = ({ web3, value, isValid, onChange }) => {
const InputAddress = ({
web3,
value,
isValid,
onChange,
className = '',
readOnly = false,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add className to add classes needed for situational positioning/styling and readOnly to render a disabled input

}) => {
const { isAddressValid } = useAddressValidation(web3.injectedProvider);

const onValueChange = async (e) => {
Expand All @@ -17,17 +24,24 @@ const InputAddress = ({ web3, value, isValid, onChange }) => {
onChange({ value: isValid ? formatAddress(value) : value, isValid });
};

const addressValidClass = isValid ? "is-success" : "is-error";
const inputClassName = value.length ? addressValidClass : "";

return (
<div className="is-flex">
<div className={`is-flex ${className}`}>
<div className="flex-1" style={{ position: 'relative' }}>
<input
className="border-light rounded-sm column is-full p-2 mt-2"
className={`border-light rounded-sm column is-full p-4 ${inputClassName}`}
type="text"
value={value}
onChange={onValueChange}
disabled={readOnly}
/>
{isValid && (
<div style={{ position: 'absolute', right: 17, top: 20 }}>
<div
className="is-flex is-align-items-center"
style={{ position: 'absolute', right: 15, top: 0, height: '100%' }}
>
<Svg name="Check" />
</div>
)}
Expand Down
44 changes: 9 additions & 35 deletions packages/client/src/pages/CreateSafe.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,19 @@
import React, { useState } from 'react';
import { NavLink, useHistory } from 'react-router-dom';
import { Web3Consumer } from '../contexts/Web3';
import { Web3Consumer } from 'contexts/Web3';
import {
Loading,
SafeDetails,
SafeOwners,
SignatureRequirements,
WalletPrompt,
} from '../components';
import { useAddressValidation } from '../hooks';
} from 'components';
import { SAFE_TYPES } from 'constants/enums';

const AuthorizeTreasury = ({
address,
safeName,
safeType,
safeOwners,
safeOwnersValidByAddress,
createTreasury,
creatingTreasury,
createdTreasury,
Expand All @@ -25,12 +22,11 @@ const AuthorizeTreasury = ({
let isAuthorizeReady = false;
const history = useHistory();
if (safeName.trim().length && safeType) {
const everyOwnerHasValidAddress = Object.values(
safeOwnersValidByAddress
).every((isValid) => isValid);
const everyOwnerHasValidAddress = safeOwners.every(
({ isValid }) => isValid
);

if (everyOwnerHasValidAddress) {
safeOwners.map((so) => (so.verified = true));
isAuthorizeReady = true;
}
}
Expand Down Expand Up @@ -107,40 +103,20 @@ function CreateSafe({ web3 }) {
const [signersAmount, setSignersAmount] = useState(1);
const [creatingTreasury, setCreatingTreasury] = useState(false);
const [createdTreasury, setCreatedTreasury] = useState(false);
const {
injectedProvider,
address,
loadingTreasuries,
submittedTransaction,
createTreasury,
} = web3;
const { address, loadingTreasuries, submittedTransaction, createTreasury } =
web3;
const [safeOwners, setSafeOwners] = useState([
{ name: '', address, verified: true },
{ name: '', address, isValid: true },
]);
const [safeOwnersValidByAddress, setSafeOwnersValidByAddress] = useState({});
const { isAddressValid } = useAddressValidation(injectedProvider);

const checkSafeOwnerAddressesValidity = async (newSafeOwners) => {
const newSafeOwnersValidByAddress = {};

for (const so of newSafeOwners) {
newSafeOwnersValidByAddress[so.address] = await isAddressValid(
so.address
);
}

setSafeOwnersValidByAddress(newSafeOwnersValidByAddress);
};

const onSafeOwnersChange = (newSafeOwners) => {
setSafeOwners(newSafeOwners);
// skip first safe owner since it's the connected user and won't have an address
checkSafeOwnerAddressesValidity(newSafeOwners.slice(1));
// force signer amount to not exceed amount of safe owners
if (newSafeOwners.length < signersAmount) {
setSignersAmount(newSafeOwners.length);
}
};

const onCreateTreasuryClick = async (treasuryData) => {
setCreatingTreasury(true);
await createTreasury(treasuryData);
Expand Down Expand Up @@ -249,7 +225,6 @@ function CreateSafe({ web3 }) {
<SafeOwners
address={address}
safeOwners={safeOwners}
safeOwnersValidByAddress={safeOwnersValidByAddress}
setSafeOwners={onSafeOwnersChange}
/>
<SignatureRequirements
Expand All @@ -267,7 +242,6 @@ function CreateSafe({ web3 }) {
safeName={safeName}
safeType={safeType}
safeOwners={safeOwners}
safeOwnersValidByAddress={safeOwnersValidByAddress}
signersAmount={signersAmount}
createTreasury={onCreateTreasuryClick}
creatingTreasury={creatingTreasury}
Expand Down
47 changes: 12 additions & 35 deletions packages/client/src/pages/LoadSafe.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import React, { useState } from 'react';
import { NavLink, useHistory } from 'react-router-dom';
import { Web3Consumer } from '../contexts/Web3';
import { WalletPrompt } from '../components';
import { ProgressBar } from 'library/components';
import { InputAddress, ProgressBar } from 'library/components';
import { useAddressValidation } from '../hooks';
import { getProgressPercentageForSignersAmount, isAddr } from '../utils';
import { getProgressPercentageForSignersAmount } from '../utils';
import Svg from 'library/Svg';
import { isEmpty } from 'lodash';

Expand Down Expand Up @@ -78,11 +78,10 @@ function LoadSafe({ web3 }) {
setSafeOwnersValidByAddress(newSafeOwnersValidByAddress);
};

const onAddressChange = async (e) => {
setSafeAddress(e.target.value);
const maybeValid = isAddr(e.target.value);
if (maybeValid) {
const treasury = await getTreasury(e.target.value);
const onAddressChange = async ({ value, isValid }) => {
setSafeAddress(value);
if (isValid) {
const treasury = await getTreasury(value);
const newSafeOwners = Object.keys(treasury?.signers ?? {}).map(
(signerAddr) => ({
name: '',
Expand Down Expand Up @@ -142,20 +141,7 @@ function LoadSafe({ web3 }) {
</div>
<div className="flex-1 is-flex is-flex-direction-column">
<label className="has-text-grey mb-2">Owner Address</label>
<div style={{ position: 'relative' }}>
<input
className="p-4 rounded-sm column is-full"
type="text"
placeholder="Enter user's FLOW address"
value={so.address}
disabled
/>
{safeOwnersValidByAddress[so.address] && (
<div style={{ position: 'absolute', right: 17, top: 14 }}>
<Svg name="Check" />
</div>
)}
</div>
<InputAddress value={so.address} readOnly isValid />
</div>
</div>
);
Expand Down Expand Up @@ -197,20 +183,11 @@ function LoadSafe({ web3 }) {
Safe Address
<span className="has-text-red">*</span>
</label>
<div style={{ position: 'relative' }}>
<input
className="p-4 rounded-sm column is-full"
type="text"
placeholder="16-character safe address"
value={safeAddress}
onChange={onAddressChange}
/>
{!isEmpty(safeOwners) && (
<div style={{ position: 'absolute', right: 17, top: 14 }}>
<Svg name="Check" />
</div>
)}
</div>
<InputAddress
value={safeAddress}
onChange={onAddressChange}
isValid={!isEmpty(safeOwners)}
/>
</div>
</div>
<div className="column is-flex is-full">
Expand Down