Merge v2-prototype
This commit is contained in:
		| @@ -16,17 +16,19 @@ | ||||
|     "types": "lib/src/index.d.ts", | ||||
|     "scripts": { | ||||
|         "watch_without_deps": "yarn pre_build && tsc -w", | ||||
|         "build": "yarn pre_build && tsc && copyfiles -u 3 './lib/src/monorepo_scripts/**/*' ./scripts", | ||||
|         "build": "yarn pre_build && build:all && copyfiles -u 3 './lib/src/monorepo_scripts/**/*' ./scripts", | ||||
|         "pre_build": "run-s generate_contract_wrappers copy_artifacts", | ||||
|         "copy_artifacts": "copyfiles -u 2 './src/compact_artifacts/**/*.json' ./lib/src/compact_artifacts", | ||||
|         "generate_contract_wrappers": "abi-gen --abis 'src/compact_artifacts/@(Exchange|Token|TokenTransferProxy|EtherToken|TokenRegistry|DummyToken).json' --template ../contract_templates/contract.handlebars --partials '../contract_templates/partials/**/*.handlebars' --output src/contract_wrappers/generated --backend ethers && prettier --write 'src/contract_wrappers/generated/**.ts'", | ||||
|         "lint": "tslint --project .", | ||||
|         "test:circleci": "run-s test:coverage", | ||||
|         "test": "yarn run_mocha", | ||||
|         "rebuild-and-test": "run-s build test", | ||||
|         "rebuild_and_test": "run-s build test", | ||||
|         "test:coverage": "nyc npm run test --all && yarn coverage:report:lcov", | ||||
|         "coverage:report:lcov": "nyc report --reporter=text-lcov > coverage/lcov.info", | ||||
|         "clean": "shx rm -rf _bundles lib test_temp scripts src/contract_wrappers/generated", | ||||
|         "build:umd:prod": "NODE_ENV=production webpack", | ||||
|         "build:commonjs": "tsc && copyfiles -u 2 './src/compact_artifacts/**/*.json' ./lib/src/compact_artifacts && copyfiles -u 3 './lib/src/monorepo_scripts/**/*' ./scripts", | ||||
|         "run_mocha": "mocha lib/test/**/*_test.js lib/test/global_hooks.js --timeout 10000 --bail --exit", | ||||
|         "manual:postpublish": "yarn build; node ./scripts/postpublish.js", | ||||
|         "docs:stage": "node scripts/stage_docs.js", | ||||
|   | ||||
| @@ -4,8 +4,7 @@ This package allows you to generate TypeScript contract wrappers from ABI files. | ||||
| It's heavily inspired by [Geth abigen](https://github.com/ethereum/go-ethereum/wiki/Native-DApps:-Go-bindings-to-Ethereum-contracts) but takes a different approach. | ||||
| You can write your custom handlebars templates which will allow you to seamlessly integrate the generated code into your existing codebase with existing conventions. | ||||
|  | ||||
| For an example of the generated [wrapper files](https://github.com/0xProject/0x-monorepo/tree/development/packages/0x.js/src/contract_wrappers/generated) check out 0x.js. | ||||
| [Here](https://github.com/0xProject/0x-monorepo/tree/development/packages/contract_templates) are the templates used to generate those files. | ||||
| [Here](https://github.com/0xProject/0x-monorepo/tree/development/packages/0x.js/contract_templates) are the templates used to generate the contract wrappers used by 0x.js.e | ||||
|  | ||||
| ## Installation | ||||
|  | ||||
|   | ||||
| @@ -15,7 +15,7 @@ | ||||
|         "run_mocha": "mocha lib/test/**/*_test.js --exit", | ||||
|         "prepublishOnly": "run-p build", | ||||
|         "test": "yarn run_mocha", | ||||
|         "rebuild-and-test": "run-s clean build test", | ||||
|         "rebuild_and_test": "run-s clean build test", | ||||
|         "test:coverage": "nyc npm run test --all && yarn coverage:report:lcov", | ||||
|         "coverage:report:lcov": "nyc report --reporter=text-lcov > coverage/lcov.info", | ||||
|         "test:circleci": "yarn test:coverage", | ||||
|   | ||||
| @@ -12,7 +12,7 @@ | ||||
|         "build": "tsc && copyfiles -u 2 './lib/monorepo_scripts/**/*' ./scripts", | ||||
|         "clean": "shx rm -rf lib scripts", | ||||
|         "test": "yarn run_mocha", | ||||
|         "rebuild-and-test": "run-s clean build test", | ||||
|         "rebuild_and_test": "run-s clean build test", | ||||
|         "test:circleci": "yarn test:coverage", | ||||
|         "run_mocha": "mocha lib/test/**/*_test.js --bail --exit", | ||||
|         "test:coverage": "nyc npm run test --all && yarn coverage:report:lcov", | ||||
|   | ||||
| @@ -22,7 +22,7 @@ | ||||
|         "lint": "tslint --project .", | ||||
|         "run_mocha": "mocha lib/test/**/*_test.js --exit", | ||||
|         "test": "run-s copy_test_fixtures run_mocha", | ||||
|         "rebuild-and-test": "run-s clean build test", | ||||
|         "rebuild_and_test": "run-s clean build test", | ||||
|         "test:coverage": "nyc npm run test --all && yarn coverage:report:lcov", | ||||
|         "coverage:report:lcov": "nyc report --reporter=text-lcov > coverage/lcov.info", | ||||
|         "test:circleci": "yarn test:coverage", | ||||
|   | ||||
| @@ -18,7 +18,7 @@ | ||||
|         "lint": "tslint --project .", | ||||
|         "test:circleci": "run-s test:coverage", | ||||
|         "test": "yarn run_mocha", | ||||
|         "rebuild-and-test": "run-s build test", | ||||
|         "rebuild_and_test": "run-s build test", | ||||
|         "test:coverage": "nyc npm run test --all && yarn coverage:report:lcov", | ||||
|         "coverage:report:lcov": "nyc report --reporter=text-lcov > coverage/lcov.info", | ||||
|         "update_compact_artifacts": "copyfiles -u 2 './src/compact_artifacts/**/*.json' ./lib/src/compact_artifacts", | ||||
|   | ||||
| @@ -158,7 +158,7 @@ export interface MethodOpts { | ||||
|  | ||||
| /** | ||||
|  * gasPrice: Gas price in Wei to use for a transaction | ||||
|  * gasLimit: The amount of gas to send with a transaction | ||||
|  * gasLimit: The amount of gas to send with a transaction (in Gwei) | ||||
|  */ | ||||
| export interface TransactionOpts { | ||||
|     gasPrice?: BigNumber; | ||||
|   | ||||
| @@ -16,7 +16,7 @@ | ||||
|         "pre_build": "run-s compile copy_artifacts generate_contract_wrappers", | ||||
|         "copy_artifacts": "copyfiles -u 4 '../migrations/artifacts/2.0.0/**/*' ./lib/src/artifacts;", | ||||
|         "test": "yarn run_mocha", | ||||
|         "rebuild-and-test": "run-s build test", | ||||
|         "rebuild_and_test": "run-s build test", | ||||
|         "test:coverage": "SOLIDITY_COVERAGE=true run-s build run_mocha coverage:report:text coverage:report:lcov", | ||||
|         "run_mocha": "mocha 'lib/test/**/*.js' --timeout 100000 --bail --exit", | ||||
|         "compile": "sol-compiler", | ||||
|   | ||||
| @@ -11,7 +11,7 @@ | ||||
|         "watch_without_deps": "tsc -w", | ||||
|         "build": "tsc && copyfiles -u 3 './lib/src/monorepo_scripts/**/*' ./scripts", | ||||
|         "test": "yarn run_mocha", | ||||
|         "rebuild-and-test": "run-s clean build test", | ||||
|         "rebuild_and_test": "run-s clean build test", | ||||
|         "test:circleci": "yarn test:coverage", | ||||
|         "run_mocha": "mocha lib/test/**/*_test.js --bail --exit", | ||||
|         "test:coverage": "nyc npm run test --all && yarn coverage:report:lcov", | ||||
|   | ||||
| @@ -11,7 +11,7 @@ | ||||
|         "watch_without_deps": "tsc -w", | ||||
|         "lint": "tslint --project .", | ||||
|         "test": "yarn run_mocha", | ||||
|         "rebuild-and-test": "run-s clean build test", | ||||
|         "rebuild_and_test": "run-s clean build test", | ||||
|         "test:coverage": "nyc npm run test --all && yarn coverage:report:lcov", | ||||
|         "coverage:report:lcov": "nyc report --reporter=text-lcov > coverage/lcov.info", | ||||
|         "test:circleci": "yarn test:coverage", | ||||
|   | ||||
| @@ -14,7 +14,7 @@ | ||||
|         "clean": "shx rm -rf lib artifacts src/contract_wrappers", | ||||
|         "copy_artifacts": "copyfiles './artifacts/**/*' './contracts/**/*' ./lib", | ||||
|         "test": "yarn run_mocha", | ||||
|         "rebuild-and-test": "run-s build test", | ||||
|         "rebuild_and_test": "run-s build test", | ||||
|         "test:coverage": "SOLIDITY_COVERAGE=true run-s build run_mocha coverage:report:text coverage:report:lcov", | ||||
|         "run_mocha": "mocha lib/test/**/*_test.js lib/test/global_hooks.js --bail --exit", | ||||
|         "generate_contract_wrappers": "abi-gen --abis 'artifacts/Metacoin.json' --template ../contract_templates/contract.handlebars --partials '../contract_templates/partials/**/*.handlebars' --output src/contract_wrappers --backend ethers && prettier --write 'src/contract_wrappers/**.ts'", | ||||
|   | ||||
| @@ -16,7 +16,7 @@ | ||||
|         "generate_contract_wrappers": "abi-gen --abis 'lib/src/artifacts/@(Exchange|IWallet|IValidator).json' --template ../contract_templates/contract.handlebars --partials '../contract_templates/partials/**/*.handlebars' --output src/generated_contract_wrappers --backend ethers && prettier --write 'src/generated_contract_wrappers/**.ts'", | ||||
|         "update_artifacts": "for i in ${npm_package_config_contracts}; do copyfiles -u 4 ../migrations/artifacts/2.0.0/$i.json lib/src/artifacts; done;", | ||||
|         "test": "yarn run_mocha", | ||||
|         "rebuild-and-test": "run-s build test", | ||||
|         "rebuild_and_test": "run-s build test", | ||||
|         "test:circleci": "yarn test:coverage", | ||||
|         "run_mocha": "mocha lib/test/**/*_test.js --bail --exit", | ||||
|         "test:coverage": "nyc npm run test --all && yarn coverage:report:lcov", | ||||
|   | ||||
| @@ -19,7 +19,7 @@ | ||||
|         "lint": "tslint --project .", | ||||
|         "test:circleci": "run-s test:coverage", | ||||
|         "test": "yarn run_mocha", | ||||
|         "rebuild-and-test": "run-s build test", | ||||
|         "rebuild_and_test": "run-s build test", | ||||
|         "test:coverage": "nyc npm run test --all && yarn coverage:report:lcov", | ||||
|         "coverage:report:lcov": "nyc report --reporter=text-lcov > coverage/lcov.info", | ||||
|         "update_compact_artifacts": "copyfiles -u 2 './src/compact_artifacts/**/*.json' ./lib/src/compact_artifacts", | ||||
|   | ||||
| @@ -22,7 +22,6 @@ const baseColors = { | ||||
|     heroGrey: '#404040', | ||||
|     projectsGrey: '#343333', | ||||
|     darkestGrey: '#272727', | ||||
|     dharmaDarkGrey: '#252525', | ||||
|     lightBlue: '#60A4F4', | ||||
|     lightBlueA700: '#0091EA', | ||||
|     linkBlue: '#1D5CDE', | ||||
|   | ||||
| @@ -13,7 +13,7 @@ | ||||
|         "pre_build": "run-s update_contract_fixtures", | ||||
|         "update_contract_fixtures": "copyfiles 'test/fixtures/contracts/**/*' ./lib", | ||||
|         "test": "yarn run_mocha", | ||||
|         "rebuild-and-test": "run-s build test", | ||||
|         "rebuild_and_test": "run-s build test", | ||||
|         "run_mocha": "mocha lib/test/*_test.js --bail --exit", | ||||
|         "test:coverage": "nyc npm run test --all && yarn coverage:report:lcov", | ||||
|         "coverage:report:lcov": "nyc report --reporter=text-lcov > coverage/lcov.info", | ||||
|   | ||||
| @@ -13,7 +13,7 @@ | ||||
|         "pre_build": "run-s copy_test_fixtures", | ||||
|         "lint": "tslint --project .", | ||||
|         "test": "run-s compile_test run_mocha", | ||||
|         "rebuild-and-test": "run-s clean build test", | ||||
|         "rebuild_and_test": "run-s clean build test", | ||||
|         "test:coverage": "nyc npm run test --all && yarn coverage:report:lcov", | ||||
|         "coverage:report:lcov": "nyc report --reporter=text-lcov > coverage/lcov.info", | ||||
|         "test:circleci": "yarn test:coverage", | ||||
|   | ||||
| @@ -13,7 +13,7 @@ | ||||
|         "build": "tsc && copyfiles -u 3 './lib/src/monorepo_scripts/**/*' ./scripts", | ||||
|         "lint": "tslint --project .", | ||||
|         "test": "run-s copy_test_environments copy_test_fixtures run_mocha", | ||||
|         "rebuild-and-test": "run-s clean build test", | ||||
|         "rebuild_and_test": "run-s clean build test", | ||||
|         "copy_test_fixtures": "copyfiles -u 2 './test/fixtures/**/*.json' ./lib/test/fixtures", | ||||
|         "copy_test_environments": "copyfiles -u 2 './test/environments/**/*.json' ./lib/test/environments", | ||||
|         "run_mocha": "mocha lib/test/**/*_test.js --exit", | ||||
|   | ||||
| @@ -7,6 +7,7 @@ | ||||
|         "async-suffix": true, | ||||
|         "boolean-naming": true, | ||||
|         "no-switch-case-fall-through": true, | ||||
|         "switch-default": true, | ||||
|         "await-promise": true, | ||||
|         "custom-no-magic-numbers": [true, 0, 1, 2, 3, -1], | ||||
|         "binary-expression-operand-order": true, | ||||
|   | ||||
| @@ -13,7 +13,7 @@ | ||||
|         "clean": "shx rm -rf lib scripts", | ||||
|         "lint": "tslint --project .", | ||||
|         "test": "yarn run_mocha", | ||||
|         "rebuild-and-test": "run-s clean build test", | ||||
|         "rebuild_and_test": "run-s clean build test", | ||||
|         "test:circleci": "yarn test:coverage", | ||||
|         "run_mocha": "mocha lib/test/**/*_test.js --bail --exit", | ||||
|         "test:coverage": "nyc npm run test --all && yarn coverage:report:lcov", | ||||
|   | ||||
| @@ -37,6 +37,7 @@ | ||||
|         "lodash": "^4.17.4", | ||||
|         "material-ui": "^0.17.1", | ||||
|         "moment": "2.21.0", | ||||
|         "polished": "^1.9.2", | ||||
|         "query-string": "^6.0.0", | ||||
|         "react": "15.6.1", | ||||
|         "react-copy-to-clipboard": "^4.2.3", | ||||
| @@ -52,6 +53,7 @@ | ||||
|         "redux": "^3.6.0", | ||||
|         "redux-devtools-extension": "^2.13.2", | ||||
|         "semver-sort": "0.0.4", | ||||
|         "styled-components": "^3.3.0", | ||||
|         "thenby": "^1.2.3", | ||||
|         "truffle-contract": "2.0.1", | ||||
|         "web3": "^0.20.0", | ||||
|   | ||||
							
								
								
									
										124
									
								
								packages/website/ts/components/forms/subscribe_form.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										124
									
								
								packages/website/ts/components/forms/subscribe_form.tsx
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,124 @@ | ||||
| import { colors } from '@0xproject/react-shared'; | ||||
| import * as _ from 'lodash'; | ||||
| import * as React from 'react'; | ||||
|  | ||||
| import { Button } from 'ts/components/ui/button'; | ||||
| import { Container } from 'ts/components/ui/container'; | ||||
| import { Input } from 'ts/components/ui/input'; | ||||
| import { Text } from 'ts/components/ui/text'; | ||||
| import { styled } from 'ts/style/theme'; | ||||
| import { backendClient } from 'ts/utils/backend_client'; | ||||
|  | ||||
| export interface SubscribeFormProps {} | ||||
|  | ||||
| export enum SubscribeFormStatus { | ||||
|     None, | ||||
|     Error, | ||||
|     Success, | ||||
|     Loading, | ||||
|     Other, | ||||
| } | ||||
|  | ||||
| export interface SubscribeFormState { | ||||
|     emailText: string; | ||||
|     lastSubmittedEmail: string; | ||||
|     status: SubscribeFormStatus; | ||||
| } | ||||
|  | ||||
| const FORM_FONT_SIZE = '15px'; | ||||
|  | ||||
| // TODO: Translate visible strings. https://app.asana.com/0/628666249318202/697485674422001 | ||||
| export class SubscribeForm extends React.Component<SubscribeFormProps, SubscribeFormState> { | ||||
|     public state = { | ||||
|         emailText: '', | ||||
|         lastSubmittedEmail: '', | ||||
|         status: SubscribeFormStatus.None, | ||||
|     }; | ||||
|     public render(): React.ReactNode { | ||||
|         return ( | ||||
|             <Container className="flex flex-column items-center justify-between md-mx2 sm-mx2"> | ||||
|                 <Container marginBottom="15px"> | ||||
|                     <Text fontFamily="Roboto Mono" fontColor={colors.grey} center={true}> | ||||
|                         Subscribe to our newsletter for 0x relayer and dApp updates | ||||
|                     </Text> | ||||
|                 </Container> | ||||
|                 <form onSubmit={this._handleFormSubmitAsync.bind(this)}> | ||||
|                     <Container className="flex flex-wrap justify-center items-center"> | ||||
|                         <Container marginTop="15px"> | ||||
|                             <Input | ||||
|                                 placeholder="you@email.com" | ||||
|                                 value={this.state.emailText} | ||||
|                                 fontColor={colors.white} | ||||
|                                 fontSize={FORM_FONT_SIZE} | ||||
|                                 backgroundColor={colors.projectsGrey} | ||||
|                                 width="300px" | ||||
|                                 onChange={this._handleEmailInputChange.bind(this)} | ||||
|                             /> | ||||
|                         </Container> | ||||
|                         <Container marginLeft="15px" marginTop="15px"> | ||||
|                             <Button | ||||
|                                 type="submit" | ||||
|                                 backgroundColor={colors.darkestGrey} | ||||
|                                 fontColor={colors.white} | ||||
|                                 fontSize={FORM_FONT_SIZE} | ||||
|                             > | ||||
|                                 Subscribe | ||||
|                             </Button> | ||||
|                         </Container> | ||||
|                     </Container> | ||||
|                 </form> | ||||
|                 {this._renderMessage()} | ||||
|             </Container> | ||||
|         ); | ||||
|     } | ||||
|     private _renderMessage(): React.ReactNode { | ||||
|         let message = null; | ||||
|         switch (this.state.status) { | ||||
|             case SubscribeFormStatus.Error: | ||||
|                 message = 'Sorry, something went wrong. Try again later.'; | ||||
|                 break; | ||||
|             case SubscribeFormStatus.Loading: | ||||
|                 message = 'One second...'; | ||||
|                 break; | ||||
|             case SubscribeFormStatus.Success: | ||||
|                 message = `Thanks! ${this.state.lastSubmittedEmail} is now on the mailing list.`; | ||||
|                 break; | ||||
|             case SubscribeFormStatus.None: | ||||
|                 break; | ||||
|             default: | ||||
|                 throw new Error( | ||||
|                     'The SubscribeFormStatus switch statement is not exhaustive when choosing an error message.', | ||||
|                 ); | ||||
|         } | ||||
|         return ( | ||||
|             <Container isHidden={!message} marginTop="30px"> | ||||
|                 <Text center={true} fontFamily="Roboto Mono" fontColor={colors.grey}> | ||||
|                     {message || 'spacer text (never shown to user)'} | ||||
|                 </Text> | ||||
|             </Container> | ||||
|         ); | ||||
|     } | ||||
|     private _handleEmailInputChange(event: React.ChangeEvent<HTMLInputElement>): void { | ||||
|         this.setState({ emailText: event.target.value }); | ||||
|     } | ||||
|     private async _handleFormSubmitAsync(event: React.FormEvent<HTMLInputElement>): Promise<void> { | ||||
|         event.preventDefault(); | ||||
|         if (_.isUndefined(this.state.emailText) || _.isEmpty(this.state.emailText)) { | ||||
|             return; | ||||
|         } | ||||
|         this.setState({ | ||||
|             status: SubscribeFormStatus.Loading, | ||||
|             lastSubmittedEmail: this.state.emailText, | ||||
|         }); | ||||
|         try { | ||||
|             const response = await backendClient.subscribeToNewsletterAsync(this.state.emailText); | ||||
|             const status = response.status === 200 ? SubscribeFormStatus.Success : SubscribeFormStatus.Error; | ||||
|             this.setState({ status, emailText: '' }); | ||||
|         } catch (error) { | ||||
|             this._setStatus(SubscribeFormStatus.Error); | ||||
|         } | ||||
|     } | ||||
|     private _setStatus(status: SubscribeFormStatus): void { | ||||
|         this.setState({ status }); | ||||
|     } | ||||
| } | ||||
| @@ -5,9 +5,9 @@ import Toggle from 'material-ui/Toggle'; | ||||
| import * as React from 'react'; | ||||
| import { Blockchain } from 'ts/blockchain'; | ||||
| import { Dispatcher } from 'ts/redux/dispatcher'; | ||||
| import { colors } from 'ts/style/colors'; | ||||
| import { BalanceErrs, Token, TokenState } from 'ts/types'; | ||||
| import { analytics } from 'ts/utils/analytics'; | ||||
| import { colors } from 'ts/utils/colors'; | ||||
| import { constants } from 'ts/utils/constants'; | ||||
| import { errorReporter } from 'ts/utils/error_reporter'; | ||||
| import { utils } from 'ts/utils/utils'; | ||||
|   | ||||
| @@ -5,7 +5,7 @@ import { Placement, Popper, PopperChildrenProps } from 'react-popper'; | ||||
| import { ContinueButtonDisplay, OnboardingTooltip } from 'ts/components/onboarding/onboarding_tooltip'; | ||||
| import { Container } from 'ts/components/ui/container'; | ||||
| import { Overlay } from 'ts/components/ui/overlay'; | ||||
| import { zIndex } from 'ts/utils/style'; | ||||
| import { zIndex } from 'ts/style/z_index'; | ||||
|  | ||||
| export interface Step { | ||||
|     target: string; | ||||
|   | ||||
| @@ -2,7 +2,7 @@ import { Styles } from '@0xproject/react-shared'; | ||||
| import * as React from 'react'; | ||||
| import { Link } from 'react-router-dom'; | ||||
|  | ||||
| import { colors } from 'ts/utils/colors'; | ||||
| import { colors } from 'ts/style/colors'; | ||||
|  | ||||
| export interface BackButtonProps { | ||||
|     to: string; | ||||
|   | ||||
| @@ -4,8 +4,8 @@ import * as React from 'react'; | ||||
|  | ||||
| import { defaultMenuItemEntries, Menu } from 'ts/components/portal/menu'; | ||||
| import { Identicon } from 'ts/components/ui/identicon'; | ||||
| import { colors } from 'ts/style/colors'; | ||||
| import { WebsitePaths } from 'ts/types'; | ||||
| import { colors } from 'ts/utils/colors'; | ||||
| import { utils } from 'ts/utils/utils'; | ||||
|  | ||||
| const IDENTICON_DIAMETER = 45; | ||||
|   | ||||
| @@ -2,8 +2,8 @@ import { Styles } from '@0xproject/react-shared'; | ||||
| import * as _ from 'lodash'; | ||||
| import * as React from 'react'; | ||||
| import { MenuItem } from 'ts/components/ui/menu_item'; | ||||
| import { colors } from 'ts/style/colors'; | ||||
| import { Environments, WebsitePaths } from 'ts/types'; | ||||
| import { colors } from 'ts/utils/colors'; | ||||
| import { configs } from 'ts/utils/configs'; | ||||
|  | ||||
| export interface MenuTheme { | ||||
|   | ||||
| @@ -34,6 +34,7 @@ import { Dispatcher } from 'ts/redux/dispatcher'; | ||||
| import { | ||||
|     BlockchainErrs, | ||||
|     HashData, | ||||
|     ItemByAddress, | ||||
|     Order, | ||||
|     ProviderType, | ||||
|     ScreenWidths, | ||||
| @@ -43,6 +44,7 @@ import { | ||||
|     TokenVisibility, | ||||
|     WebsitePaths, | ||||
| } from 'ts/types'; | ||||
| import { backendClient } from 'ts/utils/backend_client'; | ||||
| import { configs } from 'ts/utils/configs'; | ||||
| import { constants } from 'ts/utils/constants'; | ||||
| import { orderParser } from 'ts/utils/order_parser'; | ||||
| @@ -266,10 +268,6 @@ export class Portal extends React.Component<PortalProps, PortalState> { | ||||
|                         toggleDialogFn={updateShouldBlockchainErrDialogBeOpen} | ||||
|                         networkId={this.props.networkId} | ||||
|                     /> | ||||
|                     <PortalDisclaimerDialog | ||||
|                         isOpen={this.state.isDisclaimerDialogOpen} | ||||
|                         onToggleDialog={this._onPortalDisclaimerAccepted.bind(this)} | ||||
|                     /> | ||||
|                     <FlashMessage dispatcher={this.props.dispatcher} flashMessage={this.props.flashMessage} /> | ||||
|                     {this.props.blockchainIsLoaded && ( | ||||
|                         <LedgerConfigDialog | ||||
| @@ -394,6 +392,7 @@ export class Portal extends React.Component<PortalProps, PortalState> { | ||||
|             }, | ||||
|         ]; | ||||
|         return ( | ||||
|             <div> | ||||
|                 <Switch> | ||||
|                     {_.map(accountManagementItems, item => { | ||||
|                         return ( | ||||
| @@ -406,6 +405,11 @@ export class Portal extends React.Component<PortalProps, PortalState> { | ||||
|                     })}} | ||||
|                     <Route render={this._renderNotFoundMessage.bind(this)} /> | ||||
|                 </Switch> | ||||
|                 <PortalDisclaimerDialog | ||||
|                     isOpen={this.state.isDisclaimerDialogOpen} | ||||
|                     onToggleDialog={this._onPortalDisclaimerAccepted.bind(this)} | ||||
|                 /> | ||||
|             </div> | ||||
|         ); | ||||
|     } | ||||
|     private _renderAccountManagementItem(item: AccountManagementItem): React.ReactNode { | ||||
| @@ -587,6 +591,7 @@ export class Portal extends React.Component<PortalProps, PortalState> { | ||||
|                 return this._blockchain.getTokenBalanceAndAllowanceAsync(userAddressIfExists, tokenAddress); | ||||
|             }), | ||||
|         ); | ||||
|         const priceByAddress = await this._getPriceByAddressAsync(tokenAddresses); | ||||
|         for (let i = 0; i < tokenAddresses.length; i++) { | ||||
|             // Order is preserved in Promise.all | ||||
|             const [balance, allowance] = balancesAndAllowances[i]; | ||||
| @@ -595,6 +600,7 @@ export class Portal extends React.Component<PortalProps, PortalState> { | ||||
|                 balance, | ||||
|                 allowance, | ||||
|                 isLoaded: true, | ||||
|                 price: priceByAddress[tokenAddress], | ||||
|             }; | ||||
|         } | ||||
|         this.setState({ | ||||
| @@ -602,6 +608,34 @@ export class Portal extends React.Component<PortalProps, PortalState> { | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     private async _getPriceByAddressAsync(tokenAddresses: string[]): Promise<ItemByAddress<BigNumber>> { | ||||
|         if (_.isEmpty(tokenAddresses)) { | ||||
|             return {}; | ||||
|         } | ||||
|         // for each input token address, search for the corresponding symbol in this.props.tokenByAddress, if it exists | ||||
|         // create a mapping from existing symbols -> address | ||||
|         const tokenAddressBySymbol: { [symbol: string]: string } = {}; | ||||
|         _.each(tokenAddresses, address => { | ||||
|             const tokenIfExists = _.get(this.props.tokenByAddress, address); | ||||
|             if (!_.isUndefined(tokenIfExists)) { | ||||
|                 const symbol = tokenIfExists.symbol; | ||||
|                 tokenAddressBySymbol[symbol] = address; | ||||
|             } | ||||
|         }); | ||||
|         const tokenSymbols = _.keys(tokenAddressBySymbol); | ||||
|         try { | ||||
|             const priceBySymbol = await backendClient.getPriceInfoAsync(tokenSymbols); | ||||
|             const priceByAddress = _.mapKeys(priceBySymbol, (value, symbol) => _.get(tokenAddressBySymbol, symbol)); | ||||
|             const result = _.mapValues(priceByAddress, price => { | ||||
|                 const priceBigNumber = new BigNumber(price); | ||||
|                 return priceBigNumber; | ||||
|             }); | ||||
|             return result; | ||||
|         } catch (err) { | ||||
|             return {}; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private async _refetchTokenStateAsync(tokenAddress: string): Promise<void> { | ||||
|         await this._fetchBalancesAndAllowancesAsync([tokenAddress]); | ||||
|     } | ||||
|   | ||||
| @@ -7,8 +7,8 @@ import { TopTokens } from 'ts/components/relayer_index/relayer_top_tokens'; | ||||
| import { Container } from 'ts/components/ui/container'; | ||||
| import { Island } from 'ts/components/ui/island'; | ||||
| import { TokenIcon } from 'ts/components/ui/token_icon'; | ||||
| import { colors } from 'ts/style/colors'; | ||||
| import { Token, WebsiteBackendRelayerInfo } from 'ts/types'; | ||||
| import { colors } from 'ts/utils/colors'; | ||||
|  | ||||
| export interface RelayerGridTileProps { | ||||
|     relayerInfo: WebsiteBackendRelayerInfo; | ||||
|   | ||||
| @@ -6,9 +6,9 @@ import { GridList } from 'material-ui/GridList'; | ||||
| import * as React from 'react'; | ||||
|  | ||||
| import { RelayerGridTile } from 'ts/components/relayer_index/relayer_grid_tile'; | ||||
| import { colors } from 'ts/style/colors'; | ||||
| import { ScreenWidths, WebsiteBackendRelayerInfo } from 'ts/types'; | ||||
| import { backendClient } from 'ts/utils/backend_client'; | ||||
| import { colors } from 'ts/utils/colors'; | ||||
|  | ||||
| export interface RelayerIndexProps { | ||||
|     networkId: number; | ||||
|   | ||||
| @@ -77,11 +77,11 @@ interface TokenBalancesProps { | ||||
|  | ||||
| interface TokenBalancesState { | ||||
|     errorType: BalanceErrs; | ||||
|     trackedTokenStateByAddress: TokenStateByAddress; | ||||
|     isBalanceSpinnerVisible: boolean; | ||||
|     isZRXSpinnerVisible: boolean; | ||||
|     isTokenPickerOpen: boolean; | ||||
|     isAddingToken: boolean; | ||||
|     trackedTokenStateByAddress: TokenStateByAddress; | ||||
| } | ||||
|  | ||||
| export class TokenBalances extends React.Component<TokenBalancesProps, TokenBalancesState> { | ||||
|   | ||||
| @@ -9,10 +9,10 @@ import { ProviderPicker } from 'ts/components/top_bar/provider_picker'; | ||||
| import { DropDown } from 'ts/components/ui/drop_down'; | ||||
| import { Identicon } from 'ts/components/ui/identicon'; | ||||
| import { Dispatcher } from 'ts/redux/dispatcher'; | ||||
| import { colors } from 'ts/style/colors'; | ||||
| import { zIndex } from 'ts/style/z_index'; | ||||
| import { ProviderType } from 'ts/types'; | ||||
| import { colors } from 'ts/utils/colors'; | ||||
| import { constants } from 'ts/utils/constants'; | ||||
| import { zIndex } from 'ts/utils/style'; | ||||
| import { utils } from 'ts/utils/utils'; | ||||
|  | ||||
| const ROOT_HEIGHT = 24; | ||||
|   | ||||
| @@ -16,9 +16,9 @@ import { TopBarMenuItem } from 'ts/components/top_bar/top_bar_menu_item'; | ||||
| import { DropDown } from 'ts/components/ui/drop_down'; | ||||
| import { Identicon } from 'ts/components/ui/identicon'; | ||||
| import { Dispatcher } from 'ts/redux/dispatcher'; | ||||
| import { zIndex } from 'ts/style/z_index'; | ||||
| import { Deco, Key, ProviderType, WebsiteLegacyPaths, WebsitePaths } from 'ts/types'; | ||||
| import { constants } from 'ts/utils/constants'; | ||||
| import { zIndex } from 'ts/utils/style'; | ||||
| import { Translate } from 'ts/utils/translate'; | ||||
| import { utils } from 'ts/utils/utils'; | ||||
|  | ||||
|   | ||||
							
								
								
									
										79
									
								
								packages/website/ts/components/ui/button.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								packages/website/ts/components/ui/button.tsx
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,79 @@ | ||||
| import { colors } from '@0xproject/react-shared'; | ||||
| import { darken } from 'polished'; | ||||
| import * as React from 'react'; | ||||
| import { styled } from 'ts/style/theme'; | ||||
|  | ||||
| export interface ButtonProps { | ||||
|     className?: string; | ||||
|     fontSize?: string; | ||||
|     fontColor?: string; | ||||
|     backgroundColor?: string; | ||||
|     borderColor?: string; | ||||
|     width?: string; | ||||
|     type?: string; | ||||
|     onClick?: (event: React.MouseEvent<HTMLElement>) => void; | ||||
| } | ||||
|  | ||||
| const PlainButton: React.StatelessComponent<ButtonProps> = ({ children, onClick, type, className }) => ( | ||||
|     <button type={type} className={className} onClick={onClick}> | ||||
|         {children} | ||||
|     </button> | ||||
| ); | ||||
|  | ||||
| export const Button = styled(PlainButton)` | ||||
|     cursor: pointer; | ||||
|     font-size: ${props => props.fontSize}; | ||||
|     color: ${props => props.fontColor}; | ||||
|     padding: 0.8em 2.2em; | ||||
|     border-radius: 6px; | ||||
|     box-shadow: 0px 0px 4px rgba(0, 0, 0, 0.25); | ||||
|     font-weight: 500; | ||||
|     font-family: 'Roboto'; | ||||
|     width: ${props => props.width}; | ||||
|     background-color: ${props => props.backgroundColor}; | ||||
|     border: ${props => (props.borderColor ? `1px solid ${props.borderColor}` : 'none')}; | ||||
|     &:hover { | ||||
|         background-color: ${props => darken(0.1, props.backgroundColor)}; | ||||
|     } | ||||
|     &:active { | ||||
|         background-color: ${props => darken(0.2, props.backgroundColor)}; | ||||
|     } | ||||
| `; | ||||
|  | ||||
| Button.defaultProps = { | ||||
|     fontSize: '12px', | ||||
|     backgroundColor: colors.white, | ||||
|     width: 'auto', | ||||
| }; | ||||
|  | ||||
| Button.displayName = 'Button'; | ||||
|  | ||||
| type CallToActionType = 'light' | 'dark'; | ||||
|  | ||||
| export interface CallToActionProps { | ||||
|     type?: CallToActionType; | ||||
|     fontSize?: string; | ||||
|     width?: string; | ||||
| } | ||||
|  | ||||
| export const CallToAction: React.StatelessComponent<CallToActionProps> = ({ children, type, fontSize, width }) => { | ||||
|     const isLight = type === 'light'; | ||||
|     const backgroundColor = isLight ? colors.white : colors.heroGrey; | ||||
|     const fontColor = isLight ? colors.heroGrey : colors.white; | ||||
|     const borderColor = isLight ? undefined : colors.white; | ||||
|     return ( | ||||
|         <Button | ||||
|             fontSize={fontSize} | ||||
|             backgroundColor={backgroundColor} | ||||
|             fontColor={fontColor} | ||||
|             width={width} | ||||
|             borderColor={borderColor} | ||||
|         > | ||||
|             {children} | ||||
|         </Button> | ||||
|     ); | ||||
| }; | ||||
|  | ||||
| CallToAction.defaultProps = { | ||||
|     type: 'dark', | ||||
| }; | ||||
| @@ -11,13 +11,20 @@ export interface ContainerProps { | ||||
|     paddingBottom?: StringOrNum; | ||||
|     paddingRight?: StringOrNum; | ||||
|     paddingLeft?: StringOrNum; | ||||
|     backgroundColor?: string; | ||||
|     borderRadius?: StringOrNum; | ||||
|     maxWidth?: StringOrNum; | ||||
|     children?: React.ReactNode; | ||||
|     isHidden?: boolean; | ||||
|     className?: string; | ||||
| } | ||||
|  | ||||
| export const Container: React.StatelessComponent<ContainerProps> = (props: ContainerProps) => { | ||||
|     const { children, ...style } = props; | ||||
|     return <div style={style}>{children}</div>; | ||||
| export const Container: React.StatelessComponent<ContainerProps> = ({ children, className, isHidden, ...style }) => { | ||||
|     const visibility = isHidden ? 'hidden' : undefined; | ||||
|     return ( | ||||
|         <div style={{ ...style, visibility }} className={className}> | ||||
|             {children} | ||||
|         </div> | ||||
|     ); | ||||
| }; | ||||
|  | ||||
| Container.displayName = 'Container'; | ||||
|   | ||||
							
								
								
									
										43
									
								
								packages/website/ts/components/ui/input.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								packages/website/ts/components/ui/input.tsx
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,43 @@ | ||||
| import { colors } from '@0xproject/react-shared'; | ||||
| import * as React from 'react'; | ||||
| import { styled } from 'ts/style/theme'; | ||||
|  | ||||
| export interface InputProps { | ||||
|     className?: string; | ||||
|     value?: string; | ||||
|     width?: string; | ||||
|     fontSize?: string; | ||||
|     fontColor?: string; | ||||
|     placeholderColor?: string; | ||||
|     placeholder?: string; | ||||
|     backgroundColor?: string; | ||||
|     onChange?: (event: React.ChangeEvent<HTMLInputElement>) => void; | ||||
| } | ||||
|  | ||||
| const PlainInput: React.StatelessComponent<InputProps> = ({ value, className, placeholder, onChange }) => ( | ||||
|     <input className={className} value={value} onChange={onChange} placeholder={placeholder} /> | ||||
| ); | ||||
|  | ||||
| export const Input = styled(PlainInput)` | ||||
|     font-size: ${props => props.fontSize}; | ||||
|     width: ${props => props.width}; | ||||
|     padding: 0.8em 1.2em; | ||||
|     border-radius: 3px; | ||||
|     font-family: 'Roboto Mono'; | ||||
|     color: ${props => props.fontColor}; | ||||
|     border: none; | ||||
|     background-color: ${props => props.backgroundColor}; | ||||
|     &::placeholder { | ||||
|         color: ${props => props.placeholderColor}; | ||||
|     } | ||||
| `; | ||||
|  | ||||
| Input.defaultProps = { | ||||
|     width: 'auto', | ||||
|     backgroundColor: colors.white, | ||||
|     fontColor: colors.darkestGrey, | ||||
|     placeholderColor: colors.darkGrey, | ||||
|     fontSize: '12px', | ||||
| }; | ||||
|  | ||||
| Input.displayName = 'Input'; | ||||
| @@ -1,6 +1,6 @@ | ||||
| import * as React from 'react'; | ||||
| import { colors } from 'ts/style/colors'; | ||||
| import { Styleable } from 'ts/types'; | ||||
| import { colors } from 'ts/utils/colors'; | ||||
|  | ||||
| export interface IslandProps { | ||||
|     style?: React.CSSProperties; | ||||
|   | ||||
| @@ -2,7 +2,7 @@ import { colors } from '@0xproject/react-shared'; | ||||
| import * as _ from 'lodash'; | ||||
| import * as React from 'react'; | ||||
|  | ||||
| import { zIndex } from 'ts/utils/style'; | ||||
| import { zIndex } from 'ts/style/z_index'; | ||||
|  | ||||
| export interface OverlayProps { | ||||
|     children?: React.ReactNode; | ||||
|   | ||||
							
								
								
									
										41
									
								
								packages/website/ts/components/ui/text.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								packages/website/ts/components/ui/text.tsx
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,41 @@ | ||||
| import { colors } from '@0xproject/react-shared'; | ||||
| import * as React from 'react'; | ||||
| import { styled } from 'ts/style/theme'; | ||||
| import { Deco, Key } from 'ts/types'; | ||||
| import { Translate } from 'ts/utils/translate'; | ||||
|  | ||||
| export type TextTag = 'p' | 'div' | 'span' | 'label'; | ||||
|  | ||||
| export interface TextProps { | ||||
|     className?: string; | ||||
|     Tag?: TextTag; | ||||
|     fontSize?: string; | ||||
|     fontFamily?: string; | ||||
|     fontColor?: string; | ||||
|     lineHeight?: string; | ||||
|     center?: boolean; | ||||
|     fontWeight?: number; | ||||
| } | ||||
|  | ||||
| const PlainText: React.StatelessComponent<TextProps> = ({ children, className, Tag }) => ( | ||||
|     <Tag className={className}>{children}</Tag> | ||||
| ); | ||||
|  | ||||
| export const Text = styled(PlainText)` | ||||
|     font-family: ${props => props.fontFamily}; | ||||
|     font-weight: ${props => props.fontWeight}; | ||||
|     font-size: ${props => props.fontSize}; | ||||
|     ${props => (props.lineHeight ? `line-height: ${props.lineHeight}` : '')}; | ||||
|     ${props => (props.center ? 'text-align: center' : '')}; | ||||
|     color: ${props => props.fontColor}; | ||||
| `; | ||||
|  | ||||
| Text.defaultProps = { | ||||
|     fontFamily: 'Roboto', | ||||
|     fontWeight: 400, | ||||
|     fontColor: colors.white, | ||||
|     fontSize: '14px', | ||||
|     Tag: 'div', | ||||
| }; | ||||
|  | ||||
| Text.displayName = 'Text'; | ||||
| @@ -32,10 +32,11 @@ import { TokenIcon } from 'ts/components/ui/token_icon'; | ||||
| import { WalletDisconnectedItem } from 'ts/components/wallet/wallet_disconnected_item'; | ||||
| import { WrapEtherItem } from 'ts/components/wallet/wrap_ether_item'; | ||||
| import { Dispatcher } from 'ts/redux/dispatcher'; | ||||
| import { colors } from 'ts/style/colors'; | ||||
| import { zIndex } from 'ts/style/z_index'; | ||||
| import { | ||||
|     BalanceErrs, | ||||
|     BlockchainErrs, | ||||
|     ItemByAddress, | ||||
|     ProviderType, | ||||
|     ScreenWidths, | ||||
|     Side, | ||||
| @@ -45,10 +46,7 @@ import { | ||||
|     TokenStateByAddress, | ||||
|     WebsitePaths, | ||||
| } from 'ts/types'; | ||||
| import { backendClient } from 'ts/utils/backend_client'; | ||||
| import { colors } from 'ts/utils/colors'; | ||||
| import { constants } from 'ts/utils/constants'; | ||||
| import { zIndex } from 'ts/utils/style'; | ||||
| import { utils } from 'ts/utils/utils'; | ||||
| import { styles as walletItemStyles } from 'ts/utils/wallet_item_styles'; | ||||
|  | ||||
| @@ -523,34 +521,6 @@ export class Wallet extends React.Component<WalletProps, WalletState> { | ||||
|         }); | ||||
|         return trackedTokenStateByAddress; | ||||
|     } | ||||
|  | ||||
|     private async _getPriceByAddressAsync(tokenAddresses: string[]): Promise<ItemByAddress<BigNumber>> { | ||||
|         if (_.isEmpty(tokenAddresses)) { | ||||
|             return {}; | ||||
|         } | ||||
|         // for each input token address, search for the corresponding symbol in this.props.tokenByAddress, if it exists | ||||
|         // create a mapping from existing symbols -> address | ||||
|         const tokenAddressBySymbol: { [symbol: string]: string } = {}; | ||||
|         _.each(tokenAddresses, address => { | ||||
|             const tokenIfExists = _.get(this.props.tokenByAddress, address); | ||||
|             if (!_.isUndefined(tokenIfExists)) { | ||||
|                 const symbol = tokenIfExists.symbol; | ||||
|                 tokenAddressBySymbol[symbol] = address; | ||||
|             } | ||||
|         }); | ||||
|         const tokenSymbols = _.keys(tokenAddressBySymbol); | ||||
|         try { | ||||
|             const priceBySymbol = await backendClient.getPriceInfoAsync(tokenSymbols); | ||||
|             const priceByAddress = _.mapKeys(priceBySymbol, (value, symbol) => _.get(tokenAddressBySymbol, symbol)); | ||||
|             const result = _.mapValues(priceByAddress, price => { | ||||
|                 const priceBigNumber = new BigNumber(price); | ||||
|                 return priceBigNumber; | ||||
|             }); | ||||
|             return result; | ||||
|         } catch (err) { | ||||
|             return {}; | ||||
|         } | ||||
|     } | ||||
|     private _openWrappedEtherActionRow(wrappedEtherDirection: Side): void { | ||||
|         this.setState({ | ||||
|             wrappedEtherDirection, | ||||
|   | ||||
| @@ -3,8 +3,8 @@ import FlatButton from 'material-ui/FlatButton'; | ||||
| import ActionAccountBalanceWallet from 'material-ui/svg-icons/action/account-balance-wallet'; | ||||
| import * as React from 'react'; | ||||
|  | ||||
| import { colors } from 'ts/style/colors'; | ||||
| import { ProviderType } from 'ts/types'; | ||||
| import { colors } from 'ts/utils/colors'; | ||||
| import { constants } from 'ts/utils/constants'; | ||||
| import { utils } from 'ts/utils/utils'; | ||||
|  | ||||
|   | ||||
| @@ -10,8 +10,8 @@ import { Blockchain } from 'ts/blockchain'; | ||||
| import { EthAmountInput } from 'ts/components/inputs/eth_amount_input'; | ||||
| import { TokenAmountInput } from 'ts/components/inputs/token_amount_input'; | ||||
| import { Dispatcher } from 'ts/redux/dispatcher'; | ||||
| import { colors } from 'ts/style/colors'; | ||||
| import { BlockchainCallErrs, Side, Token } from 'ts/types'; | ||||
| import { colors } from 'ts/utils/colors'; | ||||
| import { constants } from 'ts/utils/constants'; | ||||
| import { errorReporter } from 'ts/utils/error_reporter'; | ||||
| import { utils } from 'ts/utils/utils'; | ||||
|   | ||||
| @@ -1,11 +1,13 @@ | ||||
| import { colors } from '@0xproject/react-shared'; | ||||
| import * as _ from 'lodash'; | ||||
| import RaisedButton from 'material-ui/RaisedButton'; | ||||
| import * as React from 'react'; | ||||
| import DocumentTitle = require('react-document-title'); | ||||
| import { Link } from 'react-router-dom'; | ||||
| import { Footer } from 'ts/components/footer'; | ||||
| import { SubscribeForm } from 'ts/components/forms/subscribe_form'; | ||||
| import { TopBar } from 'ts/components/top_bar/top_bar'; | ||||
| import { CallToAction } from 'ts/components/ui/button'; | ||||
| import { Container } from 'ts/components/ui/container'; | ||||
| import { Dispatcher } from 'ts/redux/dispatcher'; | ||||
| import { Deco, Key, Language, ScreenWidths, WebsitePaths } from 'ts/types'; | ||||
| import { constants } from 'ts/utils/constants'; | ||||
| @@ -236,7 +238,7 @@ export class Landing extends React.Component<LandingProps, LandingState> { | ||||
|             <div className="clearfix py4" style={{ backgroundColor: colors.heroGrey }}> | ||||
|                 <div className="mx-auto max-width-4 clearfix"> | ||||
|                     {this._renderWhatsNew()} | ||||
|                     <div className="lg-pt4 md-pt4 sm-pt2 lg-pb4 md-pb4 lg-my4 md-my4 sm-mt2 sm-mb4 clearfix"> | ||||
|                     <div className="lg-pt4 md-pt4 sm-pt2 lg-pb4 md-pb4 lg-mt4 md-mt4 sm-mt2 sm-mb4 clearfix"> | ||||
|                         <div className="col lg-col-5 md-col-5 col-12 sm-center"> | ||||
|                             <img src="/images/landing/hero_chip_image.png" height={isSmallScreen ? 300 : 395} /> | ||||
|                         </div> | ||||
| @@ -268,40 +270,31 @@ export class Landing extends React.Component<LandingProps, LandingState> { | ||||
|                                 > | ||||
|                                     {this.props.translate.get(Key.TopTagline)} | ||||
|                                 </div> | ||||
|                                 <div className="pt3 clearfix sm-mx-auto" style={{ maxWidth: 389 }}> | ||||
|                                     <div className="lg-pr2 md-pr2 col col-6 sm-center"> | ||||
|                                 <Container className="pt3 clearfix sm-mx-auto" maxWidth="390px"> | ||||
|                                     <div className="lg-pr2 md-pr2 lg-col lg-col-6 sm-center sm-col sm-col-12 mb2"> | ||||
|                                         <Link to={WebsitePaths.ZeroExJs} className="text-decoration-none"> | ||||
|                                             <RaisedButton | ||||
|                                                 style={{ borderRadius: 6, minWidth: 157.36 }} | ||||
|                                                 buttonStyle={{ borderRadius: 6 }} | ||||
|                                                 labelStyle={buttonLabelStyle} | ||||
|                                                 label={this.props.translate.get(Key.BuildCallToAction, Deco.Cap)} | ||||
|                                                 onClick={_.noop} | ||||
|                                             /> | ||||
|                                             <CallToAction width="175px" type="light"> | ||||
|                                                 {this.props.translate.get(Key.BuildCallToAction, Deco.Cap)} | ||||
|                                             </CallToAction> | ||||
|                                         </Link> | ||||
|                                     </div> | ||||
|                                     <div className="col col-6 sm-center"> | ||||
|                                     <div className="lg-col lg-col-6 sm-center sm-col sm-col-12"> | ||||
|                                         <a | ||||
|                                             href={constants.URL_ZEROEX_CHAT} | ||||
|                                             target="_blank" | ||||
|                                             className="text-decoration-none" | ||||
|                                         > | ||||
|                                             <RaisedButton | ||||
|                                                 style={{ borderRadius: 6, minWidth: 150 }} | ||||
|                                                 buttonStyle={lightButtonStyle} | ||||
|                                                 labelColor="white" | ||||
|                                                 backgroundColor={colors.heroGrey} | ||||
|                                                 labelStyle={buttonLabelStyle} | ||||
|                                                 label={this.props.translate.get(Key.CommunityCallToAction, Deco.Cap)} | ||||
|                                                 onClick={_.noop} | ||||
|                                             /> | ||||
|                                             <CallToAction width="175px"> | ||||
|                                                 {this.props.translate.get(Key.CommunityCallToAction, Deco.Cap)} | ||||
|                                             </CallToAction> | ||||
|                                         </a> | ||||
|                                     </div> | ||||
|                                 </Container> | ||||
|                             </div> | ||||
|                         </div> | ||||
|                     </div> | ||||
|                 </div> | ||||
|                 </div> | ||||
|                 {this.props.translate.getLanguage() === Language.English && <SubscribeForm />} | ||||
|             </div> | ||||
|         ); | ||||
|     } | ||||
| @@ -349,6 +342,9 @@ export class Landing extends React.Component<LandingProps, LandingState> { | ||||
|                 case ScreenWidths.Lg: | ||||
|                     colWidth = isRelayersOnly ? 2 : 2 - i % 2; | ||||
|                     break; | ||||
|  | ||||
|                 default: | ||||
|                     throw new Error(`Encountered unknown ScreenWidths value: ${this.state.screenWidth}`); | ||||
|             } | ||||
|             return ( | ||||
|                 <div key={`project-${project.logoFileName}`} className={`col col-${colWidth} center`}> | ||||
| @@ -782,15 +778,9 @@ export class Landing extends React.Component<LandingProps, LandingState> { | ||||
|                         </div> | ||||
|                         <div className="sm-center sm-pt2 lg-table-cell md-table-cell"> | ||||
|                             <Link to={WebsitePaths.ZeroExJs} className="text-decoration-none"> | ||||
|                                 <RaisedButton | ||||
|                                     style={{ borderRadius: 6, minWidth: 150 }} | ||||
|                                     buttonStyle={lightButtonStyle} | ||||
|                                     labelColor={colors.white} | ||||
|                                     backgroundColor={colors.heroGrey} | ||||
|                                     labelStyle={buttonLabelStyle} | ||||
|                                     label={this.props.translate.get(Key.BuildCallToAction, Deco.Cap)} | ||||
|                                     onClick={_.noop} | ||||
|                                 /> | ||||
|                                 <CallToAction fontSize="15px"> | ||||
|                                     {this.props.translate.get(Key.BuildCallToAction, Deco.Cap)} | ||||
|                                 </CallToAction> | ||||
|                             </Link> | ||||
|                         </div> | ||||
|                     </div> | ||||
|   | ||||
							
								
								
									
										15
									
								
								packages/website/ts/style/theme.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								packages/website/ts/style/theme.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,15 @@ | ||||
| import * as styledComponents from 'styled-components'; | ||||
|  | ||||
| const { | ||||
|     default: styled, | ||||
|     css, | ||||
|     injectGlobal, | ||||
|     keyframes, | ||||
|     ThemeProvider, | ||||
| } = styledComponents as styledComponents.ThemedStyledComponentsModule<IThemeInterface>; | ||||
|  | ||||
| export interface IThemeInterface {} | ||||
|  | ||||
| export const theme = {}; | ||||
|  | ||||
| export { styled, css, injectGlobal, keyframes, ThemeProvider }; | ||||
| @@ -8,6 +8,7 @@ const ETH_GAS_STATION_ENDPOINT = '/eth_gas_station'; | ||||
| const PRICES_ENDPOINT = '/prices'; | ||||
| const RELAYERS_ENDPOINT = '/relayers'; | ||||
| const WIKI_ENDPOINT = '/wiki'; | ||||
| const SUBSCRIBE_SUBSTACK_NEWSLETTER_ENDPOINT = '/newsletter_subscriber/substack'; | ||||
|  | ||||
| export const backendClient = { | ||||
|     async getGasInfoAsync(): Promise<WebsiteBackendGasInfo> { | ||||
| @@ -33,4 +34,11 @@ export const backendClient = { | ||||
|         const result = await fetchUtils.requestAsync(utils.getBackendBaseUrl(), WIKI_ENDPOINT); | ||||
|         return result; | ||||
|     }, | ||||
|     async subscribeToNewsletterAsync(email: string): Promise<Response> { | ||||
|         const result = await fetchUtils.postAsync(utils.getBackendBaseUrl(), SUBSCRIBE_SUBSTACK_NEWSLETTER_ENDPOINT, { | ||||
|             email, | ||||
|             referrer: window.location.href, | ||||
|         }); | ||||
|         return result; | ||||
|     }, | ||||
| }; | ||||
|   | ||||
| @@ -4,22 +4,38 @@ import * as queryString from 'query-string'; | ||||
|  | ||||
| import { errorReporter } from 'ts/utils/error_reporter'; | ||||
|  | ||||
| export const fetchUtils = { | ||||
|     async requestAsync(baseUrl: string, path: string, queryParams?: object): Promise<any> { | ||||
|         const query = queryStringFromQueryParams(queryParams); | ||||
|         const url = `${baseUrl}${path}${query}`; | ||||
|         const response = await fetch(url); | ||||
| const logErrorIfPresent = (response: Response, requestedURL: string) => { | ||||
|     if (response.status !== 200) { | ||||
|             const errorText = `Error requesting url: ${url}, ${response.status}: ${response.statusText}`; | ||||
|         const errorText = `Error requesting url: ${requestedURL}, ${response.status}: ${response.statusText}`; | ||||
|         logUtils.log(errorText); | ||||
|         const error = Error(errorText); | ||||
|         // tslint:disable-next-line:no-floating-promises | ||||
|         errorReporter.reportAsync(error); | ||||
|         throw error; | ||||
|     } | ||||
| }; | ||||
|  | ||||
| export const fetchUtils = { | ||||
|     async requestAsync(baseUrl: string, path: string, queryParams?: object): Promise<any> { | ||||
|         const query = queryStringFromQueryParams(queryParams); | ||||
|         const url = `${baseUrl}${path}${query}`; | ||||
|         const response = await fetch(url); | ||||
|         logErrorIfPresent(response, url); | ||||
|         const result = await response.json(); | ||||
|         return result; | ||||
|     }, | ||||
|     async postAsync(baseUrl: string, path: string, body: object): Promise<Response> { | ||||
|         const url = `${baseUrl}${path}`; | ||||
|         const response = await fetch(url, { | ||||
|             method: 'POST', | ||||
|             headers: { | ||||
|                 'Content-Type': 'application/json', | ||||
|             }, | ||||
|             body: JSON.stringify(body), | ||||
|         }); | ||||
|         logErrorIfPresent(response, url); | ||||
|         return response; | ||||
|     }, | ||||
| }; | ||||
|  | ||||
| function queryStringFromQueryParams(queryParams?: object): string { | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| import { Styles } from '@0xproject/react-shared'; | ||||
|  | ||||
| import { colors } from 'ts/utils/colors'; | ||||
| import { colors } from 'ts/style/colors'; | ||||
|  | ||||
| export const styles: Styles = { | ||||
|     focusedItem: { | ||||
|   | ||||
							
								
								
									
										47
									
								
								yarn.lock
									
									
									
									
									
								
							
							
						
						
									
										47
									
								
								yarn.lock
									
									
									
									
									
								
							| @@ -2044,7 +2044,7 @@ buffer@^4.3.0: | ||||
|     ieee754 "^1.1.4" | ||||
|     isarray "^1.0.0" | ||||
|  | ||||
| buffer@^5.0.5: | ||||
| buffer@^5.0.3, buffer@^5.0.5: | ||||
|   version "5.1.0" | ||||
|   resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.1.0.tgz#c913e43678c7cb7c8bd16afbcddb6c5505e8f9fe" | ||||
|   dependencies: | ||||
| @@ -3061,6 +3061,10 @@ crypto-random-string@^1.0.0: | ||||
|   version "1.0.0" | ||||
|   resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-1.0.0.tgz#a230f64f568310e1498009940790ec99545bca7e" | ||||
|  | ||||
| css-color-keywords@^1.0.0: | ||||
|   version "1.0.0" | ||||
|   resolved "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz#fea2616dc676b2962686b3af8dbdbe180b244e05" | ||||
|  | ||||
| css-color-names@0.0.4: | ||||
|   version "0.0.4" | ||||
|   resolved "https://registry.yarnpkg.com/css-color-names/-/css-color-names-0.0.4.tgz#808adc2e79cf84738069b646cb20ec27beb629e0" | ||||
| @@ -3122,6 +3126,14 @@ css-selector-tokenizer@^0.7.0: | ||||
|     fastparse "^1.1.1" | ||||
|     regexpu-core "^1.0.0" | ||||
|  | ||||
| css-to-react-native@^2.0.3: | ||||
|   version "2.2.0" | ||||
|   resolved "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-2.2.0.tgz#d524ef7f39a2747a8914e86563669ba35b7cf2e7" | ||||
|   dependencies: | ||||
|     css-color-keywords "^1.0.0" | ||||
|     fbjs "^0.8.5" | ||||
|     postcss-value-parser "^3.3.0" | ||||
|  | ||||
| cssesc@^0.1.0: | ||||
|   version "0.1.0" | ||||
|   resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-0.1.0.tgz#c814903e45623371a0477b40109aaafbeeaddbb4" | ||||
| @@ -4491,7 +4503,7 @@ faye-websocket@~0.11.0: | ||||
|   dependencies: | ||||
|     websocket-driver ">=0.5.1" | ||||
|  | ||||
| fbjs@^0.8.0, fbjs@^0.8.1, fbjs@^0.8.16, fbjs@^0.8.4, fbjs@^0.8.6, fbjs@^0.8.9: | ||||
| fbjs@^0.8.0, fbjs@^0.8.1, fbjs@^0.8.16, fbjs@^0.8.4, fbjs@^0.8.5, fbjs@^0.8.6, fbjs@^0.8.9: | ||||
|   version "0.8.16" | ||||
|   resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.16.tgz#5e67432f550dc41b572bf55847b8aca64e5337db" | ||||
|   dependencies: | ||||
| @@ -8721,6 +8733,10 @@ plur@^2.1.2: | ||||
|   dependencies: | ||||
|     irregular-plurals "^1.0.0" | ||||
|  | ||||
| polished@^1.9.2: | ||||
|   version "1.9.2" | ||||
|   resolved "https://registry.npmjs.org/polished/-/polished-1.9.2.tgz#d705cac66f3a3ed1bd38aad863e2c1e269baf6b6" | ||||
|  | ||||
| popper.js@^1.14.1: | ||||
|   version "1.14.3" | ||||
|   resolved "https://registry.yarnpkg.com/popper.js/-/popper.js-1.14.3.tgz#1438f98d046acf7b4d78cd502bf418ac64d4f095" | ||||
| @@ -9557,6 +9573,10 @@ react-highlight@0xproject/react-highlight: | ||||
|     react "^15.5.4" | ||||
|     react-dom "^15.5.4" | ||||
|  | ||||
| react-is@^16.3.1: | ||||
|   version "16.4.0" | ||||
|   resolved "https://registry.npmjs.org/react-is/-/react-is-16.4.0.tgz#cc9fdc855ac34d2e7d9d2eb7059bbc240d35ffcf" | ||||
|  | ||||
| react-markdown@^3.2.2: | ||||
|   version "3.3.0" | ||||
|   resolved "https://registry.yarnpkg.com/react-markdown/-/react-markdown-3.3.0.tgz#a87cdd822aa9302d6add9687961dd1a82a45d02e" | ||||
| @@ -11188,6 +11208,29 @@ style-loader@^0.20.2: | ||||
|     loader-utils "^1.1.0" | ||||
|     schema-utils "^0.4.5" | ||||
|  | ||||
| styled-components@^3.3.0: | ||||
|   version "3.3.0" | ||||
|   resolved "https://registry.npmjs.org/styled-components/-/styled-components-3.3.0.tgz#335b1b2b673b416cd5ec012010e237ed1f877fe9" | ||||
|   dependencies: | ||||
|     buffer "^5.0.3" | ||||
|     css-to-react-native "^2.0.3" | ||||
|     fbjs "^0.8.16" | ||||
|     hoist-non-react-statics "^2.5.0" | ||||
|     is-plain-object "^2.0.1" | ||||
|     prop-types "^15.5.4" | ||||
|     react-is "^16.3.1" | ||||
|     stylis "^3.5.0" | ||||
|     stylis-rule-sheet "^0.0.10" | ||||
|     supports-color "^3.2.3" | ||||
|  | ||||
| stylis-rule-sheet@^0.0.10: | ||||
|   version "0.0.10" | ||||
|   resolved "https://registry.npmjs.org/stylis-rule-sheet/-/stylis-rule-sheet-0.0.10.tgz#44e64a2b076643f4b52e5ff71efc04d8c3c4a430" | ||||
|  | ||||
| stylis@^3.5.0: | ||||
|   version "3.5.0" | ||||
|   resolved "https://registry.npmjs.org/stylis/-/stylis-3.5.0.tgz#016fa239663d77f868fef5b67cf201c4b7c701e1" | ||||
|  | ||||
| supports-color@3.1.2: | ||||
|   version "3.1.2" | ||||
|   resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.1.2.tgz#72a262894d9d408b956ca05ff37b2ed8a6e2a2d5" | ||||
|   | ||||
		Reference in New Issue
	
	Block a user