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 { AvailableERC20TokenSelector } from '../containers/available_erc20_token_selector';
|
||||
import { LatestBuyQuoteOrderDetails } from '../containers/latest_buy_quote_order_details';
|
||||
import { LatestError } from '../containers/latest_error';
|
||||
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}
|
||||
onClose={this._handlePanelClose}
|
||||
>
|
||||
Select Your Token
|
||||
<AvailableERC20TokenSelector />
|
||||
</SlidingPanel>
|
||||
</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),
|
||||
updateBuyOrderState: (orderState: OrderState) => createAction(ActionTypes.UPDATE_BUY_ORDER_STATE, orderState),
|
||||
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),
|
||||
setQuoteRequestStatePending: () => createAction(ActionTypes.SET_QUOTE_REQUEST_STATE_PENDING),
|
||||
setQuoteRequestStateFailure: () => createAction(ActionTypes.SET_QUOTE_REQUEST_STATE_FAILURE),
|
||||
|
||||
@@ -14,7 +14,6 @@ import {
|
||||
OrderProcessState,
|
||||
OrderState,
|
||||
} from '../types';
|
||||
import { assetUtils } from '../util/asset';
|
||||
import { BigNumberInput } from '../util/big_number_input';
|
||||
|
||||
import { Action, ActionTypes } from './actions';
|
||||
@@ -108,18 +107,9 @@ export const reducer = (state: State = INITIAL_STATE, action: Action): State =>
|
||||
latestErrorDisplayStatus: DisplayStatus.Hidden,
|
||||
};
|
||||
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 {
|
||||
...state,
|
||||
selectedAsset: newSelectedAsset,
|
||||
selectedAsset: action.data,
|
||||
};
|
||||
case ActionTypes.RESET_AMOUNT:
|
||||
return {
|
||||
|
||||
@@ -98,4 +98,11 @@ export const assetUtils = {
|
||||
}
|
||||
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