feat: implement basic erc20 token selector
This commit is contained in:
34
packages/instant/src/components/erc20_token_selector.tsx
Normal file
34
packages/instant/src/components/erc20_token_selector.tsx
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
import * as _ from 'lodash';
|
||||||
|
import * as React from 'react';
|
||||||
|
|
||||||
|
import { ERC20Asset } from '../types';
|
||||||
|
|
||||||
|
import { Button, Container } from './ui';
|
||||||
|
|
||||||
|
export interface ERC20TokenSelectorProps {
|
||||||
|
tokens: ERC20Asset[];
|
||||||
|
onTokenSelect: (token: ERC20Asset) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const ERC20TokenSelector: React.StatelessComponent<ERC20TokenSelectorProps> = ({ tokens, onTokenSelect }) => (
|
||||||
|
<Container>{_.map(tokens, token => <TokenSelectorRow token={token} onClick={onTokenSelect} />)}</Container>
|
||||||
|
);
|
||||||
|
|
||||||
|
interface TokenSelectorRowProps {
|
||||||
|
token: ERC20Asset;
|
||||||
|
onClick: (token: ERC20Asset) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
class TokenSelectorRow extends React.Component<TokenSelectorRowProps> {
|
||||||
|
public render(): React.ReactNode {
|
||||||
|
const { token } = this.props;
|
||||||
|
return (
|
||||||
|
<Container>
|
||||||
|
<Button onClick={this._handleClick}>Select {token.metaData.symbol}</Button>
|
||||||
|
</Container>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
private readonly _handleClick = (): void => {
|
||||||
|
this.props.onClick(this.props.token);
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
|
|
||||||
|
import { AvailableERC20TokenSelector } from '../containers/available_erc20_token_selector';
|
||||||
import { LatestBuyQuoteOrderDetails } from '../containers/latest_buy_quote_order_details';
|
import { LatestBuyQuoteOrderDetails } from '../containers/latest_buy_quote_order_details';
|
||||||
import { LatestError } from '../containers/latest_error';
|
import { LatestError } from '../containers/latest_error';
|
||||||
import { SelectedAssetBuyOrderStateButtons } from '../containers/selected_asset_buy_order_state_buttons';
|
import { SelectedAssetBuyOrderStateButtons } from '../containers/selected_asset_buy_order_state_buttons';
|
||||||
@@ -45,7 +46,7 @@ export class ZeroExInstantContainer extends React.Component<ZeroExInstantContain
|
|||||||
animationState={this.state.tokenSelectionPanelAnimationState}
|
animationState={this.state.tokenSelectionPanelAnimationState}
|
||||||
onClose={this._handlePanelClose}
|
onClose={this._handlePanelClose}
|
||||||
>
|
>
|
||||||
Select Your Token
|
<AvailableERC20TokenSelector />
|
||||||
</SlidingPanel>
|
</SlidingPanel>
|
||||||
</Container>
|
</Container>
|
||||||
</Container>
|
</Container>
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
import * as React from 'react';
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
import { Dispatch } from 'redux';
|
||||||
|
|
||||||
|
import { State } from '../redux/reducer';
|
||||||
|
import { ERC20Asset } from '../types';
|
||||||
|
import { assetUtils } from '../util/asset';
|
||||||
|
|
||||||
|
import { ERC20TokenSelector } from '../components/erc20_token_selector';
|
||||||
|
import { Action, actions } from '../redux/actions';
|
||||||
|
|
||||||
|
export interface AvailableERC20TokenSelectorProps {}
|
||||||
|
|
||||||
|
interface ConnectedState {
|
||||||
|
tokens: ERC20Asset[];
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ConnectedDispatch {
|
||||||
|
onTokenSelect: (token: ERC20Asset) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const mapStateToProps = (state: State, _ownProps: AvailableERC20TokenSelectorProps): ConnectedState => ({
|
||||||
|
tokens: assetUtils.getERC20AssetsFromAssets(state.availableAssets),
|
||||||
|
});
|
||||||
|
|
||||||
|
const mapDispatchToProps = (
|
||||||
|
dispatch: Dispatch<Action>,
|
||||||
|
ownProps: AvailableERC20TokenSelectorProps,
|
||||||
|
): ConnectedDispatch => ({
|
||||||
|
onTokenSelect: (token: ERC20Asset) => dispatch(actions.updateSelectedAsset(token)),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const AvailableERC20TokenSelector: React.ComponentClass<AvailableERC20TokenSelectorProps> = connect(
|
||||||
|
mapStateToProps,
|
||||||
|
mapDispatchToProps,
|
||||||
|
)(ERC20TokenSelector);
|
||||||
@@ -43,7 +43,7 @@ export const actions = {
|
|||||||
createAction(ActionTypes.UPDATE_SELECTED_ASSET_AMOUNT, amount),
|
createAction(ActionTypes.UPDATE_SELECTED_ASSET_AMOUNT, amount),
|
||||||
updateBuyOrderState: (orderState: OrderState) => createAction(ActionTypes.UPDATE_BUY_ORDER_STATE, orderState),
|
updateBuyOrderState: (orderState: OrderState) => createAction(ActionTypes.UPDATE_BUY_ORDER_STATE, orderState),
|
||||||
updateLatestBuyQuote: (buyQuote?: BuyQuote) => createAction(ActionTypes.UPDATE_LATEST_BUY_QUOTE, buyQuote),
|
updateLatestBuyQuote: (buyQuote?: BuyQuote) => createAction(ActionTypes.UPDATE_LATEST_BUY_QUOTE, buyQuote),
|
||||||
updateSelectedAsset: (assetData?: string) => createAction(ActionTypes.UPDATE_SELECTED_ASSET, assetData),
|
updateSelectedAsset: (asset: Asset) => createAction(ActionTypes.UPDATE_SELECTED_ASSET, asset),
|
||||||
setAvailableAssets: (availableAssets: Asset[]) => createAction(ActionTypes.SET_AVAILABLE_ASSETS, availableAssets),
|
setAvailableAssets: (availableAssets: Asset[]) => createAction(ActionTypes.SET_AVAILABLE_ASSETS, availableAssets),
|
||||||
setQuoteRequestStatePending: () => createAction(ActionTypes.SET_QUOTE_REQUEST_STATE_PENDING),
|
setQuoteRequestStatePending: () => createAction(ActionTypes.SET_QUOTE_REQUEST_STATE_PENDING),
|
||||||
setQuoteRequestStateFailure: () => createAction(ActionTypes.SET_QUOTE_REQUEST_STATE_FAILURE),
|
setQuoteRequestStateFailure: () => createAction(ActionTypes.SET_QUOTE_REQUEST_STATE_FAILURE),
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ import {
|
|||||||
OrderProcessState,
|
OrderProcessState,
|
||||||
OrderState,
|
OrderState,
|
||||||
} from '../types';
|
} from '../types';
|
||||||
import { assetUtils } from '../util/asset';
|
|
||||||
import { BigNumberInput } from '../util/big_number_input';
|
import { BigNumberInput } from '../util/big_number_input';
|
||||||
|
|
||||||
import { Action, ActionTypes } from './actions';
|
import { Action, ActionTypes } from './actions';
|
||||||
@@ -108,18 +107,9 @@ export const reducer = (state: State = INITIAL_STATE, action: Action): State =>
|
|||||||
latestErrorDisplayStatus: DisplayStatus.Hidden,
|
latestErrorDisplayStatus: DisplayStatus.Hidden,
|
||||||
};
|
};
|
||||||
case ActionTypes.UPDATE_SELECTED_ASSET:
|
case ActionTypes.UPDATE_SELECTED_ASSET:
|
||||||
const newSelectedAssetData = action.data;
|
|
||||||
let newSelectedAsset: Asset | undefined;
|
|
||||||
if (!_.isUndefined(newSelectedAssetData)) {
|
|
||||||
newSelectedAsset = assetUtils.createAssetFromAssetDataOrThrow(
|
|
||||||
newSelectedAssetData,
|
|
||||||
state.assetMetaDataMap,
|
|
||||||
state.network,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
selectedAsset: newSelectedAsset,
|
selectedAsset: action.data,
|
||||||
};
|
};
|
||||||
case ActionTypes.RESET_AMOUNT:
|
case ActionTypes.RESET_AMOUNT:
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -98,4 +98,11 @@ export const assetUtils = {
|
|||||||
}
|
}
|
||||||
return assetDataGroupIfExists[Network.Mainnet];
|
return assetDataGroupIfExists[Network.Mainnet];
|
||||||
},
|
},
|
||||||
|
getERC20AssetsFromAssets: (assets: Asset[]): ERC20Asset[] => {
|
||||||
|
const erc20sOrUndefined = _.map(
|
||||||
|
assets,
|
||||||
|
asset => (asset.metaData.assetProxyId === AssetProxyId.ERC20 ? (asset as ERC20Asset) : undefined),
|
||||||
|
);
|
||||||
|
return _.compact(erc20sOrUndefined);
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user