├── .babelrc
├── .editorconfig
├── .eslintignore
├── .eslintrc
├── .gitignore
├── .stylelintrc
├── .travis.yml
├── README.md
├── browserslist
├── build
├── assets
│ ├── fonts
│ │ ├── font-awesome.woff
│ │ ├── source-sans-pro-extra-light.woff
│ │ ├── source-sans-pro-light.woff
│ │ └── source-sans-pro-regular.woff
│ └── images
│ │ ├── android-chrome-192x192.png
│ │ ├── apple-touch-icon-152x152.png
│ │ ├── apple-touch-icon-180x180.png
│ │ ├── augur-tile-large.png
│ │ ├── augur-tile-medium.png
│ │ ├── augur-tile-small.png
│ │ ├── augur-tile-wide.png
│ │ ├── favicon-16x16.png
│ │ ├── favicon-32x32.png
│ │ └── safari-pinned-tab.svg
├── components.jsx
└── styles.css
├── docs
└── conventions.md
├── firebase.json
├── hooks
└── pre-push.sh
├── lib
└── assertions.js
├── package.json
├── src
├── assertions.js
├── assets
│ ├── fonts
│ │ ├── font-awesome.woff
│ │ ├── source-sans-pro-extra-light.woff
│ │ ├── source-sans-pro-light.woff
│ │ └── source-sans-pro-regular.woff
│ └── images
│ │ ├── android-chrome-192x192.png
│ │ ├── apple-touch-icon-152x152.png
│ │ ├── apple-touch-icon-180x180.png
│ │ ├── augur-tile-large.png
│ │ ├── augur-tile-medium.png
│ │ ├── augur-tile-small.png
│ │ ├── augur-tile-wide.png
│ │ ├── favicon-16x16.png
│ │ ├── favicon-32x32.png
│ │ └── safari-pinned-tab.svg
├── components.jsx
├── index.html
├── index.js
├── modules
│ ├── account
│ │ ├── components
│ │ │ └── account-view.jsx
│ │ └── less
│ │ │ └── account.less
│ ├── app
│ │ ├── components
│ │ │ ├── app.jsx
│ │ │ ├── core-stats.jsx
│ │ │ ├── footer.jsx
│ │ │ ├── header.jsx
│ │ │ ├── nav.jsx
│ │ │ ├── routes.jsx
│ │ │ └── side-bar.jsx
│ │ ├── constants
│ │ │ └── views.js
│ │ └── less
│ │ │ ├── animations.less
│ │ │ ├── app.less
│ │ │ ├── arrangement.less
│ │ │ ├── borders.less
│ │ │ ├── box-shadow.less
│ │ │ ├── colors.less
│ │ │ ├── common.less
│ │ │ ├── core-stats.less
│ │ │ ├── footer.less
│ │ │ ├── header.less
│ │ │ ├── layout.less
│ │ │ ├── nav.less
│ │ │ ├── responsive.less
│ │ │ ├── side-bar.less
│ │ │ ├── tables.less
│ │ │ ├── typography.less
│ │ │ └── view-header.less
│ ├── auth
│ │ ├── components
│ │ │ ├── auth-form.jsx
│ │ │ └── auth-view.jsx
│ │ ├── constants
│ │ │ └── auth-types.js
│ │ └── less
│ │ │ └── auth.less
│ ├── bids-asks
│ │ ├── components
│ │ │ ├── bids-asks.jsx
│ │ │ └── order-book.jsx
│ │ └── less
│ │ │ ├── bids-asks.less
│ │ │ └── order-book.less
│ ├── branch
│ │ ├── components
│ │ │ └── branch.jsx
│ │ └── less
│ │ │ └── branch.less
│ ├── chat
│ │ ├── components
│ │ │ └── chat-view.jsx
│ │ └── less
│ │ │ └── chat.less
│ ├── common
│ │ ├── components
│ │ │ ├── augur-logo-full.jsx
│ │ │ ├── augur-logo-icon.jsx
│ │ │ ├── bullet.jsx
│ │ │ ├── checkbox.jsx
│ │ │ ├── collapse.jsx
│ │ │ ├── component-nav.jsx
│ │ │ ├── datepicker.jsx
│ │ │ ├── dropdown.jsx
│ │ │ ├── em-dash.jsx
│ │ │ ├── input-list.jsx
│ │ │ ├── input.jsx
│ │ │ ├── null-state-message.jsx
│ │ │ ├── side-bar-mask.jsx
│ │ │ ├── tab-navigation.jsx
│ │ │ ├── toggler.jsx
│ │ │ ├── value-date.jsx
│ │ │ ├── value-denomination.jsx
│ │ │ └── value-timestamp.jsx
│ │ └── less
│ │ │ ├── buttons.less
│ │ │ ├── checkbox.less
│ │ │ ├── component-nav.less
│ │ │ ├── datepicker.less
│ │ │ ├── dropdown.less
│ │ │ ├── input.less
│ │ │ ├── null-state-message.less
│ │ │ ├── page.less
│ │ │ ├── panel-sideways.less
│ │ │ ├── side-bar-mask.less
│ │ │ ├── tab-navigation.less
│ │ │ └── value-denomination.less
│ ├── create-market
│ │ ├── components
│ │ │ ├── create-market-form-1.jsx
│ │ │ ├── create-market-form-2-categorical.jsx
│ │ │ ├── create-market-form-2-scalar.jsx
│ │ │ ├── create-market-form-2.jsx
│ │ │ ├── create-market-form-3.jsx
│ │ │ ├── create-market-form-4.jsx
│ │ │ ├── create-market-form-5.jsx
│ │ │ ├── create-market-form-buttons.jsx
│ │ │ ├── create-market-form.jsx
│ │ │ └── create-market-view.jsx
│ │ └── less
│ │ │ └── create-market.less
│ ├── link
│ │ └── components
│ │ │ └── link.jsx
│ ├── login-message
│ │ ├── components
│ │ │ └── login-message-view.jsx
│ │ └── less
│ │ │ └── login-message.less
│ ├── market
│ │ ├── components
│ │ │ ├── market-active.jsx
│ │ │ ├── market-basics.jsx
│ │ │ ├── market-chart.jsx
│ │ │ ├── market-data.jsx
│ │ │ ├── market-details.jsx
│ │ │ ├── market-header.jsx
│ │ │ ├── market-open-orders-group.jsx
│ │ │ ├── market-open-orders-row.jsx
│ │ │ ├── market-open-orders.jsx
│ │ │ ├── market-positions-row.jsx
│ │ │ ├── market-positions.jsx
│ │ │ ├── market-preview-outcomes.jsx
│ │ │ ├── market-preview.jsx
│ │ │ ├── market-properties.jsx
│ │ │ ├── market-reported.jsx
│ │ │ ├── market-reporting.jsx
│ │ │ ├── market-summary.jsx
│ │ │ ├── market-user-data.jsx
│ │ │ └── market-view.jsx
│ │ ├── constants
│ │ │ └── share-denominations.js
│ │ └── less
│ │ │ ├── basics-advanced.less
│ │ │ ├── market-active.less
│ │ │ ├── market-basics.less
│ │ │ ├── market-details.less
│ │ │ ├── market-header.less
│ │ │ ├── market-item.less
│ │ │ ├── market-open-orders-group.less
│ │ │ ├── market-open-orders-row.less
│ │ │ ├── market-open-orders.less
│ │ │ ├── market-positions.less
│ │ │ ├── market-preview-outcomes.less
│ │ │ ├── market-preview.less
│ │ │ ├── market-properties.less
│ │ │ ├── market-user-data.less
│ │ │ └── market.less
│ ├── markets
│ │ ├── components
│ │ │ ├── markets-filter-sort.jsx
│ │ │ ├── markets-headers.jsx
│ │ │ ├── markets-list.jsx
│ │ │ ├── markets-pagination.jsx
│ │ │ ├── markets-search.jsx
│ │ │ ├── markets-tags.jsx
│ │ │ └── markets-view.jsx
│ │ ├── constants
│ │ │ ├── market-types.js
│ │ │ └── markets-headers.js
│ │ └── less
│ │ │ ├── markets-filter-sort.less
│ │ │ ├── markets-pagination.less
│ │ │ └── markets-search.less
│ ├── my-markets
│ │ ├── components
│ │ │ ├── my-market-summary-header.jsx
│ │ │ └── my-market.jsx
│ │ └── less
│ │ │ └── my-markets.less
│ ├── my-positions
│ │ ├── components
│ │ │ ├── my-position.jsx
│ │ │ ├── my-positions-market-overview.jsx
│ │ │ ├── my-positions-summary.jsx
│ │ │ └── my-positions.jsx
│ │ └── less
│ │ │ └── my-positions.less
│ ├── my-reports
│ │ ├── components
│ │ │ └── my-report.jsx
│ │ └── less
│ │ │ └── my-reports.less
│ ├── open-orders
│ │ ├── components
│ │ │ ├── open-order.jsx
│ │ │ └── open-orders-group.jsx
│ │ └── less
│ │ │ └── open-order.less
│ ├── order-book
│ │ ├── components
│ │ │ ├── order-book-header.jsx
│ │ │ ├── order-book-row-side.jsx
│ │ │ ├── order-book-rows.jsx
│ │ │ └── order-book.jsx
│ │ ├── constants
│ │ │ └── order-book-value-types.js
│ │ └── less
│ │ │ ├── order-book-header.less
│ │ │ ├── order-book-row-side.less
│ │ │ ├── order-book-rows.less
│ │ │ └── order-book.less
│ ├── outcomes
│ │ ├── components
│ │ │ ├── outcome-trade-action.jsx
│ │ │ ├── outcome-trade-summary.jsx
│ │ │ ├── outcome-trade.jsx
│ │ │ ├── outcome.jsx
│ │ │ └── outcomes.jsx
│ │ ├── constants
│ │ │ └── trade-types.js
│ │ └── less
│ │ │ ├── outcome-trade-action.less
│ │ │ ├── outcome-trade-summary.less
│ │ │ ├── outcome-trade.less
│ │ │ ├── outcome.less
│ │ │ └── outcomes.less
│ ├── portfolio
│ │ ├── components
│ │ │ ├── markets.jsx
│ │ │ ├── portfolio-view.jsx
│ │ │ ├── positions.jsx
│ │ │ └── reports.jsx
│ │ └── less
│ │ │ └── portfolio-page.less
│ ├── reports
│ │ ├── components
│ │ │ ├── report-form.jsx
│ │ │ └── report-panel.jsx
│ │ └── less
│ │ │ └── report-form.less
│ └── transactions
│ │ ├── components
│ │ ├── transaction.jsx
│ │ ├── transactions-view.jsx
│ │ └── transactions.jsx
│ │ ├── constants
│ │ └── types.js
│ │ └── less
│ │ └── transactions.less
├── selectors.js
├── selectors
│ ├── active-view.js
│ ├── auth-form.js
│ ├── bids-asks
│ │ └── select-bids-asks.js
│ ├── chat.js
│ ├── core-stats.js
│ ├── create-market-form.js
│ ├── filter-sort.js
│ ├── is-transactions-working.js
│ ├── keywords.js
│ ├── links.js
│ ├── login-account-markets.js
│ ├── login-account-positions.js
│ ├── login-account-reports.js
│ ├── login-account.js
│ ├── market-data-age.js
│ ├── market-data-nav-items.js
│ ├── market-data-updater.js
│ ├── market-reporting-nav-items.js
│ ├── market-user-data-nav-items.js
│ ├── market.js
│ ├── markets-header.js
│ ├── markets-totals.js
│ ├── markets.js
│ ├── my-markets-summary.js
│ ├── my-markets.js
│ ├── my-reports-summary.js
│ ├── my-reports.js
│ ├── order-cancellation.js
│ ├── outcome-trade-nav-items.js
│ ├── pagination.js
│ ├── portfolio-nav-items.js
│ ├── portfolio-totals.js
│ ├── portfolio.js
│ ├── positions-markets.js
│ ├── positions-summary.js
│ ├── reportable-outcomes.js
│ ├── scalar-share-denomination.js
│ ├── search.js
│ ├── selected-outcome.js
│ ├── settings.js
│ ├── shares-purchased.js
│ ├── tags.js
│ ├── trade-commit-lock.js
│ ├── transactions-totals.js
│ ├── transactions.js
│ └── url.js
├── styles.less
└── utils
│ ├── add-commas-to-number.js
│ ├── debounce.js
│ ├── empty-number.js
│ ├── get-value.js
│ ├── make-date.js
│ ├── make-number.js
│ ├── random-number.js
│ ├── scroll-top-on-change.js
│ ├── set-share-denomination.js
│ ├── share-denomination-label.js
│ └── should-component-update-pure.js
└── test
├── assertions
├── active-view.js
├── auth-form.js
├── chat.js
├── common
│ ├── component-nav.js
│ ├── formatted-date.js
│ ├── formatted-number.js
│ ├── initial-fair-prices.js
│ ├── link.js
│ ├── market-link.js
│ └── nav-item.js
├── core-stats.js
├── create-market-form.js
├── favorite-markets.js
├── filter-sort.js
├── is-transactions-working.js
├── keywords.js
├── links.js
├── login-account-markets.js
├── login-account-positions.js
├── login-account-reports.js
├── login-account.js
├── market-data-age.js
├── market-data-nav-items.js
├── market-data-updater.js
├── market-reporting-nav-items.js
├── market-user-data-nav-items.js
├── market.js
├── markets-header.js
├── markets-totals.js
├── markets.js
├── my-markets-summary.js
├── my-markets.js
├── my-reports-summary.js
├── my-reports.js
├── order-cancellation.js
├── outcome-trade-nav-items.js
├── pagination.js
├── portfolio-nav-items.js
├── portfolio-summaries.js
├── portfolio-totals.js
├── portfolio.js
├── positions-markets.js
├── positions-summary.js
├── reportable-outcomes.js
├── scalar-share-denomination.js
├── search-sort.js
├── selected-outcome.js
├── selected-user-open-orders-group.js
├── settings.js
├── site-header.js
├── tags.js
├── trade-commit-lock.js
├── transactions-totals.js
├── transactions.js
└── url.js
├── mocha.opts
└── selectors-test.js
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "env": {
3 | "test": {
4 | "presets": ["es2015", "stage-0", "react"]
5 | }
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # AURC Editor Configuration
2 | root = true
3 |
4 | [*]
5 | charset = utf-8
6 | end_of_line = lf
7 | trim_trailing_whitespace = true
8 | insert_final_newline = true
9 | indent_style = tab
10 | tab_width = 2
11 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | .git
2 | build
3 | node_modules
4 | test
5 | scratch
6 | src/styles.less
7 | src/dummy.js
8 |
--------------------------------------------------------------------------------
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "env": {
3 | "browser": true
4 | },
5 | "extends": ["eslint:recommended", "plugin:react/recommended", "airbnb"],
6 | "parser": "babel-eslint",
7 | "parserOptions": {
8 | "ecmaFeatures": {
9 | "jsx": true
10 | }
11 | },
12 | "plugins": [
13 | "react"
14 | ],
15 | "rules": { # 0 = disabled, 1 = warn, 2 = error
16 | # Disabled
17 | "comma-dangle": 0,
18 | "no-eq-null": 0,
19 | "no-console": 0,
20 | "no-tabs": 0,
21 | "consistent-return": 0,
22 | "global-require": 0,
23 | "no-use-before-define": 0,
24 | "max-len": 0,
25 | "no-shadow": 0,
26 | "padded-blocks": 0,
27 | "react/no-string-refs": 0, // NOTE -- Temporarily disabled -- utilization of string refs should be refactored to utilize state
28 | "react/no-unused-prop-types": 0, // NOTE -- Temporarily disabled -- all passed props should be specific, utilized, and verified
29 | "react/forbid-prop-types": 0, // NOTE -- TODO: Temporarily disabled...all props need to be specific + valid + will remove the necessity for separate 'shape' tests once merged into Augur
30 | # Errors
31 | "eqeqeq": [2, "allow-null"],
32 | "indent": [2, "tab", { "SwitchCase": 1 }],
33 | "no-unused-expressions": [2, { "allowShortCircuit": true }],
34 | "no-unused-vars": [2, { "vars": "all", "args": "none" }],
35 | "no-param-reassign": [2, { "props": false }],
36 | "no-underscore-dangle": [2, { "allow": ["_id"] }],
37 | "react/jsx-indent": [2, "tab"],
38 | "react/jsx-indent-props": [2, "tab"],
39 | "no-plusplus": [2, { "allowForLoopAfterthoughts": true }],
40 | "no-useless-rename": 2,
41 | "quotes": [2, "single", { "avoidEscape": true, "allowTemplateLiterals": true}]
42 | },
43 | "settings": {
44 | "import/resolver": {
45 | "node": {
46 | extensions: [
47 | "",
48 | ".js",
49 | ".jsx"
50 | ],
51 | "moduleDirectory": [
52 | "node_modules",
53 | "src" # prevents linting issues w/ aliased paths
54 | ]
55 | }
56 | }
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /demo
2 |
3 | # Logs
4 | logs
5 | *.log
6 | npm-debug.log*
7 |
8 | # Runtime data
9 | pids
10 | *.pid
11 | *.seed
12 |
13 | # Directory for instrumented libs generated by jscoverage/JSCover
14 | lib-cov
15 |
16 | # Coverage directory used by tools like istanbul
17 | coverage
18 |
19 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
20 | .grunt
21 |
22 | # node-waf configuration
23 | .lock-wscript
24 |
25 | # Compiled binary addons (http://nodejs.org/api/addons.html)
26 | build/Release
27 |
28 | # Dependency directory
29 | node_modules
30 |
31 | # Optional npm cache directory
32 | .npm
33 |
34 | # Optional REPL history
35 | .node_repl_history
36 |
37 | # IDEs
38 | .idea
39 | *.iml
--------------------------------------------------------------------------------
/.stylelintrc:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "stylelint-config-standard",
3 | "rules": {
4 | "indentation": "tab",
5 | "color-hex-length": "long",
6 | "declaration-block-properties-order": "alphabetical",
7 | "function-url-quotes": "always",
8 | "property-no-vendor-prefix": true,
9 | "value-no-vendor-prefix": true,
10 | "declaration-block-no-duplicate-properties": true,
11 | "no-duplicate-selectors": true,
12 | "no-browser-hacks": true
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | sudo: false
2 |
3 | language: node_js
4 |
5 | env:
6 | - CXX=g++-4.8
7 |
8 | node_js:
9 | - "6"
10 | - "5"
11 | - "4"
12 |
13 | addons:
14 | apt:
15 | sources:
16 | - ubuntu-toolchain-r-test
17 | packages:
18 | - gcc-4.8
19 | - g++-4.8
20 |
21 | before_script:
22 | - npm install
23 |
24 | script:
25 | - npm run lint
26 | - npm run test
27 | - npm run coverage
28 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # augur-ui-react-components
2 | [](https://travis-ci.org/AugurProject/augur-ui-react-components)
3 | [](https://coveralls.io/github/AugurProject/augur-ui-react-components?branch=master)
4 |
5 | ## Documentation
6 | [Conventions](docs/conventions.md)
7 |
--------------------------------------------------------------------------------
/browserslist:
--------------------------------------------------------------------------------
1 | # Officially Supported Browsers
2 | # NOTE -- referenced by `autoprefixer` during build
3 |
4 | last 2 Chrome versions
5 | last 2 Firefox versions
6 | last 2 Safari versions
7 | last 1 Edge versions
8 | last 2 iOS versions
9 | last 2 Android versions
10 | last 2 ChromeAndroid versions
--------------------------------------------------------------------------------
/build/assets/fonts/font-awesome.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tinybike/augur-ui-react-components/742bdb50af36d36045678a2610d4b68e44638db6/build/assets/fonts/font-awesome.woff
--------------------------------------------------------------------------------
/build/assets/fonts/source-sans-pro-extra-light.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tinybike/augur-ui-react-components/742bdb50af36d36045678a2610d4b68e44638db6/build/assets/fonts/source-sans-pro-extra-light.woff
--------------------------------------------------------------------------------
/build/assets/fonts/source-sans-pro-light.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tinybike/augur-ui-react-components/742bdb50af36d36045678a2610d4b68e44638db6/build/assets/fonts/source-sans-pro-light.woff
--------------------------------------------------------------------------------
/build/assets/fonts/source-sans-pro-regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tinybike/augur-ui-react-components/742bdb50af36d36045678a2610d4b68e44638db6/build/assets/fonts/source-sans-pro-regular.woff
--------------------------------------------------------------------------------
/build/assets/images/android-chrome-192x192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tinybike/augur-ui-react-components/742bdb50af36d36045678a2610d4b68e44638db6/build/assets/images/android-chrome-192x192.png
--------------------------------------------------------------------------------
/build/assets/images/apple-touch-icon-152x152.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tinybike/augur-ui-react-components/742bdb50af36d36045678a2610d4b68e44638db6/build/assets/images/apple-touch-icon-152x152.png
--------------------------------------------------------------------------------
/build/assets/images/apple-touch-icon-180x180.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tinybike/augur-ui-react-components/742bdb50af36d36045678a2610d4b68e44638db6/build/assets/images/apple-touch-icon-180x180.png
--------------------------------------------------------------------------------
/build/assets/images/augur-tile-large.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tinybike/augur-ui-react-components/742bdb50af36d36045678a2610d4b68e44638db6/build/assets/images/augur-tile-large.png
--------------------------------------------------------------------------------
/build/assets/images/augur-tile-medium.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tinybike/augur-ui-react-components/742bdb50af36d36045678a2610d4b68e44638db6/build/assets/images/augur-tile-medium.png
--------------------------------------------------------------------------------
/build/assets/images/augur-tile-small.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tinybike/augur-ui-react-components/742bdb50af36d36045678a2610d4b68e44638db6/build/assets/images/augur-tile-small.png
--------------------------------------------------------------------------------
/build/assets/images/augur-tile-wide.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tinybike/augur-ui-react-components/742bdb50af36d36045678a2610d4b68e44638db6/build/assets/images/augur-tile-wide.png
--------------------------------------------------------------------------------
/build/assets/images/favicon-16x16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tinybike/augur-ui-react-components/742bdb50af36d36045678a2610d4b68e44638db6/build/assets/images/favicon-16x16.png
--------------------------------------------------------------------------------
/build/assets/images/favicon-32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tinybike/augur-ui-react-components/742bdb50af36d36045678a2610d4b68e44638db6/build/assets/images/favicon-32x32.png
--------------------------------------------------------------------------------
/build/assets/images/safari-pinned-tab.svg:
--------------------------------------------------------------------------------
1 |
2 |
4 |
7 |
8 | Created by potrace 1.11, written by Peter Selinger 2001-2013
9 |
10 |
12 |
16 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/firebase.json:
--------------------------------------------------------------------------------
1 | {
2 | "firebase": "augur",
3 | "public": "./demo",
4 | "ignore": [
5 | "firebase.json",
6 | "**/.*",
7 | "**/node_modules/**"
8 | ],
9 | "rewrites": [
10 | {
11 | "source": "**",
12 | "destination": "/index.html"
13 | }
14 | ]
15 | }
16 |
--------------------------------------------------------------------------------
/hooks/pre-push.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | #you can bypass this hook by `git commit --no-verify`
4 |
5 | set -e #exit immediately on `exit status > 0` of any command
6 | set -o pipefail #exit immediately on `exit status > 0` for pipes
7 |
8 | npm run lint --silent
9 | npm run test --silent -- --reporter min
10 |
--------------------------------------------------------------------------------
/src/assets/fonts/font-awesome.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tinybike/augur-ui-react-components/742bdb50af36d36045678a2610d4b68e44638db6/src/assets/fonts/font-awesome.woff
--------------------------------------------------------------------------------
/src/assets/fonts/source-sans-pro-extra-light.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tinybike/augur-ui-react-components/742bdb50af36d36045678a2610d4b68e44638db6/src/assets/fonts/source-sans-pro-extra-light.woff
--------------------------------------------------------------------------------
/src/assets/fonts/source-sans-pro-light.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tinybike/augur-ui-react-components/742bdb50af36d36045678a2610d4b68e44638db6/src/assets/fonts/source-sans-pro-light.woff
--------------------------------------------------------------------------------
/src/assets/fonts/source-sans-pro-regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tinybike/augur-ui-react-components/742bdb50af36d36045678a2610d4b68e44638db6/src/assets/fonts/source-sans-pro-regular.woff
--------------------------------------------------------------------------------
/src/assets/images/android-chrome-192x192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tinybike/augur-ui-react-components/742bdb50af36d36045678a2610d4b68e44638db6/src/assets/images/android-chrome-192x192.png
--------------------------------------------------------------------------------
/src/assets/images/apple-touch-icon-152x152.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tinybike/augur-ui-react-components/742bdb50af36d36045678a2610d4b68e44638db6/src/assets/images/apple-touch-icon-152x152.png
--------------------------------------------------------------------------------
/src/assets/images/apple-touch-icon-180x180.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tinybike/augur-ui-react-components/742bdb50af36d36045678a2610d4b68e44638db6/src/assets/images/apple-touch-icon-180x180.png
--------------------------------------------------------------------------------
/src/assets/images/augur-tile-large.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tinybike/augur-ui-react-components/742bdb50af36d36045678a2610d4b68e44638db6/src/assets/images/augur-tile-large.png
--------------------------------------------------------------------------------
/src/assets/images/augur-tile-medium.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tinybike/augur-ui-react-components/742bdb50af36d36045678a2610d4b68e44638db6/src/assets/images/augur-tile-medium.png
--------------------------------------------------------------------------------
/src/assets/images/augur-tile-small.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tinybike/augur-ui-react-components/742bdb50af36d36045678a2610d4b68e44638db6/src/assets/images/augur-tile-small.png
--------------------------------------------------------------------------------
/src/assets/images/augur-tile-wide.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tinybike/augur-ui-react-components/742bdb50af36d36045678a2610d4b68e44638db6/src/assets/images/augur-tile-wide.png
--------------------------------------------------------------------------------
/src/assets/images/favicon-16x16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tinybike/augur-ui-react-components/742bdb50af36d36045678a2610d4b68e44638db6/src/assets/images/favicon-16x16.png
--------------------------------------------------------------------------------
/src/assets/images/favicon-32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tinybike/augur-ui-react-components/742bdb50af36d36045678a2610d4b68e44638db6/src/assets/images/favicon-32x32.png
--------------------------------------------------------------------------------
/src/assets/images/safari-pinned-tab.svg:
--------------------------------------------------------------------------------
1 |
2 |
4 |
7 |
8 | Created by potrace 1.11, written by Peter Selinger 2001-2013
9 |
10 |
12 |
16 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/src/components.jsx:
--------------------------------------------------------------------------------
1 | import App from 'modules/app/components/app';
2 | import * as VIEWS from 'modules/app/constants/views';
3 | import * as AUTH_TYPES from 'modules/auth/constants/auth-types';
4 | import * as TRANSACTION_TYPES from 'modules/transactions/constants/types';
5 |
6 | const constants = {
7 | VIEWS,
8 | AUTH_TYPES,
9 | TRANSACTION_TYPES
10 | };
11 |
12 | const components = {
13 | App,
14 | constants
15 | };
16 | export default components;
17 |
18 | // also adding this notation to allow for importing specific pieces: import { App } from '...';
19 | export {
20 | App,
21 | constants
22 | };
23 |
--------------------------------------------------------------------------------
/src/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import { App } from './components';
2 | import selectors from './selectors';
3 |
4 | const appElement = document.getElementById('app');
5 |
6 | window.selectors = selectors;
7 | console.log('********************************************* \n DEVELOPMENT MODE \n window.selectors available \n ********************************************* \n');
8 |
9 | selectors.render = () => App(appElement, selectors); // eslint-disable-line new-cap
10 | selectors.render();
11 |
--------------------------------------------------------------------------------
/src/modules/app/components/core-stats.jsx:
--------------------------------------------------------------------------------
1 | import React, { PropTypes } from 'react';
2 | import ValueDenomination from 'modules/common/components/value-denomination';
3 |
4 | const CoreStats = p => (
5 |
6 | {p.coreStats && p.coreStats.map((statGroup, i) => (
7 |
11 | {Object.keys(p.coreStats[i]).map(stat => (
12 |
16 |
20 | {p.coreStats[i][stat].label}:
21 |
22 | {p.coreStats[i][stat].value && p.coreStats[i][stat].value.value ?
23 | :
27 | —
28 | }
29 |
30 |
31 | ))}
32 |
33 | ))}
34 |
35 | );
36 |
37 | CoreStats.propTypes = {
38 | coreStats: PropTypes.array
39 | };
40 |
41 | export default CoreStats;
42 |
--------------------------------------------------------------------------------
/src/modules/app/components/header.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component, PropTypes } from 'react';
2 |
3 | import Nav from 'modules/app/components/nav';
4 |
5 | import debounce from 'utils/debounce';
6 |
7 | export default class Header extends Component {
8 | constructor(props) {
9 | super(props);
10 |
11 | this.state = {
12 | headerHeight: 0
13 | };
14 |
15 | this.setHeaderHeight = debounce(this.setHeaderHeight.bind(this));
16 | }
17 |
18 | componentDidMount() {
19 | this.setHeaderHeight();
20 | window.addEventListener('resize', this.setHeaderHeight);
21 | }
22 |
23 | componentDidUpdate(pP, pS) {
24 | if (pS.headerHeight !== this.state.headerHeight && this.props.updateHeaderHeight) {
25 | this.props.updateHeaderHeight(this.state.headerHeight);
26 | }
27 | }
28 |
29 | setHeaderHeight() {
30 | const headerHeight = this.navRef.offsetHeight;
31 |
32 | this.setState({ headerHeight });
33 | }
34 |
35 | render() {
36 | const p = this.props;
37 |
38 | return (
39 |
40 | { this.navRef = navRef; }}
44 | />
45 |
46 | );
47 | }
48 | }
49 |
50 | Header.propTypes = {
51 | updateHeaderHeight: PropTypes.func
52 | };
53 |
--------------------------------------------------------------------------------
/src/modules/app/components/side-bar.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import Checkbox from 'modules/common/components/checkbox';
4 | import NullStateMessage from 'modules/common/components/null-state-message';
5 |
6 | const SideBar = (p) => {
7 | const nullMessage = 'No Tags Available';
8 |
9 | return (
10 |
32 | );
33 | };
34 |
35 | export default SideBar;
36 |
37 |
38 | // TODO -- Prop Validations
39 | // SideBar.propTypes = {
40 | // filters: React.PropTypes.array
41 | // };
42 |
--------------------------------------------------------------------------------
/src/modules/app/constants/views.js:
--------------------------------------------------------------------------------
1 | // Main Views
2 | export const DEFAULT_PAGE = MARKETS;
3 | export const MARKETS = 'markets';
4 | export const MAKE = 'make';
5 | export const TRANSACTIONS = 'transactions';
6 | export const M = 'm';
7 | export const ACCOUNT = 'account';
8 | export const LOGIN_MESSAGE = 'login-message';
9 |
10 | // Internal Navigation
11 | export const MY_POSITIONS = 'my-positions';
12 | export const MY_MARKETS = 'my-markets';
13 | export const MY_REPORTS = 'my-reports';
14 | export const MARKET_DATA_NAV_OUTCOMES = 'outcomes';
15 | export const MARKET_DATA_ORDERS = 'orders';
16 | export const MARKET_DATA_NAV_CHARTS = 'charts';
17 | export const MARKET_DATA_NAV_DETAILS = 'details';
18 | export const MARKET_USER_DATA_NAV_POSITIONS = 'positions';
19 | export const MARKET_USER_DATA_NAV_OPEN_ORDERS = 'open-orders';
20 | export const MARKET_REPORTING_NAV_REPORT = 'report';
21 | export const MARKET_REPORTING_NAV_DETAILS = 'details';
22 |
--------------------------------------------------------------------------------
/src/modules/app/less/animations.less:
--------------------------------------------------------------------------------
1 | // ANIMATIONS
2 | // shared animations
3 | // all mixins are pre-pended with `animation`
4 | // animations are assumed to be infinitely looped
5 | // appended `-` denotes finite iteration
6 |
7 | // Default Animation Values
8 | @animation-speed-slow: 700ms;
9 | @animation-speed-normal: 500ms;
10 | @animation-speed-fast: 300ms;
11 | @animation-speed-very-fast: 200ms;
12 |
13 | @animation-direction-up: 'up';
14 | @animation-direction-right: 'right';
15 | @animation-direction-down: 'down';
16 | @animation-direction-left: 'left';
17 |
18 | @animation-default-type: ease-in-out;
19 |
20 | // Notifications
21 | .animation-flash-slow(@color) {
22 | .animation(flash-slow @animation-speed-slow @animation-default-type infinite alternate);
23 |
24 | .keyframes(flash-slow, {
25 | 0% { background: fade(@color, @amount-subtle) }
26 | 100% { background: fade(@color, @amount-light) }
27 | });
28 | }
29 |
30 | // Transitions
31 | // Don't pass `all`. Can potentially cause performance issues.
32 | // Instead, pass a comma separated list of property/timing/easing to watch for changes with a `;` at the end
33 | .transition(...) {
34 | transition: @arguments;
35 | }
36 |
37 | // Helpers
38 | .animation(@args) {
39 | animation: @args;
40 | }
41 |
42 | .keyframes(@name; @args) {
43 | @keyframes @name { @args(); }
44 | }
45 |
--------------------------------------------------------------------------------
/src/modules/app/less/app.less:
--------------------------------------------------------------------------------
1 | #main_responsive_state {
2 | @media @breakpoint-mobile {
3 | & {
4 | will-change: contents; // This gets read in app.jsx on mount + reset to auto
5 | }
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/src/modules/app/less/arrangement.less:
--------------------------------------------------------------------------------
1 | // ARRANGEMENT
2 | // styles for the layering of the elements
3 |
4 | // Vars
5 | // these are intended for use with `z-index`
6 | // so will ultimately be applied within the respective stacking context.
7 |
8 | // Above Content
9 | @above-all-content: 1000;
10 |
11 | // Masking
12 | @mask: 2000;
13 | @mask-above: 3000;
14 |
--------------------------------------------------------------------------------
/src/modules/app/less/borders.less:
--------------------------------------------------------------------------------
1 | // BORDERS
2 | // Constants
3 | // Defaults
4 | @border-all: 'all sides';
5 | @border-default-chroma: @border-muted;
6 | @border-default-width: 1px;
7 |
8 | // Sides
9 | @border-top: border-top;
10 | @border-right: border-right;
11 | @border-bottom: border-bottom;
12 | @border-left: border-left;
13 |
14 | // Chroma
15 | @border-muted: @color-border-muted;
16 | @border-light: @color-border-light;
17 |
18 | // Width
19 | @border-width-2: 2px;
20 | @border-width-3: 3px;
21 |
22 | .border(@side: false; @property: @border-all; @chroma: @border-default-chroma; @width: @border-default-width) {
23 | & when (@side) {
24 | & when (@property = @border-all) {
25 | border: @width solid @chroma;
26 | }
27 |
28 | @{property}: @width solid @chroma;
29 | }
30 |
31 | & when not (@side) {
32 | border: none;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/modules/app/less/box-shadow.less:
--------------------------------------------------------------------------------
1 | // TODO -- there are a few occurances of box shadow
2 | // For consistency, need to build up a mixin
3 |
--------------------------------------------------------------------------------
/src/modules/app/less/core-stats.less:
--------------------------------------------------------------------------------
1 | .core-stats {
2 |
3 | .border(true, @border-right);
4 | .border(true, @border-bottom);
5 | .border(true, @border-left);
6 |
7 | background-color: @color-white;
8 | box-shadow: 0 0 5px 1px rgba(0, 0, 0, 0.2);
9 | display: flex;
10 | flex: 1;
11 | flex-wrap: wrap;
12 | justify-content: space-around;
13 |
14 | .core-stats-group {
15 | align-items: center;
16 | display: flex;
17 | flex: 1;
18 | justify-content: center;
19 | margin: 0 1em;
20 |
21 | &:first-child {
22 | justify-content: flex-start;
23 | }
24 |
25 | &:last-child {
26 | justify-content: flex-end;
27 | }
28 |
29 | @media @breakpoint-mobile {
30 | &:first-child,
31 | &:last-child {
32 | justify-content: center;
33 | }
34 | }
35 |
36 | .core-stat {
37 | padding: 1em;
38 |
39 | .core-stat-label {
40 | margin-right: 0.4em;
41 | white-space: nowrap;
42 | }
43 |
44 | .core-stat-value {
45 | .font-weight-normal();
46 | }
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/modules/app/less/footer.less:
--------------------------------------------------------------------------------
1 | footer {
2 |
3 | .border(true, @border-top);
4 | .transition(bottom @animation-speed-very-fast);
5 |
6 | background-color: @color-footer-background;
7 | display: flex;
8 | width: 100vw;
9 | z-index: @mask-above;
10 |
11 | @media @breakpoint-mobile {
12 |
13 | .border(false);
14 |
15 | background-color: transparent;
16 | flex-direction: column;
17 | position: fixed;
18 | }
19 |
20 | .nav-toggler {
21 | align-self: center; // Mobile Safari bugfix
22 | display: none;
23 | flex: 1;
24 | justify-content: center;
25 |
26 | @media @breakpoint-mobile {
27 | display: flex;
28 | }
29 |
30 | .nav-toggler-button {
31 |
32 | .font-color-light();
33 |
34 | background-color: @color-nav-background;
35 | border-radius: 1.75em 1.75em 0 0;
36 | height: 1.75em;
37 | position: relative;
38 | top: 0.3em;
39 | width: 3.5em;
40 |
41 | i {
42 | .font-size-large();
43 | }
44 | }
45 | }
46 |
47 | #footer_content {
48 |
49 | .contained();
50 | .font-size-medium();
51 |
52 | display: flex;
53 | justify-content: center;
54 |
55 | @media @breakpoint-mobile {
56 |
57 | .font-color-light;
58 |
59 | background-color: @color-nav-background;
60 | margin: 0;
61 | }
62 |
63 | .link {
64 | padding: 1.5em;
65 |
66 | &:hover,
67 | &:active,
68 | &:focus {
69 | text-decoration: underline;
70 | }
71 | }
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/src/modules/app/less/header.less:
--------------------------------------------------------------------------------
1 | .app-header {
2 |
3 | .font-size-medium();
4 | .font-weight-extra-light();
5 |
6 | background: @color-nav-background;
7 | color: @color-text-light-muted;
8 | }
9 |
--------------------------------------------------------------------------------
/src/modules/app/less/responsive.less:
--------------------------------------------------------------------------------
1 | // RESPONSIVE
2 | // These are determined largely by the content being displayed NOT the device displaying the content.
3 | // This allows for the most optimal presentation regardless of the device.
4 |
5 | // Maximum app width
6 | // .contained elements will max at this width, elements without that style will flow to full window width
7 | @max-app-width: 1800px;
8 |
9 | // Raw Break Points
10 | // The breakpoints encompass:
11 | // Steps (1, 2, etc.) -- Account for large structural view reflows that may need to occur (Ascending in px)
12 | // Sub-Steps (1-1, 2-1, etc.) -- Account for fine styling adjustments between steps (Descending in px)
13 |
14 | // STEP 1
15 | // Smallest layout @ < 600px
16 | // Step
17 | @step-1: 600px;
18 | // Rules
19 | @breakpoint-1: ~"all and (max-width: @{step-1})";
20 |
21 | // STEP 2
22 | // Medium layout @ > 600px && <= 1200px
23 | // Steps
24 | @step-2: 1200px;
25 | // Sub-Steps
26 | @step-2-1: 1050px;
27 | @step-2-2: 900px; // Mobile tipping point
28 | @step-2-3: 750px;
29 | // Rules
30 | @breakpoint-2: ~"all and (min-width: @{step-1}) and (max-width: @{step-2})";
31 | @breakpoint-2-1: ~"all and (min-width: @{step-1}) and (max-width: @{step-2-1})";
32 | @breakpoint-2-2: ~"all and (min-width: @{step-1}) and (max-width: @{step-2-2})"; // Mobile tipping point
33 | @breakpoint-2-3: ~"all and (min-width: @{step-1}) and (max-width: @{step-2-3})";
34 |
35 | // STEP 3
36 | // Full layout @ > 1200px
37 | // Step
38 | // Explicit declaration of step not necessary here
39 | // Rules
40 | @breakpoint-3: ~"all and (min-width: @{step-2})";
41 |
42 | // Helper Breakpoints
43 | // Mobile (up to step-2-2)
44 | @breakpoint-mobile: ~"all and (max-width: @{step-2-2})";
45 |
--------------------------------------------------------------------------------
/src/modules/app/less/side-bar.less:
--------------------------------------------------------------------------------
1 | // NOTE -- additional styles located in app/less/layout.less
2 | .side-bar {
3 |
4 | .transition(bottom @animation-speed-very-fast);
5 |
6 | background-color: @color-side-bar-background;
7 | color: @color-text-light-muted;
8 | flex: 1;
9 |
10 | @media @breakpoint-mobile {
11 | overflow-y: auto;
12 | position: fixed;
13 | }
14 |
15 | footer {
16 | display: none;
17 |
18 | @media @breakpoint-mobile {
19 | display: flex;
20 | visibility: hidden;
21 | }
22 | }
23 |
24 | h3 {
25 |
26 | .border(true, @border-bottom);
27 | .font-weight-light();
28 | .font-size-medium();
29 |
30 | color: @color-text-light;
31 | margin: 0 2rem;
32 | padding: 1rem 0;
33 | }
34 |
35 | .tags {
36 | display: flex;
37 | flex: 1;
38 | flex-direction: column;
39 | padding: 0.5rem 0;
40 |
41 | .null-state {
42 | align-self: center;
43 | position: fixed; // Simply for the case where tags are failing to load, scrolling won't cause this to go out of view
44 | }
45 |
46 | .checkbox.tag {
47 |
48 | .transition(background-color @animation-speed-very-fast, color @animation-speed-very-fast;);
49 |
50 | padding: 1em 2rem;
51 | text-align: left;
52 |
53 | &:hover,
54 | &.checked {
55 | background-color: @color-side-bar-background-active;
56 | color: @color-text-dark;
57 | }
58 |
59 | .checkbox-box {
60 | display: none;
61 | }
62 | }
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/src/modules/app/less/tables.less:
--------------------------------------------------------------------------------
1 | // TABLES
2 | // Styles + mixins for the display of tables
3 |
4 | .table-cell-spacing {
5 | padding: 0.8em 0;
6 |
7 | @media @breakpoint-mobile {
8 | padding: 1.5em 0;
9 | }
10 | }
11 |
12 | .table {
13 | display: flex;
14 | flex-direction: column;
15 |
16 | .value-denomination,
17 | .value-date {
18 | &,
19 | * {
20 |
21 | .font-weight-extra-light();
22 | }
23 |
24 | &.emphasized {
25 | * {
26 |
27 | .font-weight-normal();
28 | }
29 | }
30 | }
31 | }
32 |
33 | .table-header {
34 | display: flex;
35 | flex: 1;
36 |
37 | .font-weight-normal();
38 |
39 | & > * {
40 |
41 | .table-cell-spacing();
42 | }
43 | }
44 |
45 | .table-row {
46 |
47 | .border(true, @border-top, @border-light);
48 |
49 | display: flex;
50 | flex: 1;
51 |
52 | & > * {
53 |
54 | .table-cell-spacing();
55 |
56 | &:not(:first-child) {
57 | .border(true, @border-left, @border-light);
58 | }
59 | }
60 |
61 | &.selected {
62 |
63 | .border(true, @border-top, @color-blue-light);
64 | .border(true, @border-right, @color-blue-light);
65 | .border(true, @border-bottom, @color-blue-light);
66 | .border(true, @border-left, @color-blue, @border-width-3);
67 |
68 | background-color: @color-blue-extra-light;
69 | }
70 |
71 | &:hover,
72 | &:active {
73 | background-color: @color-blue-extra-light;
74 | }
75 |
76 | &.not-selectable:hover {
77 | background-color: @color-gray-light;
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/src/modules/app/less/view-header.less:
--------------------------------------------------------------------------------
1 | // NOTE -- additional styles located in common/less/layout.less
2 | .view-header {
3 |
4 | .font-size-medium();
5 |
6 | color: @color-text-dark;
7 | display: flex;
8 | flex-wrap: wrap-reverse;
9 |
10 | .view-header-group {
11 | display: flex;
12 | flex: 1;
13 | justify-content: flex-start;
14 | margin: 0 1em 1em 0;
15 | }
16 |
17 | .view-header-group:not(:first-child) {
18 | display: flex;
19 | flex: 1;
20 | justify-content: flex-end;
21 | }
22 |
23 | .view-header-group:last-child {
24 | margin: 0 0 1em;
25 | }
26 |
27 | h2 {
28 |
29 | .font-size-extra-large();
30 | .font-weight-normal();
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/modules/auth/components/auth-view.jsx:
--------------------------------------------------------------------------------
1 | import React, { PropTypes } from 'react';
2 | import classnames from 'classnames';
3 | import AuthForm from 'modules/auth/components/auth-form';
4 | import Link from 'modules/link/components/link';
5 |
6 | class AuthPage extends React.Component {
7 | componentDidMount() {
8 | this.props.authForm.airbitzOnLoad.onLoad();
9 | }
10 |
11 | render() {
12 | const p = this.props;
13 | return (
14 |
15 |
16 | Augur is a completely decentralized system including user accounts.
17 | Your credentials never leave the browser, and you are responsible for keeping them safe.
18 |
19 |
20 |
21 | It is impossible to recover your account if your credentials get lost!
22 |
23 |
24 | Click
25 |
29 | {p.authForm.airbitzLinkText}
30 |
31 | to create an encrypted and backed up account using a simple username and password.
32 |
33 |
34 |
35 | );
36 | }
37 | }
38 |
39 | AuthPage.propTypes = {
40 | className: PropTypes.string,
41 | authForm: PropTypes.object
42 | };
43 |
44 | export default AuthPage;
45 |
--------------------------------------------------------------------------------
/src/modules/auth/constants/auth-types.js:
--------------------------------------------------------------------------------
1 | export const REGISTER = 'register';
2 | export const LOGIN = 'login';
3 | export const LOGOUT = 'logout';
4 | export const IMPORT = 'import';
5 | export const FUND_ACCOUNT = 'fund_account';
6 |
7 | export const AUTH_TYPES = {
8 | [REGISTER]: REGISTER,
9 | [LOGIN]: LOGIN,
10 | [IMPORT]: IMPORT,
11 | [LOGOUT]: LOGOUT
12 | };
13 |
14 | export const DEFAULT_AUTH_TYPE = REGISTER;
15 |
--------------------------------------------------------------------------------
/src/modules/bids-asks/components/bids-asks.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import OrderBook from 'modules/bids-asks/components/order-book';
3 |
4 | const BidsAsks = p => (
5 |
6 | {
7 | p.market.outcomes.map(outcome =>
8 | (
9 |
15 | )
16 | )
17 | }
18 |
19 | );
20 |
21 | // TODO -- Prop Validations
22 | // BidsAsks.propTypes = {
23 | // market: PropTypes.object
24 | // };
25 |
26 | export default BidsAsks;
27 |
--------------------------------------------------------------------------------
/src/modules/bids-asks/components/order-book.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ValueDenomination from 'modules/common/components/value-denomination';
3 |
4 | const OrderBook = p => (
5 |
6 |
7 | {p.bids.map((bid, i) => {
8 | if (i !== 0) {
9 | return (
10 |
11 |
12 |
13 |
14 | );
15 | }
16 | return null;
17 | })}
18 | {!p.bids.length &&
19 |
20 |
21 |
22 |
23 | }
24 |
25 |
26 | {p.asks.map((ask, i) => {
27 | if (i !== 0) {
28 | return (
29 |
30 |
31 |
32 |
33 | );
34 | }
35 | return null;
36 | })}
37 | {!p.asks.length &&
38 |
39 |
40 |
41 |
42 | }
43 |
44 |
45 | );
46 |
47 | // TODO -- Prop Validations
48 | // OrderBook.propTypes = {
49 | // outcome: PropTypes.object,
50 | // bids: PropTypes.array,
51 | // asks: PropTypes.array
52 | // };
53 |
54 | export default OrderBook;
55 |
--------------------------------------------------------------------------------
/src/modules/bids-asks/less/bids-asks.less:
--------------------------------------------------------------------------------
1 | .bids-asks {
2 | display: flex;
3 | flex-wrap: wrap;
4 | font-size: 1.7vmin;
5 | justify-content: center;
6 | padding: 0.5rem 0 3rem;
7 | text-align: center;
8 |
9 | .order-book {
10 | flex: 0 1;
11 |
12 | .order-book();
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/modules/bids-asks/less/order-book.less:
--------------------------------------------------------------------------------
1 | .order-book() {
2 | background: white;
3 | border-radius: 1px;
4 | margin: 0.25rem;
5 | min-width: 400px;
6 |
7 | h5 {
8 | border-bottom: 1px solid @color-border;
9 | font-size: 1.3em;
10 | font-weight: 700;
11 | margin-bottom: 0.5em;
12 | text-align: center;
13 | text-transform: uppercase;
14 |
15 | .name-header {
16 | display: inline-block;
17 | }
18 |
19 | .bids-header {
20 | display: inline-block;
21 | font-size: 0.65em;
22 | font-weight: 400;
23 | padding-right: 2rem;
24 | text-align: right;
25 | }
26 |
27 | .asks-header {
28 | display: inline-block;
29 | font-size: 0.65em;
30 | font-weight: 400;
31 | padding-left: 2rem;
32 | text-align: left;
33 | }
34 | }
35 |
36 | .bids {
37 | border-right: 1px solid @color-border;
38 | display: inline-block;
39 | padding-right: 0.5em;
40 | text-align: right;
41 | vertical-align: top;
42 |
43 | .bid {
44 | .value-denomination.price {
45 | margin-left: 1em;
46 | }
47 | }
48 | }
49 |
50 | .asks {
51 | border-left: 1px solid @color-border;
52 | display: inline-block;
53 | padding-left: 0.5em;
54 | text-align: left;
55 | vertical-align: top;
56 |
57 | .ask {
58 | .value-denomination.price {
59 | margin-right: 1em;
60 | }
61 | }
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/src/modules/branch/components/branch.jsx:
--------------------------------------------------------------------------------
1 | import React, { PropTypes } from 'react';
2 | import ReactTooltip from 'react-tooltip';
3 | import { Line } from 'rc-progress';
4 |
5 | import Bullet from 'modules/common/components/bullet';
6 |
7 | const Branch = p => (
8 |
9 |
14 |
15 | Reporting Cycle {p.reportPeriod} {Math.round(p.currentPeriodProgress)}% complete {p.phaseLabel} phase ends {p.phaseTimeRemaining}
16 |
17 |
23 | {p.description} {p.periodLength / 3600} hours per cycle
24 |
25 |
32 |
33 | Branch ID: {p.id}
34 |
35 |
36 |
37 | );
38 |
39 | Branch.propTypes = {
40 | className: PropTypes.string,
41 | description: PropTypes.string,
42 | id: PropTypes.string,
43 | periodLength: PropTypes.number,
44 | phaseLabel: PropTypes.string,
45 | phaseTimeRemaining: PropTypes.string,
46 | currentPeriodProgress: PropTypes.number
47 | };
48 |
49 | export default Branch;
50 |
--------------------------------------------------------------------------------
/src/modules/branch/less/branch.less:
--------------------------------------------------------------------------------
1 | .branch-info {
2 | display: flex;
3 | flex-direction: column;
4 |
5 | & > *:first-child {
6 | margin-bottom: 0.5em;
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/src/modules/chat/less/chat.less:
--------------------------------------------------------------------------------
1 | .chat {
2 | border-left: 1px solid #c8c8c8;
3 | border-right: 1px solid #c8c8c8;
4 | border-top: 1px solid #c8c8c8;
5 | bottom: 0;
6 | box-shadow: 5px 1px 0 0 rgba(0, 0, 0, 0.2);
7 | left: 0;
8 | position: fixed;
9 | width: 100%;
10 | z-index: 101;
11 | }
12 |
13 | .chat-inputs {
14 | width: 100%;
15 | }
16 |
17 | .chat-message-wrapper {
18 | border: 1px solid #000000;
19 | display: inline-block;
20 | width: 100%;
21 | }
22 |
23 | .close-chat-button {
24 | color: @color-nav-background !important;
25 | cursor: pointer;
26 | float: right;
27 | width: 100%;
28 | }
29 |
30 | .chat-message-input {
31 | border: 0;
32 | width: 80%;
33 | word-break: break-word;
34 | }
35 |
36 | .chat-message-button {
37 | background-color: @color-nav-background;
38 | border: 0;
39 | bottom: 0;
40 | min-width: 80px;
41 | position: fixed;
42 | right: 0;
43 | width: 20%;
44 | }
45 |
46 | // @media screen and (max-width: @media-mobile-width) {
47 | // .chat-message-input {
48 | // width: 100%;
49 | // }
50 | //
51 | // .chat-message-button {
52 | // clear: both;
53 | // position: relative;
54 | // width: 100%;
55 | // }
56 | // }
57 |
58 | #chatbox {
59 | background-color: #f9f9f9;
60 | height: 250px;
61 | overflow: auto;
62 | width: 100%;
63 | word-wrap: break-word;
64 | }
65 |
66 | #babble {
67 | font-family: 'Source Sans Pro', 'Helvetica Neue', Arial, 'Open Sans', sans-serif;
68 | font-size: 11pt;
69 | font-weight: 500;
70 | line-height: 18pt;
71 | padding: 10px;
72 | text-align: left;
73 | }
74 |
75 | #chat-button {
76 | background: @color-nav-background;
77 | border: 0;
78 | border-radius: 5px 5px 0 0;
79 | bottom: 0;
80 | color: #ffffff;
81 | cursor: pointer;
82 | font-size: 14px;
83 | margin: 0;
84 | padding: 10px 20px;
85 | position: fixed;
86 | right: 5%;
87 | visibility: visible !important;
88 | width: auto;
89 | z-index: 100;
90 | }
91 |
92 | #doorbell-button {
93 | left: 5% !important;
94 | }
95 |
--------------------------------------------------------------------------------
/src/modules/common/components/bullet.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | const Bullet = () => · ;
4 |
5 | export default Bullet;
6 |
--------------------------------------------------------------------------------
/src/modules/common/components/checkbox.jsx:
--------------------------------------------------------------------------------
1 | import React, { PropTypes } from 'react';
2 | import ReactTooltip from 'react-tooltip';
3 | import classnames from 'classnames';
4 |
5 | const Checkbox = p => (
6 |
7 |
13 |
14 |
15 | {p.text}
16 |
17 | {p.text2 != null &&
18 |
19 | {p.text2}
20 |
21 | }
22 |
23 |
24 |
25 | );
26 |
27 | Checkbox.propTypes = {
28 | className: PropTypes.string,
29 | title: PropTypes.string,
30 | text: PropTypes.string,
31 | text2: PropTypes.string,
32 | isChecked: PropTypes.bool,
33 | tabIndex: PropTypes.number,
34 | onClick: PropTypes.func
35 | };
36 |
37 | export default Checkbox;
38 |
--------------------------------------------------------------------------------
/src/modules/common/components/collapse.jsx:
--------------------------------------------------------------------------------
1 | // Provides collapsible wrapper (default is div)
2 | import React, { PropTypes } from 'react';
3 | import classnames from 'classnames';
4 |
5 | const Collapse = p => (
6 |
7 | {p.children}
8 |
9 | );
10 |
11 | Collapse.propTypes = {
12 | isOpen: PropTypes.bool,
13 | component: PropTypes.any,
14 | children: PropTypes.any
15 | };
16 |
17 | export default Collapse;
18 |
--------------------------------------------------------------------------------
/src/modules/common/components/component-nav.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import classNames from 'classnames';
3 |
4 | import Link from 'modules/link/components/link';
5 |
6 | const ComponentNav = p => (
7 |
8 | {Object.keys(p.navItems || {}).map(nav => (
9 | { p.updateSelectedNav(nav); }}
13 | >
14 |
15 | {p.navItems[nav].label}
16 |
17 |
18 | ))}
19 |
20 | );
21 |
22 | export default ComponentNav;
23 |
--------------------------------------------------------------------------------
/src/modules/common/components/datepicker.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import Datetime from 'react-datetime';
3 |
4 | const DatePicker = (p) => {
5 | const yesterday = Datetime.moment().subtract(1, 'day');
6 | const valid = current => current.isAfter(yesterday);
7 | const defaultValue = p.endDate ? p.endDate : null;
8 |
9 | return (
10 | p.onValuesUpdated({ endDate: new Date(date) })}
16 | open
17 | inputProps={{ placeholder: 'YYYY/MM/DD hh:mm:ss a' }}
18 | />
19 | );
20 | };
21 |
22 | // TODO -- Prop Validations
23 | // DatePicker.propTypes = {
24 | // onValuesUpdated: PropTypes.func,
25 | // endDate: PropTypes.object
26 | // };
27 |
28 | export default DatePicker;
29 |
--------------------------------------------------------------------------------
/src/modules/common/components/dropdown.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | const Dropdown = p => (
4 |
5 | { p.onChange(event.target.value); }}
7 | defaultValue={p.default}
8 | >
9 | {p.options.map(option => (
10 |
14 | {option.label}
15 |
16 | ))}
17 |
18 |
19 |
20 | );
21 |
22 | // TODO -- Prop Validations
23 | // Dropdown.propTypes = {
24 | // default: PropTypes.string,
25 | // options: PropTypes.array,
26 | // onChange: PropTypes.func
27 | // };
28 |
29 | export default Dropdown;
30 |
--------------------------------------------------------------------------------
/src/modules/common/components/em-dash.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | const EmDash = () => — ;
4 |
5 | export default EmDash;
6 |
--------------------------------------------------------------------------------
/src/modules/common/components/null-state-message.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | const NullStateMessage = p => (
4 |
5 | {!p.message ?
6 | No Data Available :
7 | {p.message}
8 | }
9 |
10 | );
11 |
12 | export default NullStateMessage;
13 |
--------------------------------------------------------------------------------
/src/modules/common/components/side-bar-mask.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | const SidebarMask = p => (
4 |
8 | );
9 |
10 | export default SidebarMask;
11 |
--------------------------------------------------------------------------------
/src/modules/common/components/toggler.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import classnames from 'classnames';
3 |
4 | const Toggler = p => (
5 | {
8 | e.persist();
9 | p.onClick(findNextOption(p.selected, p.options), e);
10 | }}
11 | >
12 | {p.selected.label}
13 |
14 | );
15 |
16 | const findNextOption = (selected, options) => {
17 | const currentSelectedIndex = options.indexOf(selected);
18 | let nextSelectedInex = currentSelectedIndex + 1;
19 | if (nextSelectedInex >= options.length) {
20 | nextSelectedInex = 0;
21 | }
22 | return options[nextSelectedInex];
23 | };
24 |
25 | // TODO -- Prop Validations
26 | // Toggler.propTypes = {
27 | // className: PropTypes.string,
28 | // selected: PropTypes.object,
29 | // options: PropTypes.array,
30 | // onClick: PropTypes.func
31 | // };
32 |
33 | export default Toggler;
34 |
--------------------------------------------------------------------------------
/src/modules/common/components/value-date.jsx:
--------------------------------------------------------------------------------
1 | import React, { PropTypes } from 'react';
2 | import classnames from 'classnames';
3 |
4 | const ValueDate = p => (
5 |
6 | {p.formatted}
7 |
8 | );
9 |
10 | ValueDate.propTypes = {
11 | className: PropTypes.string,
12 | value: PropTypes.object,
13 | formatted: PropTypes.string
14 | };
15 |
16 | export default ValueDate;
17 |
--------------------------------------------------------------------------------
/src/modules/common/components/value-denomination.jsx:
--------------------------------------------------------------------------------
1 | import React, { PropTypes } from 'react';
2 | import ReactTooltip from 'react-tooltip';
3 | import classnames from 'classnames';
4 |
5 | import EmDash from 'modules/common/components/em-dash';
6 |
7 | const ValueDenomination = p => (
8 | 0,
11 | negative: p.formattedValue < 0
12 | })}
13 | >
14 | {p.prefix &&
15 | {p.prefix}
16 | }
17 | {p.formatted && p.fullPrecision &&
18 |
23 | {p.formatted}
24 |
25 | }
26 | {p.formatted && !p.fullPrecision &&
27 | {p.formatted}
28 | }
29 | {p.denomination &&
30 | {p.denomination}
31 | }
32 | {p.postfix &&
33 | {p.postfix}
34 | }
35 | {!p.value && p.value !== 0 && !p.formatted && p.formatted !== '0' && // null/undefined state handler
36 |
37 | }
38 |
39 |
40 | );
41 |
42 | ValueDenomination.propTypes = {
43 | className: PropTypes.string,
44 | value: PropTypes.number,
45 | formattedValue: PropTypes.number,
46 | formatted: PropTypes.string,
47 | fullPrecision: PropTypes.string,
48 | denomination: PropTypes.string,
49 | prefix: PropTypes.string,
50 | postfix: PropTypes.string
51 | };
52 |
53 | export default ValueDenomination;
54 |
--------------------------------------------------------------------------------
/src/modules/common/components/value-timestamp.jsx:
--------------------------------------------------------------------------------
1 | import React, { PropTypes } from 'react';
2 | import classnames from 'classnames';
3 |
4 | const ValueTimestamp = p => (
5 |
6 | {p.full}
7 |
8 | );
9 |
10 | ValueTimestamp.propTypes = {
11 | className: PropTypes.string,
12 | full: PropTypes.string
13 | };
14 |
15 | export default ValueTimestamp;
16 |
--------------------------------------------------------------------------------
/src/modules/common/less/checkbox.less:
--------------------------------------------------------------------------------
1 | .checkbox-container {
2 | display: flex;
3 | flex: 1;
4 | }
5 |
6 | .checkbox {
7 | cursor: default;
8 | flex: 1;
9 |
10 | &:disabled {
11 | opacity: 0.4;
12 | }
13 |
14 | &.checked {
15 | .checkbox-box::before {
16 | color: rgba(45, 45, 75, 1);
17 | content: '\f00c';
18 | font-family: 'Font Awesome';
19 | font-size: 1rem;
20 | font-weight: 500;
21 | left: 0;
22 | position: absolute;
23 | top: -0.2rem;
24 | }
25 | }
26 |
27 | .checkbox-box {
28 |
29 | .border(true);
30 |
31 | background: #fafafa;
32 | display: inline-block;
33 | height: 0.8rem;
34 | margin-right: 0.5rem;
35 | position: relative;
36 | vertical-align: middle;
37 | width: 0.8rem;
38 | }
39 |
40 | .checkbox-label,
41 | .checkbox-label2 {
42 | display: inline-block;
43 | margin-left: 0.25em;
44 | position: relative;
45 | vertical-align: middle;
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/modules/common/less/component-nav.less:
--------------------------------------------------------------------------------
1 | .component-nav {
2 |
3 | .border(true, @border-bottom, @border-muted);
4 |
5 | display: flex;
6 |
7 | .link {
8 | cursor: default;
9 |
10 | &.mobile-only {
11 | display: none;
12 |
13 | @media @breakpoint-mobile {
14 | display: block;
15 | }
16 | }
17 | }
18 |
19 | li {
20 | margin: 0 1em -1px; // -1px pulls bottom `up` one pixel to stylistically overlap w/ component-nav bottom border
21 | padding: 1em 0 0.5em;
22 |
23 | // .transition(border-bottom @animation-speed-very-fast); // Not a great transition in testing...leaving for now
24 |
25 | &.selected {
26 |
27 | .border(true, @border-bottom, @color-purple, @border-width-3);
28 | }
29 |
30 | &:hover:not(.selected) {
31 |
32 | .border(true, @border-bottom, @color-purple, @border-width-2);
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/modules/common/less/dropdown.less:
--------------------------------------------------------------------------------
1 | .dropdown {
2 | background-color: @color-white;
3 | border: 1px solid @color-border;
4 | display: flex;
5 | position: relative;
6 |
7 | select {
8 | appearance: none;
9 | background-color: transparent;
10 | border: none;
11 | padding: 1em 2.2em 1em 1em;
12 | }
13 |
14 | i {
15 |
16 | .font-size-medium();
17 |
18 | cursor: default;
19 | pointer-events: none;
20 | position: absolute;
21 | right: 1em;
22 | top: 50%;
23 | transform: translateY(-50%);
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/modules/common/less/input.less:
--------------------------------------------------------------------------------
1 | .input {
2 | .border(true);
3 |
4 | input {
5 | .border(false);
6 | }
7 |
8 | &.clearable {
9 | .box {
10 | padding-right: 2em;
11 | }
12 | }
13 |
14 | &.input-error {
15 | border-color: @color-red-light;
16 | }
17 |
18 | .box {
19 | font-size: inherit;
20 | height: 100%;
21 | padding: 0.5em;
22 | width: 100%;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/modules/common/less/null-state-message.less:
--------------------------------------------------------------------------------
1 | .null-state-message {
2 |
3 | .font-size-medium();
4 |
5 | display: flex;
6 | flex: 1;
7 | justify-content: center;
8 | padding: 1em;
9 | }
10 |
--------------------------------------------------------------------------------
/src/modules/common/less/page.less:
--------------------------------------------------------------------------------
1 | .page {
2 | display: flex;
3 | flex-direction: column;
4 | min-height: 100vh;
5 | }
6 |
7 | .page-header {
8 | background: @color-dark-hover;
9 | color: white;
10 | font-size: 3.4vmin;
11 | line-height: 2.2em;
12 | //margin-top: @site-header-height;
13 | padding: 3.5vmin 3rem 2.5vmin 2.9rem;
14 |
15 | .big-line {
16 | font-size: 1.3em;
17 | font-weight: 700;
18 | }
19 | }
20 |
21 | .page-content {
22 | color: @color-dark-active;
23 | flex: 1;
24 | padding: 0;
25 | }
26 |
27 | .site-header + .page-content {
28 | //margin-top: @site-header-height;
29 | }
30 |
--------------------------------------------------------------------------------
/src/modules/common/less/panel-sideways.less:
--------------------------------------------------------------------------------
1 | .panel-sideways {
2 | background: fade(@color-plain-normal, 7%);
3 |
4 | .title {
5 | border: 1px solid @color-plain-normal;
6 | border-bottom: 0;
7 | border-left: 7px solid @color-plain-normal;
8 | color: black;
9 | font-size: 1.4rem;
10 | font-weight: 700;
11 | padding: 1.5rem 1rem 1rem;
12 | text-transform: uppercase;
13 | vertical-align: middle;
14 | }
15 |
16 | .content {
17 | border: 1px solid @color-border;
18 | border-left: 7px solid @color-plain-normal;
19 | border-top: 0;
20 | color: @color-dark-normal;
21 | font-size: 1.1rem;
22 | font-weight: 400;
23 | padding: 0.5rem 1rem 0.8rem;
24 | vertical-align: middle;
25 | }
26 |
27 | &.primary {
28 | background: fade(@color-primary-normal, 7%);
29 |
30 | .title,
31 | .content {
32 | border-color: fade(@color-primary-normal, 20%);
33 | border-left-color: @color-primary-normal;
34 | }
35 | }
36 |
37 | &.info {
38 | background: fade(@color-dark-normal, 7%);
39 |
40 | .title,
41 | .content {
42 | border-color: fade(@color-dark-normal, 20%);
43 | border-left-color: @color-dark-normal;
44 | }
45 | }
46 |
47 | &.success {
48 | background: fade(@color-success-normal, 7%);
49 |
50 | .title,
51 | .content {
52 | border-color: fade(@color-success-normal, 20%);
53 | border-left-color: @color-success-normal;
54 | }
55 | }
56 |
57 | &.warning {
58 | background: fade(@color-warning-normal, 7%);
59 |
60 | .title,
61 | .content {
62 | border-color: fade(@color-warning-normal, 20%);
63 | border-left-color: @color-warning-normal;
64 | }
65 | }
66 |
67 | &.danger {
68 | .title,
69 | .content {
70 | border-color: fade(@color-danger-normal, 20%);
71 | border-left-color: @color-danger-normal;
72 | }
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/src/modules/common/less/side-bar-mask.less:
--------------------------------------------------------------------------------
1 | .side-bar-mask {
2 |
3 | .transition(bottom @animation-speed-very-fast);
4 |
5 | background-color: @color-mask-background;
6 | display: none;
7 | left: 0;
8 | position: fixed;
9 | right: 0;
10 | z-index: @mask;
11 |
12 | @media @breakpoint-mobile {
13 | display: block;
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/modules/common/less/tab-navigation.less:
--------------------------------------------------------------------------------
1 | .tab-navigator {
2 | align-items: stretch;
3 | display: flex;
4 | font-size: 2vmin;
5 | width: 100%;
6 |
7 | .nav-item {
8 | align-items: center;
9 | background: white;
10 | border: 1px solid @color-border-dark;
11 | color: black;
12 | display: flex;
13 | flex: 1;
14 | flex-direction: column;
15 | line-height: 2em;
16 |
17 | &:hover,
18 | &:active {
19 | background: @color-light-hover;
20 | }
21 |
22 | &.active {
23 | background: @color-dark-hover;
24 | color: @color-light-normal;
25 | }
26 |
27 | &:not(:last-of-type) {
28 | border-right: none;
29 | }
30 |
31 | .nav-label {
32 | align-items: center;
33 | display: flex;
34 | flex: 5;
35 | font-size: 2.5vmin;
36 | justify-content: center;
37 | }
38 |
39 | .nav-values {
40 | align-items: center;
41 | border-top: 1px solid @color-border;
42 | display: flex;
43 | flex: 2;
44 | font-size: 1.6vmin;
45 | width: 100%;
46 |
47 | .value-denomination {
48 | align-items: center;
49 | border-right: 1px solid @color-border;
50 | display: flex;
51 | flex: 1;
52 | height: 100%;
53 | justify-content: center;
54 |
55 | &:last-of-type {
56 | border-right: none;
57 | padding-right: 0;
58 | }
59 |
60 | &.colorize {
61 | .colorize();
62 | }
63 | }
64 | }
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/src/modules/common/less/value-denomination.less:
--------------------------------------------------------------------------------
1 | .value-denomination {
2 | &.colorize {
3 |
4 | .colorize();
5 | }
6 |
7 | .value {
8 |
9 | .font-weight-normal();
10 | }
11 |
12 | .denomination {
13 |
14 | .font-weight-light();
15 |
16 | margin-left: 0.2em;
17 | }
18 |
19 | .prefix {
20 |
21 | .font-weight-light();
22 |
23 | margin-right: 0.3em;
24 | }
25 |
26 | .postfix {
27 |
28 | .font-weight-light();
29 |
30 | margin-left: 0.3em;
31 | }
32 | }
33 |
34 | .value-date {
35 |
36 | .font-weight-normal();
37 | }
38 |
39 | .value-timestamp {
40 |
41 | .font-weight-light();
42 | }
43 |
--------------------------------------------------------------------------------
/src/modules/create-market/components/create-market-form-1.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { BINARY, CATEGORICAL, SCALAR } from 'modules/markets/constants/market-types';
3 |
4 | const CreateMarketForm1 = p => (
5 |
6 |
Select the type of market you want to create
7 |
8 |
9 |
10 |
A market with a YES or NO outcome
11 |
p.onValuesUpdated({ type: BINARY, step: 2 })}>
12 | Yes / No
13 |
14 |
Ask a question that has a simple YES or NO answer
15 |
16 |
17 |
18 |
A market with a MULTIPLE CHOICE outcome
19 |
p.onValuesUpdated({ type: CATEGORICAL, step: 2 })}>
20 | Multiple Choice
21 |
22 |
Ask a question and provide a set of multiple choice answers
23 |
24 |
25 |
26 |
A market with a NUMERIC outcome
27 |
p.onValuesUpdated({ type: SCALAR, step: 2 })}>
28 | Numeric
29 |
30 |
Ask a question that has an answer within a range of numbers
31 |
32 |
33 |
34 |
35 |
Important:
36 |
37 | There is a 30.00 ETH bond charged to your account when you create a new market. If the
38 | outcome of your market cannot be determined (and the market cannot be expired as a result)
39 | or if your market is ruled unethical, this bond will be forfeited. If your market is expired the
40 | bond will be returned to you in full.
41 |
42 |
43 |
44 | );
45 |
46 | // TODO -- Prop Validations
47 | // CreateMarketForm1.propTypes = {
48 | // onValuesUpdated: PropTypes.func
49 | // };
50 |
51 | export default CreateMarketForm1;
52 |
--------------------------------------------------------------------------------
/src/modules/create-market/components/create-market-form-2-categorical.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import InputList from 'modules/common/components/input-list';
3 |
4 | const CreateMarketForm2Categorical = p => (
5 |
6 |
What are the possible answers to your question? (required)
7 |
8 | {`All possible outcomes to your question must be covered by these answers. You can add an
9 | "any other outcome" type answer at the end to ensure everything is covered.`}
10 |
11 |
p.onValuesUpdated({ categoricalOutcomes: newOutcomes })}
19 | />
20 |
21 | );
22 |
23 | // TOOD -- Prop Validations
24 | // CreateMarketForm2Categorical.propTypes = {
25 | // categoricalOutcomes: PropTypes.array,
26 | // errors: PropTypes.object,
27 | // categoricalOutcomesMinNum: PropTypes.number,
28 | // categoricalOutcomesMaxNum: PropTypes.number,
29 | // categoricalOutcomeMaxLength: PropTypes.number,
30 | // onValuesUpdated: PropTypes.func
31 | // };
32 |
33 | export default CreateMarketForm2Categorical;
34 |
--------------------------------------------------------------------------------
/src/modules/create-market/components/create-market-form-2-scalar.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import Input from 'modules/common/components/input';
3 |
4 | const CreateMarketForm2Scalar = p => (
5 |
6 |
What are the minimum and maximum values allowed when answering?
7 |
8 | The answer to your question must be a number that falls between the minimum and maximum
9 | values you're about to set.
10 |
11 |
12 |
13 |
16 | Minimum
17 |
18 | p.onValuesUpdated({ scalarSmallNum: value })}
25 | />
26 |
27 | {p.errors.scalarSmallNum &&
28 | {p.errors.scalarSmallNum}
29 | }
30 |
31 |
32 |
33 |
36 | Maximum
37 |
38 | p.onValuesUpdated({ scalarBigNum: value })}
45 | />
46 |
47 | {p.errors.scalarBigNum &&
48 | {p.errors.scalarBigNum}
49 | }
50 |
51 |
52 | );
53 |
54 | // TOOD -- Prop Validations
55 | // CreateMarketForm2Scalar.propTypes = {
56 | // scalarSmallNum: PropTypes.string,
57 | // scalarBigNum: PropTypes.string,
58 | // onValuesUpdated: PropTypes.func
59 | // };
60 |
61 | export default CreateMarketForm2Scalar;
62 |
--------------------------------------------------------------------------------
/src/modules/create-market/components/create-market-form-5.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import MarketPreview from 'modules/market/components/market-preview';
3 | import FormButtons from 'modules/create-market/components/create-market-form-buttons';
4 | import ValueDenomination from 'modules/common/components/value-denomination';
5 |
6 | const CreateMarketForm5 = p => (
7 |
8 |
Review and submit your new market
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | p.onValuesUpdated({ step: p.step - 1 })}
20 | />
21 |
22 | );
23 |
24 | // TOOD -- Prop Validations
25 | // CreateMarketForm5.propTypes = {
26 | // marketCreationFee: PropTypes.object,
27 | // gasCost: PropTypes.object,
28 | // eventBond: PropTypes.object,
29 | // onSubmit: PropTypes.func
30 | // };
31 |
32 | export default CreateMarketForm5;
33 |
--------------------------------------------------------------------------------
/src/modules/create-market/components/create-market-form-buttons.jsx:
--------------------------------------------------------------------------------
1 | import React, { PropTypes } from 'react';
2 |
3 | const CreateMarketFormButtons = p => (
4 |
5 |
10 | {p.prevLabel || 'back'}
11 |
12 |
13 |
19 | {p.nextLabel || 'Next'}
20 |
21 |
22 | );
23 |
24 | CreateMarketFormButtons.propTypes = {
25 | disabled: PropTypes.bool,
26 | nextLabel: PropTypes.string,
27 | prevLabel: PropTypes.string,
28 | onPrev: PropTypes.func,
29 | onNext: PropTypes.func
30 | };
31 |
32 | export default CreateMarketFormButtons;
33 |
--------------------------------------------------------------------------------
/src/modules/create-market/components/create-market-form.jsx:
--------------------------------------------------------------------------------
1 | import React, { PropTypes } from 'react';
2 | import Form1 from 'modules/create-market/components/create-market-form-1';
3 | import Form2 from 'modules/create-market/components/create-market-form-2';
4 | import Form3 from 'modules/create-market/components/create-market-form-3';
5 | import Form4 from 'modules/create-market/components/create-market-form-4';
6 | import Form5 from 'modules/create-market/components/create-market-form-5';
7 |
8 | import { SHARE } from 'modules/market/constants/share-denominations';
9 |
10 | import getValue from 'utils/get-value';
11 |
12 | const CreateMarketForm = (p) => {
13 | let form;
14 |
15 | const shareDenominations = getValue(p, 'scalarShareDenomination.denominations');
16 |
17 | switch (p.step) {
18 | case 1:
19 | default:
20 | form = ;
21 | break;
22 | case 2:
23 | form = ;
24 | break;
25 | case 3:
26 | form = ;
27 | break;
28 | case 4:
29 | form = ;
30 | break;
31 | case 5:
32 | form = ( );
37 | break;
38 | }
39 |
40 | return (
41 |
42 | {form}
43 |
44 | );
45 | };
46 |
47 | CreateMarketForm.propTypes = {
48 | className: PropTypes.string,
49 | step: PropTypes.number
50 | };
51 |
52 | export default CreateMarketForm;
53 |
--------------------------------------------------------------------------------
/src/modules/create-market/components/create-market-view.jsx:
--------------------------------------------------------------------------------
1 | import React, { PropTypes } from 'react';
2 | import CreateMarketForm from 'modules/create-market/components/create-market-form';
3 |
4 | const CreateMarketPage = p => (
5 |
6 |
7 | Be the market maker .
8 | Earn fees by making markets for people to trade.
9 | The more people trade your markets, the more fees you will make .
10 |
11 |
12 |
13 |
18 |
19 |
20 | );
21 |
22 | CreateMarketPage.propTypes = {
23 | className: PropTypes.string,
24 | createMarketForm: PropTypes.object
25 | };
26 |
27 | export default CreateMarketPage;
28 |
--------------------------------------------------------------------------------
/src/modules/link/components/link.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component, PropTypes } from 'react';
2 |
3 | export default class Link extends Component {
4 |
5 | // TODO -- Prop Validations
6 | static propTypes = {
7 | // className: PropTypes.string,
8 | href: PropTypes.string,
9 | target: PropTypes.string,
10 | onClick: PropTypes.func,
11 | disabled: PropTypes.bool
12 | };
13 |
14 | constructor(props) {
15 | super(props);
16 | this.handleClick = this.handleClick.bind(this);
17 | }
18 |
19 | handleClick = (e) => {
20 | // if target is set (e.g. to "_blank"), let the browser handle it
21 | if (this.props.target || (this.props.href && this.props.href.indexOf('mailto:') === 0)) {
22 | return;
23 | }
24 | // if not a left click or is a special click, let the browser handle it
25 | if (e.button !== 0 || e.metaKey || e.altKey || e.ctrlKey || e.shiftKey) {
26 | return;
27 | }
28 |
29 | e.preventDefault();
30 | if (this.props.onClick && !this.props.disabled) {
31 | this.props.onClick(this.props.href);
32 | }
33 | };
34 |
35 | render() {
36 | const p = Object.keys(this.props).reduce((prev, key) => { // Strips certain invalid attrs for `a` tag
37 | if (key !== 'text') {
38 | return {
39 | ...prev,
40 | [key]: this.props[key]
41 | };
42 | }
43 | return prev;
44 | }, {});
45 |
46 | return (
47 |
53 | {p.children}
54 |
55 | );
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/src/modules/login-message/less/login-message.less:
--------------------------------------------------------------------------------
1 | #login_message_view {
2 | .page-content {
3 | font-size: 1.4em;
4 |
5 | h1 {
6 | margin: 14px 0 8px;
7 | }
8 |
9 | h2 {
10 | margin: 10px 0 6px;
11 | }
12 |
13 | h3 {
14 | font-size: 1.4rem;
15 | font-weight: 500;
16 | }
17 |
18 | ol {
19 | padding-left: 40px;
20 |
21 | ul {
22 | list-style: disc;
23 | margin: 0.5em 1em;
24 | }
25 | }
26 |
27 | .contained {
28 | padding: 2em;
29 | }
30 |
31 | .link {
32 | color: @color-primary-active;
33 |
34 | &:hover,
35 | &:active,
36 | &:focus {
37 | color: @color-primary-hover;
38 | text-decoration: underline;
39 | }
40 | }
41 |
42 | .lets-do-this-button {
43 | background-color: #43505c;
44 | border: 0;
45 | border-radius: 1px;
46 | color: #ffffff;
47 | display: inline-block;
48 | font-size: 2vmin;
49 | height: 2.8em;
50 | line-height: 2.8em;
51 | margin-top: 1em;
52 | padding: 0 1em;
53 | text-align: center;
54 | text-transform: uppercase;
55 | white-space: nowrap;
56 | }
57 |
58 | .lets-do-this-button:hover {
59 | background-color: @color-dark-hover;
60 | color: #ffffff;
61 | text-decoration: none;
62 | }
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/src/modules/market/components/market-chart.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component, PropTypes } from 'react';
2 | import ReactHighcharts from 'react-highcharts';
3 |
4 | import NullStateMessage from 'modules/common/components/null-state-message';
5 |
6 | export default class MarketChart extends Component {
7 | static propTypes = {
8 | series: PropTypes.array
9 | };
10 |
11 | shouldComponentUpdate(nextProps) {
12 | if (nextProps.series.length === this.props.series.length) return false;
13 |
14 | return true;
15 | }
16 |
17 | render() {
18 | const p = this.props;
19 |
20 | const config = {
21 | title: {
22 | text: ''
23 | },
24 | rangeSelector: { selected: 1 },
25 | xAxis: {
26 | type: 'datetime'
27 | },
28 | yAxis: {
29 | title: {
30 | text: 'price'
31 | },
32 | min: 0,
33 | max: 1
34 | },
35 | legend: {
36 | enabled: true
37 | },
38 | tooltip: {
39 | pointFormat: '{series.name} : {point.y} ',
40 | valueDecimals: 2
41 | },
42 | series: p.series
43 | };
44 |
45 | const nullMessage = 'No Completed Trades';
46 |
47 | return (
48 |
49 | {!p.series || !p.series.length ?
50 | :
51 |
52 | }
53 |
54 | );
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/modules/market/components/market-header.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import Dropdown from 'modules/common/components/dropdown';
4 | import MarketProperties from 'modules/market/components/market-properties';
5 |
6 | import { SCALAR } from 'modules/markets/constants/market-types';
7 |
8 | const MarketDataHeader = p => (
9 |
10 |
11 |
{p.description}
12 |
13 |
14 |
15 | {p.type === SCALAR && p.selectedShareDenomination && !p.isPendingReport &&
16 | { p.updateSelectedShareDenomination(p.id, denomination); }}
20 | />
21 | }
22 |
23 |
24 | );
25 |
26 | export default MarketDataHeader;
27 |
--------------------------------------------------------------------------------
/src/modules/market/components/market-open-orders-group.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import MarketOpenOrdersRow from 'modules/market/components/market-open-orders-row';
4 |
5 | const MarketOpenOrdersGroup = p => (
6 |
7 | {(p.userOpenOrders || []).map((order, i) => (
8 |
22 | ))}
23 |
24 | );
25 |
26 | export default MarketOpenOrdersGroup;
27 |
--------------------------------------------------------------------------------
/src/modules/market/components/market-positions-row.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import ValueDenomination from 'modules/common/components/value-denomination';
4 |
5 | import { SCALAR } from 'modules/markets/constants/market-types';
6 |
7 | import getValue from 'utils/get-value';
8 | import setShareDenomination from 'utils/set-share-denomination';
9 |
10 | const MarketPositionsRow = (p) => {
11 |
12 | const quantityOfShares = setShareDenomination(getValue(p, 'outcome.position.qtyShares.formatted'), p.selectedShareDenomination);
13 |
14 | const outcomeName = getValue(p, 'outcome.name');
15 | const lastPricePercent = getValue(p, 'outcome.lastPricePercent.rounded');
16 | const purchasePrice = getValue(p, 'outcome.position.purchasePrice.formatted');
17 | const lastPrice = getValue(p, 'outcome.lastPrice.formatted');
18 | const realizedNet = getValue(p, 'outcome.position.realizedNet.formatted');
19 | const unrealizedNet = getValue(p, 'outcome.position.unrealizedNet.formatted');
20 | const totalNet = getValue(p, 'outcome.position.totalNet.formatted');
21 |
22 | return (
23 |
24 | {p.marketType === SCALAR ?
25 | :
26 | {outcomeName}
27 | }
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 | );
36 | };
37 |
38 | export default MarketPositionsRow;
39 |
--------------------------------------------------------------------------------
/src/modules/market/components/market-positions.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import MarketPositionsRow from 'modules/market/components/market-positions-row';
4 | import NullStateMessage from 'modules/common/components/null-state-message';
5 |
6 | import { SCALAR } from 'modules/markets/constants/market-types';
7 |
8 | import getValue from 'utils/get-value';
9 |
10 | const MarketPositions = (p) => {
11 | const outcomePositions = getValue(p, 'market.myPositionOutcomes');
12 | const nullMessage = 'No Current Positions';
13 |
14 | return (
15 |
16 | {!outcomePositions ?
17 | :
18 |
19 |
20 | {!p.marketType === SCALAR ? 'Outcomes' : 'Outcome'}
21 | Shares
22 | Avg Price
23 | Last Price
24 | Realized P/L
25 | Unrealized P/L
26 | Total P/L
27 |
28 |
29 | {(outcomePositions || []).map(outcome =>
30 |
36 | )}
37 |
38 |
39 | }
40 |
41 | );
42 | };
43 |
44 | export default MarketPositions;
45 |
--------------------------------------------------------------------------------
/src/modules/market/components/market-preview-outcomes.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ValueDenomination from 'modules/common/components/value-denomination';
3 |
4 | const MarketOutcomes = p => (
5 |
6 | {p.outcomes.map((outcome, i) => (
7 |
11 | {!!outcome.lastPricePercent &&
12 |
18 | }
19 | {outcome.name}
20 |
21 | ))}
22 |
23 | );
24 |
25 | // TODO -- Prop Validations
26 | // MarketOutcomes.propTypes = {
27 | // outcomes: React.PropTypes.array
28 | // };
29 |
30 | export default MarketOutcomes;
31 |
--------------------------------------------------------------------------------
/src/modules/market/components/market-preview.jsx:
--------------------------------------------------------------------------------
1 | import React, { PropTypes } from 'react';
2 | import classnames from 'classnames';
3 |
4 | import MarketBasics from 'modules/market/components/market-basics';
5 | import MarketPreviewOutcomes from 'modules/market/components/market-preview-outcomes';
6 | import Link from 'modules/link/components/link';
7 |
8 | const MarketPreview = p => (
9 |
10 |
11 |
12 |
13 | {!!p.marketLink &&
14 |
15 |
19 | {p.marketLink.text}
20 |
21 |
22 | }
23 |
24 |
25 | {p.outcomes &&
26 |
27 |
28 |
29 | }
30 |
31 | );
32 |
33 | MarketPreview.propTypes = {
34 | className: PropTypes.string,
35 | description: PropTypes.string,
36 | outcomes: PropTypes.array,
37 | isOpen: PropTypes.bool,
38 | isFavorite: PropTypes.bool,
39 | isPendingReport: PropTypes.bool,
40 | endDate: PropTypes.object,
41 | tradingFeePercent: PropTypes.object,
42 | volume: PropTypes.object,
43 | tags: PropTypes.array,
44 | marketLink: PropTypes.object,
45 | onClickToggleFavorite: PropTypes.func
46 | };
47 |
48 | export default MarketPreview;
49 |
--------------------------------------------------------------------------------
/src/modules/market/components/market-reported.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import MarketBasics from 'modules/market/components/market-basics';
4 | import MarketDetails from 'modules/market/components/market-details';
5 |
6 | const MarketReported = p => (
7 |
8 |
20 |
21 | );
22 |
23 | export default MarketReported;
24 |
--------------------------------------------------------------------------------
/src/modules/market/components/market-reporting.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import ReportPanel from 'modules/reports/components/report-panel';
4 |
5 | const MarketReporting = p => (
6 |
7 |
8 |
9 |
10 |
11 | );
12 |
13 | export default MarketReporting;
14 |
--------------------------------------------------------------------------------
/src/modules/market/components/market-summary.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import shouldComponentUpdatePure from 'utils/should-component-update-pure';
3 | import Market from 'modules/my-markets/components/my-market';
4 | import MarketSummaryHeader from 'modules/my-markets/components/my-market-summary-header';
5 |
6 | export default class MarketSummary extends Component {
7 | // TODO -- Prop Validations
8 | // static propTypes = {
9 | // marketSummary: PropTypes.object.isRequired
10 | // };
11 |
12 | constructor(props) {
13 | super(props);
14 | this.shouldComponentUpdate = shouldComponentUpdatePure;
15 | }
16 |
17 | render() {
18 | const p = this.props;
19 |
20 | return (
21 |
27 | );
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/modules/market/components/market-user-data.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 |
3 | import ComponentNav from 'modules/common/components/component-nav';
4 | import MarketPositions from 'modules/market/components/market-positions';
5 | import MarketOpenOrders from 'modules/market/components/market-open-orders';
6 |
7 | import { MARKET_USER_DATA_NAV_POSITIONS, MARKET_USER_DATA_NAV_OPEN_ORDERS } from 'modules/app/constants/views';
8 |
9 | import getValue from 'utils/get-value';
10 |
11 | export default class MarketUserData extends Component {
12 | constructor(props) {
13 | super(props);
14 |
15 | this.state = {
16 | selectedNav: MARKET_USER_DATA_NAV_POSITIONS
17 | };
18 |
19 | this.updateSelectedNav = this.updateSelectedNav.bind(this);
20 | }
21 |
22 | updateSelectedNav(selectedNav) {
23 | this.setState({ selectedNav });
24 | }
25 |
26 | render() {
27 | const p = this.props;
28 | const s = this.state;
29 |
30 | const outcomes = getValue(p, 'market.outcomes');
31 |
32 | return (
33 |
34 | My Trading
35 |
40 | {s.selectedNav === MARKET_USER_DATA_NAV_POSITIONS &&
41 |
46 | }
47 | {s.selectedNav === MARKET_USER_DATA_NAV_OPEN_ORDERS &&
48 |
54 | }
55 |
56 | );
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/src/modules/market/components/market-view.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import MarketActive from 'modules/market/components/market-active';
4 | import MarketReporting from 'modules/market/components/market-reporting';
5 | import MarketReported from 'modules/market/components/market-reported';
6 | import NullStateMessage from 'modules/common/components/null-state-message';
7 |
8 | import getValue from 'utils/get-value';
9 |
10 | const MarketView = (p) => {
11 | const nullMessage = 'No Market Data';
12 |
13 | const isAvailable = getValue(p, 'market.id');
14 | const isOpen = getValue(p, 'market.isOpen');
15 | const isPendingReport = getValue(p, 'market.isPendingReport');
16 |
17 | return (
18 |
19 | {!isAvailable && }
20 | {isAvailable && isOpen && !isPendingReport && }
21 | {isAvailable && isPendingReport && }
22 | {isAvailable && !isOpen && !isPendingReport && }
23 |
24 | );
25 | };
26 |
27 | export default MarketView;
28 |
--------------------------------------------------------------------------------
/src/modules/market/constants/share-denominations.js:
--------------------------------------------------------------------------------
1 | export const SHARE = 'share';
2 | export const MILLI_SHARE = 'milli-share';
3 | export const MICRO_SHARE = 'micro-share';
4 |
--------------------------------------------------------------------------------
/src/modules/market/less/basics-advanced.less:
--------------------------------------------------------------------------------
1 | .basics,
2 | .advanced {
3 | .description {
4 | display: block;
5 | font-size: 3.5vmin;
6 | font-weight: 400;
7 | line-height: 1.3em;
8 | overflow: hidden;
9 | text-overflow: ellipsis;
10 | }
11 |
12 | .properties {
13 | font-size: 1.2rem;
14 | line-height: 1em;
15 | margin: 0.5rem 0 0;
16 |
17 | .property {
18 | display: inline-block;
19 | margin: 0.5rem 2rem 0 0;
20 |
21 | .property-value {
22 | font-weight: 900;
23 | margin-left: 0.5rem;
24 | }
25 | }
26 | }
27 |
28 | .tags {
29 | line-height: 1em;
30 | margin: 0.5rem 0 0;
31 |
32 | .tag {
33 | display: inline-block;
34 | font-size: 1rem;
35 | padding: 0.5em 0;
36 | text-transform: uppercase;
37 |
38 | &:not(:last-child)::after {
39 | content: '>';
40 | display: inline-block;
41 | margin: 0 0.5em;
42 | }
43 |
44 | &.link {
45 | cursor: pointer;
46 |
47 | &:hover,
48 | &:active,
49 | &:focus {
50 | text-decoration: underline;
51 | }
52 | }
53 | }
54 | }
55 | }
56 |
57 | .advanced {
58 | .properties {
59 | margin: 0;
60 |
61 | .property {
62 | vertical-align: top;
63 |
64 | .distinct {
65 | display: block;
66 | margin: 0.5rem 0 0;
67 | }
68 | }
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/src/modules/market/less/market-active.less:
--------------------------------------------------------------------------------
1 | .market-active {
2 | display: flex;
3 | flex: 1;
4 | flex-direction: column;
5 |
6 | @media @breakpoint-mobile {
7 | .market-group:first-child > .order-book {
8 | display: none;
9 | }
10 |
11 | .market-group:last-child .outcome-trade {
12 | display: none;
13 | }
14 |
15 | .market-group {
16 | flex-direction: column;
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/modules/market/less/market-basics.less:
--------------------------------------------------------------------------------
1 | .market-basics {
2 | display: flex;
3 | flex-direction: column;
4 | margin: 0 0 2em;
5 |
6 | .market-basics-header {
7 | display: flex;
8 | flex-direction: row;
9 |
10 | .market-basics-header-group-1 {
11 | flex: 4;
12 |
13 | .tags {
14 | color: @color-blue;
15 | display: flex;
16 | flex: 1;
17 | flex-direction: row;
18 |
19 | .tag {
20 | &:not(:last-of-type)::after {
21 |
22 | .fa();
23 |
24 | content: '';
25 | cursor: default;
26 | padding: 0 0.5em;
27 | }
28 | }
29 | }
30 | }
31 |
32 | .market-basics-header-group-2 {
33 | display: flex;
34 | flex: 1;
35 | justify-content: flex-end;
36 | }
37 | }
38 |
39 | .market-description {
40 |
41 | .font-size-large();
42 | .font-weight-normal();
43 |
44 | padding: 0.4em 0;
45 | }
46 | }
47 |
48 | .market-reported-details {
49 | .market-basics {
50 | margin: 1em 0 2em 1em;
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/modules/market/less/market-details.less:
--------------------------------------------------------------------------------
1 | .market-details {
2 | display: flex;
3 | flex: 1;
4 | flex-direction: column;
5 |
6 | .properties {
7 |
8 | .table();
9 |
10 | .property {
11 |
12 | .table-cell-spacing();
13 |
14 | display: flex;
15 | flex: 1;
16 |
17 | .property-label {
18 |
19 | .font-weight-normal();
20 |
21 | flex: 1;
22 | padding-left: 1em;
23 | }
24 |
25 | .property-value {
26 | flex: 5;
27 | }
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/modules/market/less/market-header.less:
--------------------------------------------------------------------------------
1 | .market-header {
2 | display: flex;
3 | padding: 1em;
4 |
5 | @media @breakpoint-mobile {
6 | background-color: @color-app-background;
7 | padding: 2em 1em;
8 | }
9 |
10 | h3 {
11 | margin: 0 !important;
12 | }
13 |
14 | .market-header-actions {
15 | display: flex;
16 | flex: 1;
17 | justify-content: flex-end;
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/modules/market/less/market-item.less:
--------------------------------------------------------------------------------
1 | .market-item {
2 | background: white;
3 | border-radius: 1px;
4 | margin: 1vmin 0 0 1vmin;
5 | padding: 1.5em 4.9vw 1.5em 2.8rem;
6 |
7 | .basics-container {
8 | display: inline-block;
9 | padding-right: 1em;
10 | vertical-align: middle;
11 | width: 70%;
12 |
13 | .basics {
14 | .description {
15 | color: black;
16 | margin: 0.5rem 2.5vw 0 0;
17 | width: 100%;
18 | }
19 |
20 | .properties {
21 | color: @color-dark-active;
22 | }
23 | }
24 |
25 | .buttons {
26 | margin: 2.5rem 0 1rem;
27 |
28 | .button {
29 | font-size: 1rem;
30 | font-weight: 700;
31 | height: 2.4em;
32 | line-height: 2.3em;
33 | margin: 0 1rem 0 0;
34 | padding: 0 0.75em;
35 | }
36 | }
37 | }
38 |
39 | .outcomes {
40 | display: inline-block;
41 | vertical-align: middle;
42 | width: 30%;
43 |
44 | .outcome {
45 | border-left: 4px solid @color-border-muted;
46 | display: flex;
47 | font-size: 1.3rem;
48 | font-weight: 700;
49 | line-height: 1.4em;
50 | margin-top: 0.1em;
51 | padding: 0.3em;
52 |
53 | .outcome-name {
54 | display: inline-block;
55 | text-align: left;
56 | width: 70%;
57 | }
58 |
59 | .outcome-price {
60 | display: inline-block;
61 | font-weight: 400;
62 | margin-right: 1em;
63 | overflow: hidden;
64 | text-align: right;
65 | text-overflow: ellipsis;
66 | white-space: nowrap;
67 | width: 30%;
68 |
69 | .colorize();
70 | }
71 | }
72 | }
73 |
74 | .favorite-button {
75 | font-size: 1.8rem;
76 | position: absolute;
77 | right: 1.6rem;
78 | top: 1.6rem;
79 |
80 | &.on {
81 | font-size: 2rem;
82 | right: 1rem;
83 | top: 0.7rem;
84 | }
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/src/modules/market/less/market-open-orders-group.less:
--------------------------------------------------------------------------------
1 | .market-open-orders-group {
2 | display: flex;
3 | flex-direction: column;
4 |
5 | &:hover {
6 | .market-open-orders-row {
7 | & > * {
8 | &:first-child {
9 | background-color: @color-gray-light;
10 | }
11 | }
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/modules/market/less/market-open-orders-row.less:
--------------------------------------------------------------------------------
1 | .market-open-orders-row {
2 |
3 | .table-row();
4 |
5 | &:not(.isFirst) {
6 |
7 | .border(false);
8 | }
9 |
10 | &:last-child {
11 | & > * {
12 |
13 | .border(false); // Non-ideal...but the mixin needs some work to accomodate this scenario
14 | .border(true, @border-left, @border-light);
15 | }
16 | }
17 |
18 | & > * {
19 |
20 | .border(true, @border-bottom, @border-light);
21 |
22 | flex: 1;
23 |
24 | &:first-child {
25 |
26 | .border(false);
27 |
28 | flex: 2;
29 | padding-left: 1em;
30 |
31 | .value-denomination span {
32 |
33 | .font-weight-extra-light();
34 | }
35 | }
36 |
37 | &:last-child {
38 | .cancel {
39 | color: @color-red;
40 | }
41 |
42 | .yes {
43 | color: @color-red;
44 | }
45 |
46 | .confirm {
47 | padding: 0 1em;
48 | }
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/src/modules/market/less/market-open-orders.less:
--------------------------------------------------------------------------------
1 | .market-open-orders {
2 | .market-open-orders-header,
3 | .market-open-orders-row {
4 | span:not(:first-child) {
5 | text-align: center;
6 | }
7 | }
8 |
9 | .market-open-orders-header {
10 |
11 | .table-header();
12 |
13 | & > * {
14 | flex: 1;
15 | margin-left: 1em;
16 |
17 | &:first-child {
18 | flex: 2;
19 | }
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/modules/market/less/market-positions.less:
--------------------------------------------------------------------------------
1 | .market-positions {
2 |
3 | .table();
4 |
5 | .market-positions-header {
6 |
7 | .table-header();
8 | }
9 |
10 | .market-positions-row {
11 |
12 | .table-row();
13 | }
14 |
15 | .market-positions-header,
16 | .market-positions-row {
17 | & > * {
18 | &:first-child {
19 | flex: 3;
20 | margin-left: 1em;
21 | }
22 |
23 | flex: 1;
24 | }
25 |
26 | span:not(:first-child) {
27 | text-align: center;
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/modules/market/less/market-preview-outcomes.less:
--------------------------------------------------------------------------------
1 | .market-preview-outcomes {
2 | display: flex;
3 | flex: 1;
4 | flex-direction: column;
5 |
6 | .outcome {
7 |
8 | .font-weight-normal();
9 |
10 | display: flex;
11 | padding: 0.2em;
12 |
13 | .outcome-price {
14 | display: flex;
15 | flex: 1;
16 | justify-content: flex-end;
17 |
18 | .value:only-child {
19 | margin-right: @font-size-normal;
20 | }
21 | }
22 |
23 | .outcome-name {
24 | flex: 3;
25 | padding-left: 0.5em;
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/modules/market/less/market-preview.less:
--------------------------------------------------------------------------------
1 | .market-preview {
2 |
3 | .border(true);
4 |
5 | background-color: @color-white;
6 | display: flex;
7 | flex: 1;
8 | margin: 2em 0;
9 | padding: 2em;
10 |
11 | .market-preview-group-1 {
12 | display: flex;
13 | flex: 4;
14 | flex-direction: column;
15 | padding-right: 2em;
16 |
17 | .market-link {
18 | display: flex;
19 |
20 | .button.trade {
21 | cursor: pointer;
22 | }
23 | }
24 | }
25 |
26 | .market-preview-group-2 {
27 |
28 | .border(true, @border-left);
29 |
30 | display: flex;
31 | flex: 1;
32 | padding-left: 2em;
33 |
34 | .outcome .outcome-price {
35 | color: @color-blue;
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/modules/market/less/market-properties.less:
--------------------------------------------------------------------------------
1 | .market-properties {
2 | display: flex;
3 | flex-wrap: wrap;
4 |
5 | .property {
6 | .property-value {
7 | margin-left: 0.3em;
8 | }
9 |
10 | &:not(:last-of-type)::after {
11 | content: '•';
12 | padding: 0 0.5em;
13 | }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/modules/market/less/market-user-data.less:
--------------------------------------------------------------------------------
1 | .market-group .market-user-data {
2 | h3 {
3 | @media @breakpoint-mobile {
4 | background-color: @color-app-background;
5 | margin: 0;
6 | padding: 2em 1em;
7 | }
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/src/modules/market/less/market.less:
--------------------------------------------------------------------------------
1 | #market_view {
2 | margin: 0;
3 | }
4 |
5 | .market-group {
6 | display: flex;
7 | flex: 1;
8 |
9 | & > article {
10 |
11 | .border(true);
12 |
13 | background-color: @color-white;
14 | display: flex;
15 | flex-direction: column;
16 |
17 | // Not the most ideal implementation, but we'd need to do a refactor of the overall layout to accomodate something like a flexed row height that doesn't exceed the window height
18 | .market-content-scrollable {
19 | max-height: 30rem;
20 | overflow-y: scroll;
21 | }
22 |
23 | h3 {
24 | margin-left: 1em;
25 | }
26 |
27 | &:first-child {
28 | flex: 3;
29 | margin: 1rem 0.5rem 0.5rem 1rem;
30 |
31 | @media @breakpoint-mobile {
32 | margin: 0;
33 | }
34 |
35 | & + article {
36 | flex: 1;
37 | margin: 1rem 1rem 0.5rem 0.5rem;
38 | }
39 | }
40 | }
41 |
42 | &:last-child {
43 | & > article {
44 | &:first-child {
45 | margin: 0.5rem 0.5rem 0.5rem 1rem;
46 |
47 | @media @breakpoint-mobile {
48 |
49 | .border(false);
50 |
51 | margin: 0;
52 | }
53 |
54 | & + article {
55 | margin: 0.5rem 1rem 0.5rem 0.5rem;
56 | }
57 | }
58 | }
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/src/modules/markets/components/markets-filter-sort.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import Dropdown from 'modules/common/components/dropdown';
4 | import MarketsSearch from 'modules/markets/components/markets-search';
5 |
6 | const MarketsFilterSort = p => (
7 |
8 |
9 |
{ p.onChange(type, null, null); }}
13 |
14 | />
15 |
16 | { p.onChange(null, sort, null); }}
21 | />
22 | { p.onChange(null, null, !p.selectedFilterSort.isDesc); }}
25 | >
26 |
27 | {p.selectedFilterSort.isDesc ? '' : ''}
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 | );
37 |
38 |
39 | // TODO -- Prop Validations
40 | // MarketsFilterSort.propTypes = {
41 | // className: PropTypes.string,
42 | // selectedFilterSort: PropTypes.object,
43 | // sorts: PropTypes.array,
44 | // types: PropTypes.array,
45 | // order: PropTypes.object,
46 | // onChange: PropTypes.func,
47 | // keywords: PropTypes.object
48 | // };
49 |
50 | export default MarketsFilterSort;
51 |
--------------------------------------------------------------------------------
/src/modules/markets/components/markets-headers.jsx:
--------------------------------------------------------------------------------
1 | import React, { PropTypes } from 'react';
2 | import MarketsFilterSort from 'modules/markets/components/markets-filter-sort';
3 | import Link from 'modules/link/components/link';
4 |
5 | const MarketsHeaders = p => (
6 |
7 |
8 |
9 |
Markets
10 |
11 |
12 | {p.loginAccount && p.loginAccount.address &&
13 |
18 | + Create New Market
19 |
20 | }
21 |
22 |
23 |
27 |
28 | );
29 |
30 | MarketsHeaders.propTypes = {
31 | className: PropTypes.string,
32 | createMarketLink: PropTypes.object,
33 | loginAccount: PropTypes.object,
34 | marketsHeader: PropTypes.object,
35 | filterSort: PropTypes.object,
36 | keywords: PropTypes.object
37 | };
38 |
39 | export default MarketsHeaders;
40 |
--------------------------------------------------------------------------------
/src/modules/markets/components/markets-list.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import MarketPreview from 'modules/market/components/market-preview';
3 | import MarketsPagination from 'modules/markets/components/markets-pagination';
4 |
5 | import getValue from 'utils/get-value';
6 |
7 | const MarketsList = p => (
8 |
9 | {(p.markets || []).map((market) => {
10 | const selectedShareDenomination = getValue(p, `scalarShareDenomination.markets.${market.id}`);
11 | const shareDenominations = getValue(p, 'scalarShareDenomination.denominations');
12 |
13 | return (
14 |
21 | );
22 | })}
23 | {!!p.pagination && !!p.pagination.numUnpaginated &&
24 |
25 | }
26 |
27 | );
28 |
29 | // TODO -- Prop Validations
30 | // MarketsList.propTypes = {
31 | // markets: PropTypes.array,
32 | // pagination: PropTypes.object
33 | // };
34 |
35 | export default MarketsList;
36 |
--------------------------------------------------------------------------------
/src/modules/markets/components/markets-pagination.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import Link from 'modules/link/components/link';
3 |
4 | const MarketsPagination = p => (
5 |
6 |
7 | {!!p.pagination && !!p.pagination.previousPageNum &&
8 |
12 |
13 |
14 | }
15 |
16 |
17 |
18 | {`${p.pagination.startItemNum} - ${p.pagination.endItemNum}`} of {p.pagination.numUnpaginated}
19 |
20 |
21 |
22 | {!!p.pagination && !!p.pagination.nextPageNum &&
23 |
27 |
28 |
29 | }
30 |
31 |
32 | );
33 |
34 | export default MarketsPagination;
35 |
--------------------------------------------------------------------------------
/src/modules/markets/components/markets-search.jsx:
--------------------------------------------------------------------------------
1 | import React, { PropTypes } from 'react';
2 | import Input from 'modules/common/components/input';
3 |
4 | const MarketsSearch = p => (
5 |
6 |
7 |
13 |
14 | );
15 |
16 | MarketsSearch.propTypes = {
17 | className: PropTypes.string,
18 | keywords: PropTypes.object
19 | };
20 |
21 | export default MarketsSearch;
22 |
--------------------------------------------------------------------------------
/src/modules/markets/components/markets-tags.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import Checkbox from 'modules/common/components/checkbox';
3 |
4 | const Filters = p => (
5 |
6 | {p.filters.map(filter =>
7 |
8 | {filter.title}
9 | {filter.options.map(option =>
10 |
11 | )}
12 |
13 | )}
14 |
15 | );
16 |
17 | // TOOD -- Prop Validations
18 | // Filters.propTypes = {
19 | // filters: PropTypes.array
20 | // };
21 |
22 | export default Filters;
23 |
--------------------------------------------------------------------------------
/src/modules/markets/components/markets-view.jsx:
--------------------------------------------------------------------------------
1 | import React, { PropTypes } from 'react';
2 |
3 | import MarketsHeaders from 'modules/markets/components/markets-headers';
4 | import MarketsList from 'modules/markets/components/markets-list';
5 | import Branch from 'modules/branch/components/branch';
6 |
7 | const MarketsView = p => (
8 |
9 | {!!p.loginAccount.rep && !!p.loginAccount.rep.value &&
10 |
11 | }
12 |
19 |
25 |
26 | );
27 |
28 | MarketsView.propTypes = {
29 | className: PropTypes.string,
30 | filterSort: PropTypes.object,
31 | marketsHeader: PropTypes.object,
32 | markets: PropTypes.array,
33 | pagination: PropTypes.object,
34 | keywords: PropTypes.object,
35 | branch: PropTypes.object
36 | };
37 |
38 | export default MarketsView;
39 |
--------------------------------------------------------------------------------
/src/modules/markets/constants/market-types.js:
--------------------------------------------------------------------------------
1 | export const BINARY = 'binary';
2 | export const CATEGORICAL = 'categorical';
3 | export const SCALAR = 'scalar';
4 |
5 | export const MARKET_TYPES = {
6 | [BINARY]: BINARY,
7 | [CATEGORICAL]: CATEGORICAL,
8 | [SCALAR]: SCALAR
9 | };
10 |
11 |
--------------------------------------------------------------------------------
/src/modules/markets/constants/markets-headers.js:
--------------------------------------------------------------------------------
1 | export const FAVORITES = 'favorites';
2 | export const PENDING_REPORTS = 'pending reports';
3 |
--------------------------------------------------------------------------------
/src/modules/markets/less/markets-filter-sort.less:
--------------------------------------------------------------------------------
1 | .markets-filter-sort {
2 | .dropdown {
3 | &:not(:last-of-type) {
4 | margin-right: 1em;
5 | }
6 | }
7 |
8 | .companion-fields {
9 | display: flex;
10 |
11 | & > button {
12 | align-items: center;
13 | background-color: @color-white;
14 | border-bottom: 1px solid @color-border;
15 | border-right: 1px solid @color-border;
16 | border-top: 1px solid @color-border;
17 | cursor: default;
18 | display: flex;
19 | padding: 0 1em;
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/modules/markets/less/markets-pagination.less:
--------------------------------------------------------------------------------
1 | .markets-pagination {
2 |
3 | .font-size-large();
4 |
5 | align-items: center;
6 | display: flex;
7 | flex: 1;
8 | justify-content: space-around;
9 |
10 | & > div {
11 | flex: 1;
12 | }
13 |
14 | .markets-pagination-group-1 {
15 | margin-left: -1.5em; // Derived from the default padding applied to buttons
16 | }
17 |
18 | .markets-pagination-group-2 {
19 | display: flex;
20 | justify-content: center;
21 | }
22 |
23 | .markets-pagination-group-3 {
24 | display: flex;
25 | justify-content: flex-end;
26 | margin-right: -1.5em; // Derived from the default padding applied to buttons
27 | }
28 |
29 | .button {
30 |
31 | .font-size-extra-large();
32 |
33 | background-color: @color-transparent;
34 | color: @color-text-dark;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/modules/markets/less/markets-search.less:
--------------------------------------------------------------------------------
1 | .search-input {
2 |
3 | .border(true);
4 |
5 | align-items: center;
6 | background-color: @color-white;
7 | display: flex;
8 | flex: 1;
9 | min-width: 22em;
10 | padding-left: 1em;
11 |
12 | .input {
13 |
14 | .border(false);
15 |
16 | display: flex;
17 | flex: 1;
18 |
19 | input {
20 |
21 | .border(false);
22 | }
23 | }
24 |
25 | input.box {
26 |
27 | .border();
28 |
29 | background-color: @color-transparent;
30 | padding: 1em;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/modules/my-markets/components/my-market-summary-header.jsx:
--------------------------------------------------------------------------------
1 | import React, { PropTypes } from 'react';
2 | import ValueDenomination from 'modules/common/components/value-denomination';
3 |
4 | const MyMarketsSummary = p => (
5 |
6 | My Markets
7 | {!!p.fees &&
8 |
9 | }
10 |
11 | );
12 |
13 | MyMarketsSummary.propTypes = {
14 | className: PropTypes.string.isRequired,
15 | fees: PropTypes.object.isRequired
16 | };
17 |
18 | export default MyMarketsSummary;
19 |
--------------------------------------------------------------------------------
/src/modules/my-markets/components/my-market.jsx:
--------------------------------------------------------------------------------
1 | import React, { PropTypes } from 'react';
2 | import ValueDenomination from 'modules/common/components/value-denomination';
3 | import ValueDate from 'modules/common/components/value-date';
4 |
5 | const Market = p => (
6 |
7 |
8 | ends:
9 |
10 |
11 |
12 |
13 | fees collected
14 |
18 |
19 |
20 | open volume
21 |
22 |
23 |
24 | volume
25 |
26 |
27 |
28 | # of trades
29 |
30 |
31 |
32 | avg trade size
33 |
34 |
35 |
36 |
37 | );
38 |
39 | Market.propTypes = {
40 | endDate: PropTypes.object.isRequired,
41 | openVolume: PropTypes.object.isRequired,
42 | volume: PropTypes.object.isRequired,
43 | numberOfTrades: PropTypes.object.isRequired,
44 | averageTradeSize: PropTypes.object.isRequired,
45 | fees: PropTypes.object.isRequired
46 | };
47 |
48 | export default Market;
49 |
--------------------------------------------------------------------------------
/src/modules/my-markets/less/my-markets.less:
--------------------------------------------------------------------------------
1 | .portfolio-list {
2 | .portfolio-main-group {
3 | .market-main-group-title {
4 | margin-right: 0.4em;
5 | text-transform: uppercase;
6 | }
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/src/modules/my-positions/components/my-position.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ValueDenomination from 'modules/common/components/value-denomination';
3 | import { SCALAR } from 'modules/markets/constants/market-types';
4 |
5 | const Position = p => (
6 |
7 |
8 | {p.type === SCALAR ?
9 | {p.lastPricePercent.rounded} :
10 | {p.name}
11 | }
12 |
13 |
14 |
15 |
16 | average price of open position
17 |
18 |
19 |
20 | last trade price
21 |
22 |
23 |
24 |
25 |
26 | realized P/L
27 |
28 |
29 |
30 | unrealized P/L
31 |
32 |
33 |
34 | total P/L
35 |
36 |
37 |
38 |
39 | );
40 |
41 | Position.propTypes = {
42 | name: React.PropTypes.string,
43 | type: React.PropTypes.string,
44 | qtyShares: React.PropTypes.object,
45 | gainPercent: React.PropTypes.object,
46 | lastPrice: React.PropTypes.object,
47 | lastPricePercent: React.PropTypes.object,
48 | purchasePrice: React.PropTypes.object,
49 | realizedNet: React.PropTypes.object,
50 | unrealizedNet: React.PropTypes.object,
51 | totalNet: React.PropTypes.object
52 | };
53 |
54 | export default Position;
55 |
--------------------------------------------------------------------------------
/src/modules/my-positions/components/my-positions-market-overview.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ValueDenomination from 'modules/common/components/value-denomination';
3 |
4 | const PositionsMarketOverview = p => (
5 |
6 |
7 |
{p.description}
8 |
9 |
10 | total realized P/L
11 |
12 |
13 |
14 | total unrealized P/L
15 |
16 |
17 |
18 | total P/L
19 |
20 |
21 |
22 |
23 |
24 | );
25 |
26 | PositionsMarketOverview.propTypes = {
27 | description: React.PropTypes.string.isRequired,
28 | unrealizedNet: React.PropTypes.object.isRequired,
29 | realizedNet: React.PropTypes.object.isRequired
30 | };
31 |
32 | export default PositionsMarketOverview;
33 |
--------------------------------------------------------------------------------
/src/modules/my-positions/components/my-positions-summary.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import classnames from 'classnames';
3 |
4 | const PositionsSummary = p => (
5 |
6 | {!!p.numPositions &&
7 | Positions
8 | }
9 |
10 | );
11 |
12 | PositionsSummary.propTypes = {
13 | className: React.PropTypes.string
14 | };
15 |
16 | export default PositionsSummary;
17 |
--------------------------------------------------------------------------------
/src/modules/my-positions/components/my-positions.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactTooltip from 'react-tooltip';
3 |
4 | import Position from 'modules/my-positions/components/my-position';
5 | import Link from 'modules/link/components/link';
6 |
7 | const Positions = p => (
8 |
9 | {p.marketLink &&
10 |
11 | {(p.market.myPositionOutcomes || []).map(outcome =>
12 |
18 | )}
19 |
20 | }
21 | {!p.marketLink &&
22 | (p.market.myPositionOutcomes || []).map(outcome =>
23 |
29 | )
30 | }
31 | {!p.settings.autoSellCompleteSets && p.market.hasCompleteSet &&
32 |
33 |
34 | {
38 | event.stopPropagation();
39 | p.market.onSubmitClosePosition();
40 | }}
41 | >
42 | Redeem {p.market.smallestPosition.formatted} Complete Sets
43 |
44 |
45 |
46 | }
47 |
48 |
49 | );
50 |
51 | // TODO -- Prop Validations
52 | // Positions.propTypes = {
53 | // className: React.PropTypes.string,
54 | // market: React.PropTypes.object,
55 | // marketLink: React.PropTypes.object
56 | // };
57 |
58 | export default Positions;
59 |
--------------------------------------------------------------------------------
/src/modules/my-positions/less/my-positions.less:
--------------------------------------------------------------------------------
1 | .positions-market-overview,
2 | .positions-list {
3 | display: table;
4 | font-size: 1.2rem;
5 | line-height: 1.9rem;
6 | margin: 1vmin 0 0 4%;
7 | width: 92%;
8 |
9 | .complete-sets {
10 | .close-position-button {
11 | float: left;
12 | margin-top: 10px;
13 | }
14 | }
15 |
16 | .position {
17 | display: table-row;
18 |
19 | &:not(:first-child) {
20 | border-top: 1px solid @color-border;
21 | }
22 |
23 | .position-group {
24 | display: table-cell;
25 | padding: 0.5em 0;
26 | text-align: right;
27 | vertical-align: middle;
28 |
29 | .position-pair {
30 | display: inline-block;
31 | line-height: 1.1em;
32 | min-width: 7.8em;
33 | white-space: nowrap;
34 |
35 | &.realized-net,
36 | &.unrealized-net,
37 | &.total-net {
38 | .colorize();
39 | }
40 |
41 | > * {
42 | display: block;
43 | margin-left: 0.5em;
44 | }
45 |
46 | .title {
47 | font-size: 0.8em;
48 | }
49 | }
50 | }
51 |
52 | .main-group {
53 | text-align: left;
54 | .colorize();
55 |
56 | > * {
57 | display: inline-block;
58 | margin-right: 1em;
59 | vertical-align: middle;
60 | }
61 |
62 | .position-pair {
63 | white-space: nowrap;
64 | }
65 |
66 | .position-name {
67 | min-width: 4.5em;
68 | text-transform: uppercase;
69 | }
70 | }
71 | }
72 | }
73 |
74 | .positions-market-overview {
75 | .position {
76 | .description {
77 | padding-left: 0;
78 | }
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/src/modules/my-reports/less/my-reports.less:
--------------------------------------------------------------------------------
1 | .portfolio-list {
2 | .portfolio-main-group {
3 | .report-main-group-title {
4 | margin-right: 0.4em;
5 | text-transform: uppercase;
6 | }
7 |
8 | .report-main-group-title-outcome {
9 | text-transform: none;
10 |
11 | .report-committed {
12 | color: @color-negative;
13 | }
14 |
15 | .fa {
16 | font-family: 'Font Awesome';
17 | padding: 0 0.4rem;
18 |
19 | &.report-equal {
20 | color: @color-positive;
21 | }
22 |
23 | &.report-unequal {
24 | color: @color-negative;
25 | }
26 |
27 | &.report-unethical {
28 | color: @color-negative;
29 | }
30 | }
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/modules/open-orders/components/open-orders-group.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import OpenOrder from 'modules/open-orders/components/open-order';
4 |
5 | const OpenOrdersGroup = (p) => {
6 | if (p.userOpenOrders == null || p.userOpenOrders.length === 0) {
7 | return null;
8 | }
9 |
10 | return (
11 |
12 | {p.userOpenOrders.map((openOrder, index) =>
13 |
24 | )}
25 |
26 | );
27 | };
28 |
29 | // TODO -- Prop Validations
30 | // OpenOrdersGroup.propTypes = {
31 | // userOpenOrders: React.PropTypes.arrayOf(React.PropTypes.object).isRequired,
32 | // name: React.PropTypes.string.isRequired,
33 | // orderCancellation: React.PropTypes.object.isRequired,
34 | // isFirst: React.PropTypes.bool.isRequired
35 | // };
36 |
37 | export default OpenOrdersGroup;
38 |
--------------------------------------------------------------------------------
/src/modules/open-orders/less/open-order.less:
--------------------------------------------------------------------------------
1 | .market-open-orders {
2 | .open-orders-list {
3 | font-size: 1.2rem;
4 | margin-left: 4%;
5 | width: 92%;
6 |
7 | .open-orders-group {
8 | width: 100%;
9 |
10 | td {
11 | box-sizing: border-box; // this should be done for *
12 | padding: 0.5em 0;
13 | }
14 |
15 | .outcome-name {
16 | min-width: 9rem;
17 | text-align: left;
18 | }
19 |
20 | .type {
21 | text-align: right;
22 | }
23 |
24 | .shares {
25 | text-align: right;
26 | }
27 |
28 | .price {
29 | text-align: right;
30 | }
31 |
32 | .cancel {
33 | text-align: right;
34 | width: 110px; // so there is enough space for different states
35 |
36 | .cancel-order-action {
37 | background: transparent;
38 | color: @color-danger-active;
39 | height: unset;
40 | line-height: unset;
41 | padding: 0;
42 | text-align: left;
43 |
44 | &::before {
45 | content: '\f00d';
46 | display: inline-block;
47 | font-family: 'Font Awesome';
48 | font-weight: 700;
49 | left: -0.2em;
50 | position: relative;
51 | }
52 |
53 | &:hover,
54 | &:active {
55 | font-weight: 900;
56 | }
57 |
58 | &[disabled] {
59 | background: transparent !important;
60 | color: @color-muted-active !important;
61 | }
62 | }
63 |
64 | .cancel-order-abort-confirmation {
65 | background-color: transparent;
66 | color: inherit;
67 | height: unset;
68 | line-height: unset;
69 | margin-right: 1.4em;
70 | padding: 0;
71 | text-align: left;
72 |
73 | &:hover {
74 | font-weight: 700;
75 | }
76 | }
77 | }
78 |
79 | .open-order {
80 | border-top: 1px solid @color-border;
81 |
82 | &.first {
83 | border-top: none;
84 | }
85 |
86 | .outcome-name {
87 | text-transform: uppercase;
88 | }
89 |
90 | &.is-disabled {
91 | text-decoration: line-through;
92 | }
93 | }
94 | }
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/src/modules/order-book/components/order-book-header.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | const OrderBookHeader = () => (
4 |
5 | Bid Q.
6 | Bid
7 | Ask
8 | Ask Q.
9 |
10 | );
11 |
12 | export default OrderBookHeader;
13 |
--------------------------------------------------------------------------------
/src/modules/order-book/components/order-book-rows.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import OrderBookRowSide from 'modules/order-book/components/order-book-row-side';
4 |
5 | import { BID } from 'modules/transactions/constants/types';
6 |
7 | const OrderBookRows = p => (
8 |
9 |
18 |
26 |
27 | );
28 |
29 | export default OrderBookRows;
30 |
--------------------------------------------------------------------------------
/src/modules/order-book/components/order-book.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import OrderBookHeader from 'modules/order-book/components/order-book-header';
4 | import OrderBookRows from 'modules/order-book/components/order-book-rows';
5 | import EmDash from 'modules/common/components/em-dash';
6 |
7 | import { SCALAR } from 'modules/markets/constants/market-types';
8 |
9 | // NOTE --
10 | // Bids + Asks are rendered into individual row components -- flexbox is utilized for side-by-side layout
11 | const OrderBook = p => (
12 |
13 | {p.marketType !== SCALAR ?
14 | Order Book {p.outcome.name} :
15 | Order Book
16 | }
17 |
18 |
19 |
28 |
29 |
30 | );
31 |
32 | export default OrderBook;
33 |
--------------------------------------------------------------------------------
/src/modules/order-book/constants/order-book-value-types.js:
--------------------------------------------------------------------------------
1 | export const PRICE = 'price';
2 | export const SHARE = 'share';
3 |
--------------------------------------------------------------------------------
/src/modules/order-book/less/order-book-header.less:
--------------------------------------------------------------------------------
1 | .order-book-header {
2 |
3 | .table-header();
4 |
5 | flex: none;
6 | }
7 |
--------------------------------------------------------------------------------
/src/modules/order-book/less/order-book-row-side.less:
--------------------------------------------------------------------------------
1 | .order-book-row-side {
2 | flex: 1;
3 |
4 | &:first-child {
5 |
6 | .border(true, @border-right, @border-light);
7 | }
8 |
9 | &.order-book-row-side-trading {
10 | background-color: @color-blue-extra-light;
11 | }
12 |
13 | .order-book-side-row {
14 |
15 | .border(true, @border-top, @border-light);
16 | .table-row();
17 |
18 | display: flex;
19 |
20 | &.is-of-current-user {
21 | background-color: @color-green-extra-light;
22 |
23 | &:hover {
24 | background-color: @color-green-extra-light;
25 | }
26 | }
27 |
28 | & > * {
29 |
30 | .table-cell-spacing();
31 |
32 | flex: 1;
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/modules/order-book/less/order-book-rows.less:
--------------------------------------------------------------------------------
1 | .order-book-rows {
2 | display: flex;
3 | }
4 |
--------------------------------------------------------------------------------
/src/modules/order-book/less/order-book.less:
--------------------------------------------------------------------------------
1 | .order-book {
2 |
3 | .table();
4 |
5 | .order-book-header,
6 | .order-book-side-row {
7 | & > * {
8 | flex: 1;
9 | text-align: center;
10 | }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/modules/outcomes/components/outcome-trade-action.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 |
3 | export default class OutcomeTradeAction extends Component {
4 | constructor(props) {
5 | super(props);
6 |
7 | this.state = {
8 | isConfirming: false
9 | };
10 | }
11 |
12 | render() {
13 | const p = this.props;
14 | const s = this.state;
15 |
16 | return (
17 |
18 | {!s.isConfirming &&
19 |
{
22 | this.setState({ isConfirming: true });
23 | }}
24 | >
25 | Place Trade
26 |
27 | }
28 | {s.isConfirming &&
29 |
30 |
Are you sure?
31 |
32 | {
35 | this.setState({ isConfirming: false });
36 | }}
37 | >
38 | Cancel
39 |
40 | {
42 | p.submitTrade(p.selectedID);
43 | }}
44 | >
45 | Yes
46 |
47 |
48 |
49 | }
50 |
51 | );
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/src/modules/outcomes/components/outcome-trade-summary.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import ValueDenomination from 'modules/common/components/value-denomination';
4 |
5 | import getValue from 'utils/get-value';
6 |
7 | const OutcomeTradeSummary = (p) => {
8 | const tradingFees = getValue(p, 'tradeOrder.tradingFees');
9 | const feePercent = getValue(p, 'tradeOrder.feePercent');
10 | const gasFees = getValue(p, 'tradeOrder.gasFees');
11 | const totalCost = getValue(p, 'trade.totalCost');
12 |
13 | return (
14 |
15 | {tradingFees && feePercent &&
16 |
17 | Fees:
18 | ETH ({p.tradeOrder.feePercent.formatted}%)
19 |
20 | }
21 | {gasFees &&
22 |
23 | Gas:
24 | ETH
25 |
26 | }
27 | {totalCost &&
28 |
29 | Total:
30 | ETH
31 |
32 | }
33 |
34 | );
35 | };
36 |
37 | export default OutcomeTradeSummary;
38 |
--------------------------------------------------------------------------------
/src/modules/outcomes/components/outcomes.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import Outcome from 'modules/outcomes/components/outcome';
4 |
5 | import { SCALAR } from 'modules/markets/constants/market-types';
6 |
7 | const Outcomes = p => (
8 |
9 |
10 |
11 | Outcome{!p.marketType === SCALAR && 's'}
12 | Bid Q.
13 | Bid
14 | Ask
15 | Ask Q
16 | Last
17 |
18 |
19 | Outcome{!p.marketType === SCALAR && 's'}
20 | Bid
21 | Ask
22 |
23 |
24 |
25 | {(p.outcomes || []).map(outcome => (
26 |
42 | ))}
43 |
44 |
45 | );
46 |
47 | export default Outcomes;
48 |
--------------------------------------------------------------------------------
/src/modules/outcomes/constants/trade-types.js:
--------------------------------------------------------------------------------
1 | export const BUY = 'buy';
2 | export const SELL = 'sell';
3 |
--------------------------------------------------------------------------------
/src/modules/outcomes/less/outcome-trade-action.less:
--------------------------------------------------------------------------------
1 | .outcome-trade-action {
2 | display: flex;
3 | justify-content: center;
4 | margin: 1em;
5 |
6 | .trade-confirmation {
7 | display: flex;
8 | flex: 1;
9 | flex-direction: column;
10 | justify-content: center;
11 |
12 | span {
13 |
14 | .font-size-large();
15 |
16 | align-self: center;
17 | }
18 |
19 | .trade-confirmation-actions {
20 | display: flex;
21 |
22 | button {
23 | flex: 1;
24 | margin: 1em 1em 0;
25 |
26 | &.cancel {
27 | background-color: @color-gray;
28 | }
29 | }
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/modules/outcomes/less/outcome-trade-summary.less:
--------------------------------------------------------------------------------
1 | .outcome-trade-summary {
2 | & > div {
3 | display: flex;
4 | margin: 1em 0 1em 1em;
5 |
6 | & > span:first-child {
7 | flex: 1;
8 | }
9 |
10 | & > span {
11 | display: flex;
12 | flex: 5;
13 |
14 | .value-denomination {
15 | display: flex;
16 | flex: 2;
17 | justify-content: flex-end;
18 |
19 | & + span {
20 | flex: 1;
21 | padding-left: 1em;
22 | }
23 | }
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/modules/outcomes/less/outcome-trade.less:
--------------------------------------------------------------------------------
1 | .outcome-trade {
2 | @media @breakpoint-mobile {
3 | background-color: @color-gray-extra-light;
4 | padding: 1em 0;
5 | }
6 |
7 | h3 {
8 | @media @breakpoint-mobile {
9 | display: none;
10 | }
11 | }
12 |
13 | .outcome-trade-input-error-message {
14 | color: @color-red-light;
15 | padding: 0 0 0.5em;
16 | }
17 |
18 | & > span {
19 | margin-left: 1em;
20 | }
21 |
22 | .outcome-trade-inputs {
23 | display: flex;
24 | flex-direction: column;
25 |
26 | .outcome-trade-inputs-sides {
27 | display: flex;
28 | flex-direction: row;
29 |
30 | & > * {
31 | flex: 1;
32 |
33 | .link {
34 | flex: 1;
35 |
36 | &.selected {
37 |
38 | .border(true, @border-bottom, @color-purple, @border-width-3);
39 | }
40 |
41 | &:hover:not(.selected) {
42 |
43 | .border(true, @border-bottom, @color-purple, @border-width-2);
44 | }
45 |
46 | li {
47 | display: flex;
48 | justify-content: center;
49 | margin: 0;
50 |
51 | &.selected {
52 |
53 | .border(false);
54 | }
55 |
56 | &:hover:not(.selected) {
57 |
58 | .border(false);
59 | }
60 | }
61 | }
62 | }
63 | }
64 |
65 | .outcome-trade-inputs-fields {
66 | align-items: center;
67 | display: flex;
68 | flex-direction: row;
69 | padding: 1em;
70 |
71 | .input {
72 | flex: 3;
73 | }
74 |
75 | span {
76 | display: flex;
77 | flex: 1;
78 | justify-content: center;
79 | }
80 | }
81 | }
82 |
83 | .outcome-trade-actions {
84 | display: flex;
85 | justify-content: center;
86 | margin: 1em 0;
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/src/modules/outcomes/less/outcome.less:
--------------------------------------------------------------------------------
1 | .outcome {
2 | .outcome-trade {
3 | box-shadow: inset 0 5px 5px -5px @color-black-extra-light, inset 0 -5px 5px -5px @color-black-extra-light;
4 | display: none;
5 | }
6 |
7 | &.selected {
8 | .outcome-trade {
9 | @media @breakpoint-mobile {
10 | display: flex;
11 | flex-direction: column;
12 | }
13 | }
14 | }
15 |
16 | .outcome-row-full,
17 | .outcome-row-condensed {
18 |
19 | .table-row();
20 |
21 | @media @breakpoint-mobile {
22 | &.selected {
23 | .border(true, @border-left, @color-blue);
24 | }
25 | }
26 |
27 | &.link {
28 | cursor: default;
29 | }
30 | }
31 |
32 | .outcome-row-full {
33 | @media @breakpoint-mobile {
34 | display: none;
35 | }
36 | }
37 |
38 | .outcome-row-condensed {
39 | display: none;
40 |
41 | @media @breakpoint-mobile {
42 | display: flex;
43 | }
44 |
45 | .outcome-summary {
46 | align-items: flex-start;
47 | display: flex;
48 | flex-direction: column;
49 | justify-content: center;
50 |
51 | .outcome-name {
52 |
53 | .font-weight-normal();
54 |
55 | margin-bottom: 0.2em;
56 | }
57 | }
58 |
59 | .outcome-best-orders {
60 | display: flex;
61 | justify-content: center;
62 |
63 | .outcome-best-container {
64 | border-radius: 5px;
65 | color: @color-white;
66 | display: flex;
67 | flex-direction: column;
68 | padding: 1em 1.5em;
69 | }
70 |
71 | &.outcome-best-bid .outcome-best-container {
72 | background-color: @color-red;
73 | }
74 |
75 | &.outcome-best-ask .outcome-best-container {
76 | background-color: @color-green;
77 | }
78 | }
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/src/modules/outcomes/less/outcomes.less:
--------------------------------------------------------------------------------
1 | .outcomes {
2 |
3 | .table();
4 |
5 | margin-top: 1em;
6 |
7 | .outcomes-header-full,
8 | .outcomes-header-condensed {
9 | .table-header();
10 | }
11 |
12 | .outcomes-header-full {
13 | @media @breakpoint-mobile {
14 | display: none;
15 | }
16 | }
17 |
18 | .outcomes-header-condensed {
19 | display: none;
20 |
21 | @media @breakpoint-mobile {
22 | display: flex;
23 |
24 | .border(false);
25 | }
26 | }
27 |
28 | .outcomes-header-full,
29 | .outcomes-header-condensed,
30 | .outcome-row-full,
31 | .outcome-row-condensed {
32 | & > * {
33 | flex: 1;
34 |
35 | &:first-child {
36 | flex: 3;
37 | margin-left: 1em;
38 | }
39 |
40 | @media @breakpoint-mobile {
41 | padding-left: 1em;
42 | padding-right: 1em;
43 | }
44 | }
45 |
46 | span:not(:first-child) {
47 | text-align: center;
48 |
49 | .border(false, @border-left);
50 | }
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/modules/portfolio/components/markets.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import Market from 'modules/my-markets/components/my-market';
3 | import Link from 'modules/link/components/link';
4 |
5 | const PortfolioMarkets = p => (
6 |
7 | {!!p.markets && !!p.markets.length && p.markets.map(market => (
8 |
9 |
10 |
{market.description}
11 | {!!market &&
12 |
13 |
14 |
15 | }
16 |
17 |
18 | ))}
19 |
20 | );
21 |
22 | // TODO -- Prop Validations
23 | // PortfolioMarkets.propTypes = {
24 | // markets: React.PropTypes.array.isRequired
25 | // };
26 |
27 | export default PortfolioMarkets;
28 |
--------------------------------------------------------------------------------
/src/modules/portfolio/components/portfolio-view.jsx:
--------------------------------------------------------------------------------
1 | import React, { PropTypes } from 'react';
2 |
3 | import TabNavigation from 'modules/common/components/tab-navigation';
4 | import Positions from 'modules/portfolio/components/positions';
5 | import Markets from 'modules/portfolio/components/markets';
6 | import Reports from 'modules/portfolio/components/reports';
7 |
8 | import { MY_POSITIONS, MY_MARKETS, MY_REPORTS } from 'modules/app/constants/views';
9 |
10 | const PortfolioView = (p) => {
11 | let node;
12 |
13 | switch (p.activeView) {
14 | default:
15 | case MY_POSITIONS:
16 | node = ;
17 | break;
18 | case MY_MARKETS:
19 | node = ;
20 | break;
21 | case MY_REPORTS:
22 | node = ;
23 | break;
24 | }
25 | return (
26 |
27 |
28 | {!!p.navItems && !!p.navItems.length &&
29 |
33 | }
34 |
35 |
36 |
37 |
40 |
41 |
42 | );
43 | };
44 |
45 | PortfolioView.propTypes = {
46 | navItems: PropTypes.array.isRequired,
47 | totals: PropTypes.object.isRequired,
48 | positions: PropTypes.object.isRequired,
49 | markets: PropTypes.object.isRequired,
50 | reports: PropTypes.object.isRequired,
51 | settings: PropTypes.object.isRequired
52 | };
53 |
54 | export default PortfolioView;
55 |
--------------------------------------------------------------------------------
/src/modules/portfolio/components/positions.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import Positions from 'modules/my-positions/components/my-positions';
3 | import PositionsMarketOverview from 'modules/my-positions/components/my-positions-market-overview';
4 | import Link from 'modules/link/components/link';
5 |
6 | const PortfolioPositions = p => (
7 |
8 | {!!p.markets && !!p.markets.length && p.markets.map(market => (
9 |
10 |
11 |
15 |
16 | {!!market.myPositionOutcomes && !!market.myPositionOutcomes.length &&
17 |
23 | }
24 |
25 | ))}
26 |
27 | );
28 |
29 | // TODO -- Prop Validations
30 | // PortfolioPositions.propTypes = {
31 | // markets: React.PropTypes.array.isRequired
32 | // };
33 |
34 | export default PortfolioPositions;
35 |
--------------------------------------------------------------------------------
/src/modules/portfolio/components/reports.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactTooltip from 'react-tooltip';
3 |
4 | import Report from 'modules/my-reports/components/my-report';
5 | import Link from 'modules/link/components/link';
6 |
7 | const PortfolioReports = p => (
8 |
9 | {!!p.reports && !!p.reports.length && p.reports.map(market => (
10 |
11 |
12 |
13 | {market.description}
14 | {market.isChallenged &&
15 |
19 |
20 |
21 | }
22 | {!market.isChallenged && market.isChallengeable &&
23 |
27 |
28 |
29 | }
30 |
31 | {!!market &&
32 |
33 |
34 |
35 | }
36 |
37 |
38 | ))}
39 |
40 |
41 | );
42 |
43 | // TODO -- Prop Validations
44 | // PortfolioReports.propTypes = {
45 | // reports: React.PropTypes.array.isRequired
46 | // };
47 |
48 | export default PortfolioReports;
49 |
--------------------------------------------------------------------------------
/src/modules/reports/components/report-panel.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 |
3 | import MarketHeader from 'modules/market/components/market-header';
4 | import ComponentNav from 'modules/common/components/component-nav';
5 | import ReportForm from 'modules/reports/components/report-form';
6 | import MarketDetails from 'modules/market/components/market-details';
7 |
8 | import { MARKET_REPORTING_NAV_REPORT, MARKET_REPORTING_NAV_DETAILS } from 'modules/app/constants/views';
9 |
10 | import getValue from 'utils/get-value';
11 |
12 | export default class ReportPanel extends Component {
13 | constructor(props) {
14 | super(props);
15 |
16 | this.state = {
17 | selectedNav: MARKET_REPORTING_NAV_REPORT
18 | };
19 |
20 | this.updateSelectedNav = this.updateSelectedNav.bind(this);
21 | }
22 |
23 | updateSelectedNav(selectedNav) {
24 | this.setState({ selectedNav });
25 | }
26 |
27 | render() {
28 | const p = this.props;
29 | const s = this.state;
30 |
31 | const market = getValue(p, 'market');
32 |
33 | return (
34 |
35 |
36 |
41 | {s.selectedNav === MARKET_REPORTING_NAV_REPORT &&
42 |
43 |
48 |
49 | }
50 | {s.selectedNav === MARKET_REPORTING_NAV_DETAILS &&
51 |
52 | }
53 |
54 | );
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/modules/reports/less/report-form.less:
--------------------------------------------------------------------------------
1 | .report-form {
2 | display: flex;
3 | flex-direction: column;
4 | margin: 1em;
5 |
6 | & > div {
7 | display: flex;
8 | flex-direction: column;
9 |
10 | &:not(:first-child) {
11 | margin: 1em 0;
12 | }
13 | }
14 |
15 | .reportable-outcomes {
16 | display: flex;
17 | flex-direction: column;
18 | margin-top: 1em;
19 |
20 | .outcome-option {
21 | margin: 0.25em;
22 |
23 | .outcome-option-radio {
24 | margin-right: 1em;
25 | }
26 | }
27 | }
28 |
29 | .checkbox {
30 | margin-top: 1em;
31 | }
32 |
33 | .report-actions {
34 | flex-direction: row;
35 | margin-bottom: 0;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/modules/transactions/components/transactions-view.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import Transactions from 'modules/transactions/components/transactions';
4 |
5 | const TransactionsPage = p => (
6 |
7 |
8 | {p.transactionsTotals.title}
9 |
10 |
11 |
12 |
16 |
17 |
18 | );
19 |
20 | TransactionsPage.propTypes = {
21 | className: React.PropTypes.string,
22 | transactions: React.PropTypes.array,
23 | transactionsTotals: React.PropTypes.object
24 | };
25 |
26 | export default TransactionsPage;
27 |
--------------------------------------------------------------------------------
/src/modules/transactions/components/transactions.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import Transaction from 'modules/transactions/components/transaction';
3 |
4 | const Transactions = p => (
5 |
6 |
7 | {(p.transactions || []).map((transaction, i) =>
8 |
13 | )}
14 |
15 | {!!p.transactions.length &&
16 |
17 | {"continue trading while transactions are running, just don't close the browser before they're done!"}
18 |
19 | }
20 |
21 | );
22 |
23 | // TODO -- prop validations
24 | // Transactions.propTypes = {
25 | // transactions: React.PropTypes.array
26 | // };
27 | export default Transactions;
28 |
--------------------------------------------------------------------------------
/src/modules/transactions/constants/types.js:
--------------------------------------------------------------------------------
1 | export const BUY = 'buy';
2 | export const SELL = 'sell';
3 | export const TRADE_SUMMARY = 'trade_summary';
4 | export const BID = 'bid';
5 | export const ASK = 'ask';
6 | export const SHORT_SELL = 'short_sell';
7 | export const SHORT_ASK = 'short_ask';
8 | export const CREATE_MARKET = 'create_market';
9 | export const COMMIT_REPORT = 'commit_report';
10 | export const REVEAL_REPORT = 'reveal_report';
11 | export const REGISTER_ACCOUNT = 'register_account';
12 | export const GENERATE_ORDER_BOOK = 'generate_order_book';
13 | export const CANCEL_ORDER = 'cancel_order';
14 | export const SELL_COMPLETE_SETS = 'sell_complete_sets';
15 |
--------------------------------------------------------------------------------
/src/selectors/active-view.js:
--------------------------------------------------------------------------------
1 | export default 'markets';
2 |
--------------------------------------------------------------------------------
/src/selectors/chat.js:
--------------------------------------------------------------------------------
1 | export default {
2 | augur: {}
3 | };
4 |
--------------------------------------------------------------------------------
/src/selectors/core-stats.js:
--------------------------------------------------------------------------------
1 | import { randomNum } from 'utils/random-number';
2 | import makeNumber from 'utils/make-number';
3 |
4 | export default [
5 | {
6 | totalEth: {
7 | label: 'Total ETH',
8 | title: 'Ether -- outcome trading currency',
9 | value: makeNumber(Math.abs(randomNum(1000)), 'ETH')
10 | },
11 | totalRep: {
12 | label: 'Total REP',
13 | title: 'Reputation -- event voting currency',
14 | value: makeNumber(Math.abs(randomNum(100)), 'REP')
15 | }
16 | },
17 | // {
18 | // totalRiskedEth: {
19 | // label: 'Risked ETH',
20 | // title: 'Risked Ether -- Ether tied up in positions',
21 | // value: makeNumber(Math.abs(randomNum(1000)), 'ETH')
22 | // },
23 | // totalAvailableEth: {
24 | // label: 'Available ETH',
25 | // title: 'Available Ether -- Ether not tied up in positions',
26 | // value: makeNumber(Math.abs(randomNum(1000)), 'ETH')
27 | // }
28 | // },
29 | {
30 | totalPL: {
31 | label: 'Total P/L',
32 | tile: 'Profit/Loss -- net of all trades',
33 | value: makeNumber(0),
34 | colorize: true
35 | },
36 | totalPLMonth: {
37 | label: '30 Day P/L',
38 | tile: 'Profit/Loss -- net of all trades over the last 30 days',
39 | value: makeNumber(randomNum(10), 'ETH'),
40 | colorize: true
41 | },
42 | totalPLDay: {
43 | label: '1 Day P/L',
44 | tile: 'Profit/Loss -- net of all trades over the last day',
45 | value: makeNumber(randomNum(10), 'ETH'),
46 | colorize: true
47 | }
48 | }
49 | ];
50 |
--------------------------------------------------------------------------------
/src/selectors/filter-sort.js:
--------------------------------------------------------------------------------
1 | export default {
2 | selectedFilterSort: { // Initial Defaults
3 | type: 'open',
4 | sort: 'volume',
5 | isDesc: true
6 | },
7 | types: [
8 | {
9 | label: 'Open',
10 | value: 'open',
11 | default: true
12 | },
13 | {
14 | label: 'Closed',
15 | value: 'closed'
16 | },
17 | {
18 | label: 'Reporting',
19 | value: 'reporting'
20 | }
21 | ],
22 | sorts: [
23 | {
24 | label: 'Volume',
25 | value: 'volume',
26 | default: true
27 | },
28 | {
29 | label: 'Newest',
30 | value: 'newest'
31 | },
32 | {
33 | label: 'Expiry',
34 | value: 'expiry'
35 | },
36 | {
37 | label: 'Taker Fee',
38 | value: 'takerFee'
39 | },
40 | {
41 | label: 'Maker Fee',
42 | value: 'makerFee'
43 | }
44 | ],
45 | order: {
46 | isDesc: true // This is the default
47 | },
48 | onChange: (type, sort, order) => {
49 | const selectors = require('../selectors');
50 |
51 | const isDesc = order == null ? selectors.filterSort.selectedFilterSort.isDesc : order;
52 |
53 | selectors.update({
54 | filterSort: {
55 | ...selectors.filterSort,
56 | filterSort: {
57 | type: type || selectors.filterSort.selectedFilterSort.type,
58 | sort: sort || selectors.filterSort.selectedFilterSort.sort,
59 | isDesc
60 | }
61 | }
62 | });
63 | }
64 | };
65 |
--------------------------------------------------------------------------------
/src/selectors/is-transactions-working.js:
--------------------------------------------------------------------------------
1 | export default true;
2 |
--------------------------------------------------------------------------------
/src/selectors/keywords.js:
--------------------------------------------------------------------------------
1 | export default {
2 | value: '',
3 | onChangeKeywords: (keywords) => {
4 | const selectors = require('../selectors');
5 |
6 | selectors.update({
7 | keywords: {
8 | ...selectors.keywords,
9 | value: keywords
10 | }
11 | });
12 | }
13 | };
14 |
--------------------------------------------------------------------------------
/src/selectors/links.js:
--------------------------------------------------------------------------------
1 | import { ACCOUNT, MARKETS, MAKE, TRANSACTIONS, M, MY_POSITIONS, MY_MARKETS, MY_REPORTS, LOGIN_MESSAGE } from 'modules/app/constants/views';
2 | import { LOGIN } from 'modules/auth/constants/auth-types';
3 |
4 | export default {
5 | authLink: { href: '/?page=register', onClick: url => require('../selectors').update({ activeView: LOGIN, url }) },
6 | marketsLink: { href: '/', onClick: url => require('../selectors').update({ activeView: MARKETS, url }) },
7 | transactionsLink: { href: '/?page=transactions', onClick: url => require('../selectors').update({ activeView: TRANSACTIONS, url }) },
8 | marketLink: { href: '/?page=m', onClick: url => require('../selectors').update({ activeView: M, url }) },
9 | previousLink: { href: '/', onClick: url => require('../selectors').update({ activeView: MARKETS, url }) },
10 | createMarketLink: { href: '/?page=create', onClick: url => require('../selectors').update({ activeView: MAKE, url }) },
11 | accountLink: { href: '/?page=account', onClick: url => require('../selectors').update({ activeView: ACCOUNT, url }) },
12 | myPositionsLink: { href: '/?page=my-positions', onClick: url => require('../selectors').update({ activeView: MY_POSITIONS, url }) },
13 | myMarketsLink: { href: '/?page=my-markets', onClick: url => require('../selectors').update({ activeView: MY_MARKETS, url }) },
14 | myReportsLink: { href: '/?page=my-reports', onClick: url => require('../selectors').update({ activeView: MY_REPORTS, url }) },
15 | loginMessageLink: { href: '/?page=login-message', onClick: url => require('../selectors').update({ activeView: LOGIN_MESSAGE, url }) }
16 | };
17 |
--------------------------------------------------------------------------------
/src/selectors/login-account-markets.js:
--------------------------------------------------------------------------------
1 | import markets from 'selectors/my-markets';
2 | import summary from 'selectors/my-markets-summary';
3 |
4 | export default {
5 | markets,
6 | summary
7 | };
8 |
--------------------------------------------------------------------------------
/src/selectors/login-account-positions.js:
--------------------------------------------------------------------------------
1 | import markets from 'selectors/positions-markets';
2 | import summary from 'selectors/positions-summary';
3 |
4 | export default {
5 | markets,
6 | summary
7 | };
8 |
--------------------------------------------------------------------------------
/src/selectors/login-account-reports.js:
--------------------------------------------------------------------------------
1 | import reports from 'selectors/my-reports';
2 | import summary from 'selectors/my-reports-summary';
3 |
4 | export default {
5 | reports,
6 | summary
7 | };
8 |
--------------------------------------------------------------------------------
/src/selectors/market-data-age.js:
--------------------------------------------------------------------------------
1 | export default {
2 | lastUpdatedBefore: '1 second ago',
3 | isMarketDataLoading: false
4 | };
5 |
--------------------------------------------------------------------------------
/src/selectors/market-data-nav-items.js:
--------------------------------------------------------------------------------
1 | import { MARKET_DATA_NAV_OUTCOMES, MARKET_DATA_ORDERS, MARKET_DATA_NAV_CHARTS, MARKET_DATA_NAV_DETAILS } from 'modules/app/constants/views';
2 |
3 | export default {
4 | [MARKET_DATA_NAV_OUTCOMES]: {
5 | label: 'Outcomes'
6 | },
7 | [MARKET_DATA_ORDERS]: {
8 | label: 'Orders',
9 | mobileOnly: true
10 | },
11 | [MARKET_DATA_NAV_CHARTS]: {
12 | label: 'Charts'
13 | },
14 | [MARKET_DATA_NAV_DETAILS]: {
15 | label: 'Details'
16 | }
17 | };
18 |
--------------------------------------------------------------------------------
/src/selectors/market-data-updater.js:
--------------------------------------------------------------------------------
1 | // Starts timer and restarts it on demand
2 |
3 | const UPDATE_INTERVAL_SECS = 15;
4 |
5 | let timerId = startTimer();
6 |
7 | export default {
8 | /**
9 | * Resets market fields and restarts timer
10 | * @param marketId
11 | */
12 | update: (marketId) => {
13 | const marketDataAge = require('../selectors').marketDataAge;
14 |
15 | if (marketDataAge != null) {
16 | marketDataAge.lastUpdatedBefore = '1 second ago';
17 | marketDataAge.isMarketDataLoading = true;
18 | setTimeout(() => {
19 | const marketDataAge = require('../selectors').marketDataAge;
20 |
21 | marketDataAge.isMarketDataLoading = false;
22 | require('../selectors').update({
23 | marketDataAge
24 | });
25 | }, 1000);
26 | require('../selectors').update({
27 | marketDataAge
28 | });
29 | }
30 | clearInterval(timerId);
31 | timerId = startTimer();
32 | },
33 | updateIntervalSecs: UPDATE_INTERVAL_SECS
34 | };
35 |
36 | /**
37 | * Starts timer which periodically updates market fields and redraws the app
38 | *
39 | * @return {number} timerID
40 | */
41 | function startTimer() {
42 | return setInterval(() => {
43 | const marketDataAge = require('../selectors').marketDataAge;
44 |
45 | if (marketDataAge != null) {
46 | const lastUpdatedBeforeSecs = parseInt(marketDataAge.lastUpdatedBefore, 10);
47 | marketDataAge.lastUpdatedBefore = `${(lastUpdatedBeforeSecs + 1)} seconds ago`;
48 | require('../selectors').update({
49 | marketDataAge
50 | }, { ignore: true });
51 | }
52 | }, 1000);
53 | }
54 |
--------------------------------------------------------------------------------
/src/selectors/market-reporting-nav-items.js:
--------------------------------------------------------------------------------
1 | import { MARKET_REPORTING_NAV_REPORT, MARKET_REPORTING_NAV_DETAILS } from 'modules/app/constants/views';
2 |
3 | export default {
4 | [MARKET_REPORTING_NAV_REPORT]: {
5 | label: 'Report'
6 | },
7 | [MARKET_REPORTING_NAV_DETAILS]: {
8 | label: 'Details'
9 | }
10 | };
11 |
--------------------------------------------------------------------------------
/src/selectors/market-user-data-nav-items.js:
--------------------------------------------------------------------------------
1 | import { MARKET_USER_DATA_NAV_POSITIONS, MARKET_USER_DATA_NAV_OPEN_ORDERS } from 'modules/app/constants/views';
2 |
3 | export default {
4 | [MARKET_USER_DATA_NAV_POSITIONS]: {
5 | label: 'Positions'
6 | },
7 | [MARKET_USER_DATA_NAV_OPEN_ORDERS]: {
8 | label: 'Open Orders'
9 | }
10 | };
11 |
--------------------------------------------------------------------------------
/src/selectors/market.js:
--------------------------------------------------------------------------------
1 | import markets from './markets';
2 |
3 | export default markets[0];
4 |
--------------------------------------------------------------------------------
/src/selectors/markets-header.js:
--------------------------------------------------------------------------------
1 | export default {
2 | selectedMarketsHeader: null,
3 | numMarkets: 10,
4 | numFavorites: 6,
5 | numPendingReports: 20,
6 | onClickAllMarkets: () => {},
7 | onClickFavorites: () => {},
8 | onClickPendingReports: () => {}
9 | };
10 |
--------------------------------------------------------------------------------
/src/selectors/markets-totals.js:
--------------------------------------------------------------------------------
1 | export default {
2 | numAll: 6,
3 | numFavorites: 4,
4 | numPendingReports: 3,
5 | numUnpaginated: 7,
6 | numFiltered: 7,
7 | };
8 |
--------------------------------------------------------------------------------
/src/selectors/my-markets-summary.js:
--------------------------------------------------------------------------------
1 | export default {
2 | numMarkets: Math.random() * 4
3 | };
4 |
--------------------------------------------------------------------------------
/src/selectors/my-reports-summary.js:
--------------------------------------------------------------------------------
1 | export default {
2 | numReports: Math.random() * 4,
3 | netRep: Math.random() * 10
4 | };
5 |
--------------------------------------------------------------------------------
/src/selectors/order-cancellation.js:
--------------------------------------------------------------------------------
1 | export default {
2 | cancellationStatuses: {
3 | CANCELLATION_CONFIRMATION: 'CANCELLATION_CONFIRMATION',
4 | CANCELLING: 'CANCELLING',
5 | CANCELLED: 'CANCELLED',
6 | CANCELLATION_FAILED: 'CANCELLATION_FAILED'
7 | },
8 | cancelOrder: (orderID) => {
9 | require('../selectors').orderCancellation[orderID] = require('../selectors').orderCancellation.cancellationStatuses.CANCELLING;
10 | require('../selectors').update({});
11 |
12 | setTimeout(() => {
13 | require('../selectors').markets.forEach((market) => {
14 | market.outcomes.forEach((outcome) => {
15 | const order = outcome.userOpenOrders.find(openOrder => openOrder.id === orderID);
16 | if (order != null) {
17 | if (order.type === 'buy') {
18 | // cancellation success => remove
19 | const index = outcome.userOpenOrders.findIndex(openOrder => openOrder.id === orderID);
20 | outcome.userOpenOrders.splice(index, 1);
21 | } else {
22 | // cancellation failure => display cancel action again
23 | require('../selectors').orderCancellation[orderID] = require('../selectors').orderCancellation.cancellationStatuses.CANCELLATION_FAILED;
24 |
25 | setTimeout(() => {
26 | delete require('../selectors').orderCancellation[orderID];
27 | require('../selectors').update({});
28 | }, 2000);
29 | }
30 | require('../selectors').update({});
31 | }
32 | });
33 | });
34 | }, 2000);
35 | },
36 | showCancelOrderConfirmation: (orderID) => {
37 | // prevent accidental cancellation from double click
38 | setTimeout(() => {
39 | require('../selectors').orderCancellation[orderID] = require('../selectors').orderCancellation.cancellationStatuses.CANCELLATION_CONFIRMATION;
40 | require('../selectors').update({});
41 | }, 300);
42 | },
43 | abortCancelOrderConfirmation: (orderID) => {
44 | delete require('../selectors').orderCancellation[orderID];
45 | require('../selectors').update({});
46 | }
47 | };
48 |
--------------------------------------------------------------------------------
/src/selectors/outcome-trade-nav-items.js:
--------------------------------------------------------------------------------
1 | import { BUY, SELL } from 'modules/outcomes/constants/trade-types';
2 |
3 | export default {
4 | [BUY]: {
5 | label: BUY
6 | },
7 | [SELL]: {
8 | label: SELL
9 | }
10 | };
11 |
--------------------------------------------------------------------------------
/src/selectors/pagination.js:
--------------------------------------------------------------------------------
1 | import { MARKETS } from 'modules/app/constants/views';
2 |
3 | export default {
4 | numPerPage: 10,
5 | numPages: 10,
6 | selectedPageNum: 1,
7 | nextPageNum: 2,
8 | startItemNum: 1,
9 | endItemNum: 10,
10 | numUnpaginated: 89,
11 | nextItemNum: 11,
12 | onUpdateSelectedPageNum: (selectedPageNum) => {
13 | const selectors = require('../selectors');
14 |
15 | selectors.update({
16 | pagination: {
17 | ...selectors.pagination,
18 | selectedPageNum,
19 | nextPageNum: selectedPageNum + 1,
20 | previousPageNum: selectedPageNum - 1,
21 | startItemNum: ((selectedPageNum - 1) * 10) + 1,
22 | endItemNum: selectedPageNum * 10,
23 | nextItemNum: (selectedPageNum * 10) + 1,
24 | previousItemNum: ((selectedPageNum - 2) * 10) + 1
25 | }
26 | });
27 | },
28 | previousPageLink: { href: '/?page=1', onClick: url => require('../selectors').update({ activeView: MARKETS, url }) },
29 | nextPageLink: { href: '/?page=2', onClick: url => require('../selectors').update({ activeView: MARKETS, url }) },
30 | };
31 |
--------------------------------------------------------------------------------
/src/selectors/portfolio-nav-items.js:
--------------------------------------------------------------------------------
1 | import links from 'selectors/links';
2 |
3 | import { MY_POSITIONS, MY_MARKETS, MY_REPORTS } from 'modules/app/constants/views';
4 |
5 | import makeNumber from 'utils/make-number';
6 | import { randomNum } from 'utils/random-number';
7 |
8 | export default [
9 | {
10 | label: 'Positions',
11 | link: links.myPositionsLink,
12 | page: MY_POSITIONS,
13 | leadingTitle: 'Total Positions',
14 | leadingValue: makeNumber(Math.round(randomNum()), 'positions'),
15 | trailingTitle: 'Total Gain/Loss',
16 | trailingValue: makeNumber(randomNum(), ' ETH')
17 | },
18 | {
19 | label: 'Markets',
20 | link: links.myMarketsLink,
21 | page: MY_MARKETS,
22 | leadingTitle: 'Total Markets',
23 | leadingValue: makeNumber(Math.round(randomNum()), 'markets'),
24 | trailingTitle: 'Total Gain/Loss',
25 | trailingValue: makeNumber(randomNum(), ' ETH')
26 | },
27 | {
28 | label: 'Reports',
29 | link: links.myReportsLink,
30 | page: MY_REPORTS,
31 | leadingTitle: 'Total Reports',
32 | leadingValue: makeNumber(Math.round(randomNum()), 'reports'),
33 | trailingTitle: 'Total Gain/Loss',
34 | trailingValue: makeNumber(randomNum(), ' REP')
35 | }
36 | ];
37 |
--------------------------------------------------------------------------------
/src/selectors/portfolio-totals.js:
--------------------------------------------------------------------------------
1 | import makeNumber from 'utils/make-number';
2 |
3 | const randomSign = Math.random() < 0.5 ? -1 : 1;
4 |
5 | export default {
6 | netChange: makeNumber(randomSign * Math.random() * 10, ' ETH')
7 | };
8 |
--------------------------------------------------------------------------------
/src/selectors/portfolio.js:
--------------------------------------------------------------------------------
1 | import navItems from 'selectors/portfolio-nav-items';
2 | import totals from 'selectors/portfolio-totals';
3 | import positions from 'selectors/login-account-positions';
4 | import markets from 'selectors/login-account-markets';
5 | import reports from 'selectors/login-account-reports';
6 |
7 | export default {
8 | navItems,
9 | totals,
10 | positions,
11 | markets,
12 | reports
13 | };
14 |
--------------------------------------------------------------------------------
/src/selectors/positions-summary.js:
--------------------------------------------------------------------------------
1 | import makeNumber from 'utils/make-number';
2 | import { randomNum } from 'utils/random-number';
3 |
4 | export default {
5 | numPositions: makeNumber(randomNum(), 'Positions', true),
6 | qtyShares: makeNumber(randomNum(), 'shares'),
7 | purchasePrice: makeNumber(randomNum(), ' ETH'),
8 | realizedNet: makeNumber(randomNum(900), ' ETH'),
9 | unrealizedNet: makeNumber(randomNum(100), ' ETH'),
10 | totalNet: makeNumber(randomNum(), ' ETH')
11 | };
12 |
--------------------------------------------------------------------------------
/src/selectors/reportable-outcomes.js:
--------------------------------------------------------------------------------
1 | import { BINARY, CATEGORICAL } from 'modules/markets/constants/market-types';
2 |
3 | const reportableOutcomes = (type, outcomes) => {
4 | switch (type) {
5 | case BINARY:
6 | return [
7 | {
8 | id: '1',
9 | name: 'No'
10 | },
11 | {
12 | id: '2',
13 | name: 'Yes'
14 | }
15 | ];
16 | case CATEGORICAL:
17 | return outcomes;
18 | default:
19 | return [];
20 | }
21 | };
22 |
23 | export default reportableOutcomes;
24 |
--------------------------------------------------------------------------------
/src/selectors/scalar-share-denomination.js:
--------------------------------------------------------------------------------
1 | import { SHARE, MILLI_SHARE, MICRO_SHARE } from 'modules/market/constants/share-denominations';
2 |
3 | export default {
4 | markets: {
5 | 0: MILLI_SHARE
6 | },
7 | denominations: [
8 | {
9 | label: 'Share',
10 | value: SHARE
11 | },
12 | {
13 | label: 'mShare',
14 | value: MILLI_SHARE
15 | },
16 | {
17 | label: 'μShare',
18 | value: MICRO_SHARE
19 | }
20 | ],
21 | updateSelectedShareDenomination: (id, selection) => {
22 | require('../selectors').update({
23 | scalarMarketShareDenomination: {
24 | ...require('../selectors').scalarShareDenomination,
25 | markets: {
26 | ...require('../selectors').scalarShareDenomination.markets,
27 | [id]: selection
28 | }
29 | }
30 | });
31 | }
32 | };
33 |
--------------------------------------------------------------------------------
/src/selectors/search.js:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tinybike/augur-ui-react-components/742bdb50af36d36045678a2610d4b68e44638db6/src/selectors/search.js
--------------------------------------------------------------------------------
/src/selectors/selected-outcome.js:
--------------------------------------------------------------------------------
1 | export default {
2 | selectedOutcomeID: null,
3 | updateSelectedOutcome: (selectedOutcomeID) => {
4 | const selectors = require('../selectors');
5 |
6 | selectors.update({
7 | selectedOutcome: {
8 | ...selectors.selectedOutcome,
9 | selectedOutcomeID
10 | }
11 | });
12 | }
13 | };
14 |
--------------------------------------------------------------------------------
/src/selectors/settings.js:
--------------------------------------------------------------------------------
1 | export default {};
2 |
--------------------------------------------------------------------------------
/src/selectors/shares-purchased.js:
--------------------------------------------------------------------------------
1 | function randomShares(n) { return (n * Math.random()).toString(); }
2 |
3 | export default [{
4 | id: '123',
5 | outcomes: [{
6 | id: '1',
7 | shares: randomShares(10)
8 | }, {
9 | id: '2',
10 | shares: randomShares(1)
11 | }]
12 | }, {
13 | id: '456',
14 | outcomes: [{
15 | id: '1',
16 | shares: randomShares(10)
17 | }, {
18 | id: '2',
19 | shares: '0'
20 | },
21 | {
22 | id: '3',
23 | shares: '0'
24 | },
25 | {
26 | id: '4',
27 | shares: randomShares(100)
28 | },
29 | {
30 | id: '5',
31 | shares: randomShares(10)
32 | },
33 | {
34 | id: '6',
35 | shares: randomShares(10)
36 | }]
37 | }];
38 |
--------------------------------------------------------------------------------
/src/selectors/trade-commit-lock.js:
--------------------------------------------------------------------------------
1 | export default {
2 | isLocked: false
3 | };
4 |
--------------------------------------------------------------------------------
/src/selectors/transactions-totals.js:
--------------------------------------------------------------------------------
1 | export default {
2 | numWorking: 1,
3 | numPending: 0,
4 | numComplete: 3,
5 | numWorkingAndPending: 1,
6 | numTotal: 4,
7 | title: 'Transaction Working',
8 | shortTitle: 'Working'
9 | };
10 |
--------------------------------------------------------------------------------
/src/selectors/url.js:
--------------------------------------------------------------------------------
1 | export default '/';
2 |
--------------------------------------------------------------------------------
/src/styles.less:
--------------------------------------------------------------------------------
1 | // Core
2 | @import (less) '../node_modules/normalize.css/normalize.css';
3 | @import './modules/app/less/typography';
4 | @import './modules/app/less/responsive';
5 | @import './modules/app/less/colors';
6 | @import './modules/app/less/animations';
7 | @import './modules/app/less/borders';
8 | @import './modules/app/less/arrangement';
9 | @import './modules/app/less/layout';
10 | @import './modules/app/less/common';
11 |
12 | // Module Styles
13 | @import './modules/**/less/*';
14 |
--------------------------------------------------------------------------------
/src/utils/add-commas-to-number.js:
--------------------------------------------------------------------------------
1 | export default function (number) {
2 | let sides = [];
3 |
4 | sides = number.toString().split('.');
5 | sides[0] = sides[0].replace(/\B(?=(\d{3})+(?!\d))/g, ',');
6 |
7 | return sides.join('.');
8 | }
9 |
--------------------------------------------------------------------------------
/src/utils/debounce.js:
--------------------------------------------------------------------------------
1 | export default function debounce(func, wait) {
2 | let timeout;
3 | const realWait = wait || 250;
4 |
5 | return (...args) => {
6 | const context = this;
7 |
8 | const later = () => {
9 | timeout = null;
10 | func.apply(context, args);
11 | };
12 |
13 | const callNow = !timeout;
14 |
15 | clearTimeout(timeout);
16 | timeout = setTimeout(later, realWait);
17 | if (callNow) {
18 | func.apply(context, args);
19 | }
20 | };
21 | }
22 |
--------------------------------------------------------------------------------
/src/utils/empty-number.js:
--------------------------------------------------------------------------------
1 | function emptyNumber(denomination) {
2 | return {
3 | value: 0,
4 | formattedValue: 0,
5 | formatted: '-',
6 | roundedValue: 0,
7 | rounded: '-',
8 | minimized: '-',
9 | full: '-',
10 | denomination: denomination || ''
11 | };
12 | }
13 |
14 | export default emptyNumber;
15 |
--------------------------------------------------------------------------------
/src/utils/get-value.js:
--------------------------------------------------------------------------------
1 | // Gets value of a arbitrarily deeply nested value by key path
2 | // @params {Object} obj - parent object
3 | // @params {String} target - string of path `this.is.the.target`
4 | // @returns value - returns null is value is not found, otherwise, returns value
5 | function getValue(obj, target) {
6 | return target.split('.').reduce((o, x) => ((typeof o === 'undefined' || o === null) ? o : o[x]), obj);
7 | }
8 |
9 | export default getValue;
10 |
--------------------------------------------------------------------------------
/src/utils/make-date.js:
--------------------------------------------------------------------------------
1 | function makeDate(d) {
2 | const months = [
3 | 'Jan', 'Feb', 'Mar',
4 | 'Apr', 'May', 'Jun',
5 | 'Jul', 'Aug', 'Sep',
6 | 'Oct', 'Nov', 'Dec'
7 | ];
8 | const date = (d instanceof Date) ? d : new Date(0);
9 | return {
10 | value: date,
11 | formatted: `${months[d.getMonth()]} ${d.getDate()}, ${d.getFullYear()}`,
12 | full: d.toISOString()
13 | };
14 | }
15 |
16 | export default makeDate;
17 |
--------------------------------------------------------------------------------
/src/utils/make-number.js:
--------------------------------------------------------------------------------
1 | function makeNumber(num, denomination, omitSign, noRandom) {
2 | let rndNum = num;
3 | if (!noRandom || Math.round(num) !== num) {
4 | rndNum = Math.round(num * 10000) / 10000;
5 | }
6 |
7 | const o = {
8 | value: rndNum,
9 | formattedValue: rndNum,
10 | formatted: rndNum.toFixed(2),
11 | roundedValue: Math.round(rndNum),
12 | rounded: Math.round(rndNum).toFixed(2),
13 | minimized: rndNum.toFixed(0),
14 | denomination: denomination || ''
15 | };
16 | if (denomination === ' shares') {
17 | o.formatted = addBigUnitPostfix(rndNum);
18 | o.rounded = addBigUnitPostfix(rndNum);
19 | o.fullPrecision = rndNum.toString();
20 | }
21 |
22 | const neverShowPlusSign = true;
23 | if (!omitSign && !neverShowPlusSign) {
24 | if (o.value > 0) {
25 | o.formatted = `+${o.formatted}`;
26 | o.rounded = `+${o.rounded}`;
27 | o.minimized = `+${o.minimized}`;
28 | }
29 | }
30 |
31 | o.full = o.formatted + o.denomination;
32 |
33 | return o;
34 | }
35 |
36 | function addBigUnitPostfix(value) {
37 | let postfixed;
38 | if (value > 1000000000000) {
39 | postfixed = '> 1T';
40 | } else if (value > 10000000000) {
41 | postfixed = `${(value / 1000000000).toFixed(0)}B`;
42 | } else if (value > 10000000) {
43 | postfixed = `${(value / 1000000).toFixed(0)}M`;
44 | } else if (value > 10000) {
45 | postfixed = `${(value / 1000).toFixed(0)}K`;
46 | } else {
47 | postfixed = value.toFixed(2);
48 | }
49 | return postfixed;
50 | }
51 |
52 | export default makeNumber;
53 |
--------------------------------------------------------------------------------
/src/utils/random-number.js:
--------------------------------------------------------------------------------
1 | export const randomSign = () => (Math.random() > 0.5 ? 1 : -1);
2 | export const randomNum = (multiplier = 10) => Math.random() * multiplier * randomSign();
3 |
--------------------------------------------------------------------------------
/src/utils/scroll-top-on-change.js:
--------------------------------------------------------------------------------
1 | export default (url) => {
2 | if (url && url !== `${window.location.pathname}${window.location.search}`) {
3 | window.scroll(0, 0);
4 | window.history.pushState(null, null, url);
5 | }
6 | };
7 |
--------------------------------------------------------------------------------
/src/utils/share-denomination-label.js:
--------------------------------------------------------------------------------
1 | import { MICRO_SHARE, MILLI_SHARE, SHARE } from 'modules/market/constants/share-denominations';
2 |
3 | export default function (selectedDenomination, shareDenominations) {
4 | switch (selectedDenomination) {
5 | case (MICRO_SHARE): {
6 | const value = shareDenominations && shareDenominations.find(denomination => denomination.value === MICRO_SHARE);
7 | return (value && value.label) || 'μShares';
8 | }
9 | case (MILLI_SHARE): {
10 | const value = shareDenominations && shareDenominations.find(denomination => denomination.value === MILLI_SHARE);
11 | return (value && value.label) || 'mShares';
12 | }
13 | default:
14 | case (SHARE): {
15 | const value = shareDenominations && shareDenominations.find(denomination => denomination.value === SHARE);
16 | return (value && value.label) || 'Shares';
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/utils/should-component-update-pure.js:
--------------------------------------------------------------------------------
1 | export default function (nextProps, nextState) {
2 | return isShallowUnEqual(nextProps, this.props) || isShallowUnEqual(nextState, this.state);
3 | }
4 |
5 | export function shouldComponentUpdateLog(nextProps, nextState) {
6 | return isShallowUnEqual(nextProps, this.props, true) || isShallowUnEqual(nextState, this.state, true);
7 | }
8 |
9 | export function shouldComponentUpdateOnStateChangeOnly(nextProps, nextState) {
10 | return isShallowUnEqual(nextState, this.state);
11 | }
12 |
13 | function isShallowUnEqual(obj1, obj2, log) {
14 | // both arguments reference the same object
15 | if (obj1 === obj2) {
16 | return false;
17 | }
18 |
19 | // arguments are either not objects or undefined/null
20 | if (typeof obj1 !== 'object' || obj1 == null || typeof obj2 !== 'object' || obj2 == null) {
21 | return true;
22 | }
23 |
24 | const keysA = Object.keys(obj1);
25 | const keysB = Object.keys(obj2);
26 | const keysALen = keysA.length;
27 |
28 | // keys don't match
29 | if (keysALen !== keysB.length) {
30 | return true;
31 | }
32 |
33 | for (let i = 0; i < keysALen; i++) {
34 | // actual values are different + not functions
35 | if (obj1[keysA[i]] !== obj2[keysA[i]] && typeof obj1[keysA[i]] !== 'function') {
36 | log && console.log('------->', keysA[i], obj1[keysA[i]], obj2[keysA[i]]);
37 | return true;
38 | }
39 | }
40 |
41 | // nothing needs to be updated
42 | return false;
43 | }
44 |
--------------------------------------------------------------------------------
/test/assertions/active-view.js:
--------------------------------------------------------------------------------
1 | import { assert } from 'chai';
2 |
3 | export default function (activeView) {
4 | assert.isDefined(activeView, `activeView isn't defined`);
5 | assert.isString(activeView, `activeView isn't a string`);
6 | }
--------------------------------------------------------------------------------
/test/assertions/chat.js:
--------------------------------------------------------------------------------
1 | import { assert } from 'chai';
2 |
3 | export default function (chat) {
4 | assert.isDefined(chat, `chat isn't defined`);
5 | assert.isObject(chat, `chat isn't an object`);
6 |
7 | Object.keys(chat).forEach(room => {
8 | assert.isDefined(chat[room], `chat.${room} isn't defined`);
9 | assert.isObject(chat[room], `chat.${room} isn't an object`);
10 | });
11 |
12 | // TODO -- flesh these test out
13 | }
14 |
--------------------------------------------------------------------------------
/test/assertions/common/component-nav.js:
--------------------------------------------------------------------------------
1 | import { assert } from 'chai';
2 |
3 | export default function(nav, label = 'Component Nav Item') {
4 | describe(`${label} Shape`, () => {
5 | assert.isDefined(nav);
6 | assert.isObject(nav);
7 |
8 | assert.isDefined(nav.label, `${label}.label isn't defined`);
9 | assert.isString(nav.label, `${label}.label isn't a string`);
10 | });
11 | }
12 |
--------------------------------------------------------------------------------
/test/assertions/common/formatted-date.js:
--------------------------------------------------------------------------------
1 | import { assert } from 'chai';
2 |
3 | export default function (formattedDate, label = 'Formatted Date'){
4 | describe(`${label}`, () => {
5 | it(`should be formatted date`, () => {
6 | assert.isDefined(formattedDate.value, `value is not defined`);
7 | assert.instanceOf(formattedDate.value, Date, `value is not a date`);
8 | assert.isDefined(formattedDate.formatted, `formatted is not defined`);
9 | assert.isString(formattedDate.formatted, `formatted is not a string`);
10 | assert.isDefined(formattedDate.full, `full is not defined`);
11 | assert.isString(formattedDate.full, `full is not a string`);
12 | });
13 | });
14 | }
15 |
--------------------------------------------------------------------------------
/test/assertions/common/formatted-number.js:
--------------------------------------------------------------------------------
1 | import { assert } from 'chai';
2 |
3 | export default function (actual, label = 'Formatted Number') {
4 | describe(label, () => {
5 | it('should be formatted number', () => {
6 | assert.isDefined(actual.value, `'value' isn't defined`);
7 | assert.isNumber(actual.value, `'value' isn't a number`);
8 | assert.isDefined(actual.formattedValue, `'formattedValue' isn't defined`);
9 | assert.isNumber(actual.formattedValue, `'formattedValue' isn't a number`);
10 | assert.isDefined(actual.formatted, `'formatted' isn't defined`);
11 | assert.isString(actual.formatted, `'formatted' isn't a string`);
12 | assert.isDefined(actual.roundedValue, `'roundedValue' isn't defined`);
13 | assert.isNumber(actual.roundedValue, `'roundedValue' isn't a number`);
14 | assert.isDefined(actual.rounded, `'rounded' isn't defined`);
15 | assert.isString(actual.rounded, `'rounded' isn't a string`);
16 | assert.isDefined(actual.minimized, `'minimized' isn't defined`);
17 | assert.isString(actual.minimized, `'minimized' isn't a string`);
18 | assert.isDefined(actual.denomination, `'denomination' isn't defined`);
19 | assert.isString(actual.denomination, `'denomination' isn't a String`);
20 | assert.isDefined(actual.full, `'full' isn't defined`);
21 | assert.isString(actual.full, `'full' isn't a string`);
22 | });
23 | });
24 | };
25 |
--------------------------------------------------------------------------------
/test/assertions/common/initial-fair-prices.js:
--------------------------------------------------------------------------------
1 | import { assert } from 'chai';
2 |
3 | export default function (initialFairPrices, refObj){
4 | describe(`${refObj}'s initiaiFairPrices`, () => {
5 | describe('type', () => {
6 | it('should exist', () => {
7 | assert.isDefined(initialFairPrices.type, 'initialFairPrices.type is not defined');
8 | });
9 |
10 | it('should be a string', () => {
11 | assert.isString(initialFairPrices.type, 'initialFairPrices.type is not a string');
12 | });
13 | });
14 |
15 | describe('values', () => {
16 | it('should exist', () => {
17 | assert.isDefined(initialFairPrices.values, 'initialFairPrices.values is not defined');
18 | });
19 |
20 | it('should be an array', () => {
21 | assert.isArray(initialFairPrices.values, 'initialFairPrices.values is not an array');
22 | });
23 | });
24 |
25 | describe('raw', () => {
26 | it('should exist', () => {
27 | assert.isDefined(initialFairPrices.raw, 'initialFairPrices.raw is not defined');
28 | });
29 |
30 | it('should be an array', () => {
31 | assert.isArray(initialFairPrices.raw, 'initialFairPrices.raw is not an array');
32 | });
33 | });
34 | });
35 | }
--------------------------------------------------------------------------------
/test/assertions/common/link.js:
--------------------------------------------------------------------------------
1 | import { assert } from 'chai';
2 |
3 | export default function (link, label = 'Link') {
4 | describe(`${label} Shape`, () => {
5 | assert.isDefined(link);
6 | assert.isObject(link);
7 |
8 | it('href', () => {
9 | assert.isDefined(link.href);
10 | assert.isString(link.href);
11 | });
12 |
13 | it('onClick', () => {
14 | assert.isDefined(link.onClick);
15 | assert.isFunction(link.onClick);
16 | });
17 | });
18 | }
--------------------------------------------------------------------------------
/test/assertions/common/market-link.js:
--------------------------------------------------------------------------------
1 | import { assert } from 'chai';
2 |
3 | export default function (marketLink, label = 'marketLink') {
4 | describe(label, () => {
5 | it('should be market link', () => {
6 | assert.isDefined(marketLink, `'marketLink' is not defined`);
7 | assert.isObject(marketLink, `'marketLink' is not defined`);
8 |
9 | assert.isDefined(marketLink.text,`'text' is not defined`);
10 | assert.isString(marketLink.text, `'text' is not a string`);
11 |
12 | assert.isDefined(marketLink.className, `'className' is not defined`);
13 | assert.isString(marketLink.className, `'className' is not a string`);
14 |
15 | assert.isDefined(marketLink.onClick, `'onClick' is not defined`);
16 | assert.isFunction(marketLink.onClick, `'onClick' is not a function`);
17 | });
18 | });
19 | }
--------------------------------------------------------------------------------
/test/assertions/common/nav-item.js:
--------------------------------------------------------------------------------
1 | import { assert } from 'chai';
2 | import assertLink from '../../../test/assertions/common/link';
3 |
4 | export default function (navItem, label = 'Nav Item'){
5 | describe(`${label}' Shape`, () => {
6 | assert.isDefined(navItem);
7 | assert.isObject(navItem);
8 |
9 | it('label', () => {
10 | assert.isDefined(navItem.label);
11 | assert.isString(navItem.label);
12 | });
13 |
14 | it('link', () => {
15 | assertLink(navItem.link, 'portfolio.navItem.link');
16 | });
17 |
18 | it('page', () => {
19 | assert.isDefined(navItem.page);
20 | assert.isString(navItem.page);
21 | });
22 | });
23 | }
--------------------------------------------------------------------------------
/test/assertions/core-stats.js:
--------------------------------------------------------------------------------
1 | import { assert } from 'chai';
2 |
3 | export default function (coreStats) {
4 | assert.isDefined(coreStats, `'coreStats' was not defined as expected`);
5 | }
6 |
--------------------------------------------------------------------------------
/test/assertions/favorite-markets.js:
--------------------------------------------------------------------------------
1 | import { assert } from 'chai';
2 |
3 | export default function (positionsSummary) {
4 | // implement me
5 | };
6 |
7 |
--------------------------------------------------------------------------------
/test/assertions/is-transactions-working.js:
--------------------------------------------------------------------------------
1 | import { assert } from 'chai';
2 |
3 | export default function(isTransactionsWorking) {
4 | assert.isDefined(isTransactionsWorking, `isTransactionsWorking isn't defined`);
5 | assert.isBoolean(isTransactionsWorking, `isTransactionsWorking isn't a boolean`);
6 | }
7 |
--------------------------------------------------------------------------------
/test/assertions/keywords.js:
--------------------------------------------------------------------------------
1 | import { assert } from 'chai';
2 |
3 | export default function (keywords) {
4 | assert.isDefined(keywords, `keywords isn't defined`);
5 | assert.isObject(keywords, `keywords isn't an object`);
6 | assert.isDefined(keywords.value, `keywords.value isn't defined`);
7 | assert.isString(keywords.value, `keywords.value isn't a string`);
8 | assert.isDefined(keywords.onChangeKeywords, `keywords.onChangeKeywords isn't defined`);
9 | assert.isFunction(keywords.onChangeKeywords, `keywords.onChangeKeywords isn't a function`);
10 | }
11 |
--------------------------------------------------------------------------------
/test/assertions/links.js:
--------------------------------------------------------------------------------
1 | import { assert } from 'chai';
2 | import assertLink from '../../test/assertions/common/link';
3 |
4 |
5 | export default function(links) {
6 | describe('augur-ui-react-components links state', () => {
7 | assert.isDefined(links, `links isn't defined`);
8 | assert.isObject(links, `links isn't an object`);
9 |
10 | it('authLink', () => {
11 | assertLink(links.authLink, 'authLink');
12 | });
13 |
14 | it('marketsLink', () => {
15 | assertLink(links.marketsLink, 'marketsLink');
16 | });
17 |
18 | it('transactionsLink', () => {
19 | assertLink(links.transactionsLink, 'transactionsLink');
20 | });
21 |
22 | it('marketLink', () => {
23 | assertLink(links.marketLink, 'marketLink');
24 | });
25 |
26 | it('previousLink', () => {
27 | assertLink(links.previousLink, 'previousLink');
28 | });
29 |
30 | it('createMarketLink', () => {
31 | assertLink(links.createMarketLink, 'createMarketLink');
32 | });
33 |
34 | it('loginMessageLink', () => {
35 | assertLink(links.loginMessageLink, 'loginMessageLink');
36 | });
37 | });
38 | };
39 |
--------------------------------------------------------------------------------
/test/assertions/login-account-markets.js:
--------------------------------------------------------------------------------
1 | import { assert } from 'chai';
2 |
3 | export default function (loginAccountMarkets){
4 | describe(`augur-ui-react-components loginAccountMarket's shape`, () => {
5 | assert.isDefined(loginAccountMarkets);
6 | assert.isObject(loginAccountMarkets);
7 | });
8 | };
9 |
--------------------------------------------------------------------------------
/test/assertions/login-account-positions.js:
--------------------------------------------------------------------------------
1 | import { assert } from 'chai';
2 |
3 | export default function (loginAccountPositions){
4 | describe(`augur-ui-react-components loginAccountPositions' shape`, () => {
5 | assert.isDefined(loginAccountPositions);
6 | assert.isObject(loginAccountPositions);
7 |
8 | it('markets', () => {
9 | assert.isDefined(loginAccountPositions.markets);
10 | assert.isArray(loginAccountPositions.markets);
11 | });
12 |
13 | it('summary', () => {
14 | assert.isDefined(loginAccountPositions.summary);
15 | assert.isObject(loginAccountPositions.summary);
16 | });
17 | });
18 | };
--------------------------------------------------------------------------------
/test/assertions/login-account-reports.js:
--------------------------------------------------------------------------------
1 | import { assert } from 'chai';
2 |
3 | export default function (loginAccountReports){
4 | describe(`augur-ui-react-components loginAccountReports' shape`, () => {
5 | assert.isDefined(loginAccountReports);
6 | assert.isObject(loginAccountReports);
7 |
8 | it('reports', () => {
9 | assert.isDefined(loginAccountReports.reports);
10 | assert.isArray(loginAccountReports.reports);
11 | });
12 |
13 | it('summary', () => {
14 | assert.isDefined(loginAccountReports.summary);
15 | assert.isObject(loginAccountReports.summary);
16 | });
17 | });
18 | };
19 |
--------------------------------------------------------------------------------
/test/assertions/market-data-age.js:
--------------------------------------------------------------------------------
1 | import {assert} from 'chai';
2 |
3 | export default function (marketDataAge) {
4 | describe('augur-ui-react-components marketDataAge', () => {
5 | it('marketDataAge', () => {
6 | assert.isObject(marketDataAge);
7 | });
8 |
9 | it('marketDataAge.lastUpdatedBefore', () => {
10 | assert.isString(marketDataAge.lastUpdatedBefore);
11 | });
12 |
13 | it('marketDataAge.isMarketDataLoading', () => {
14 | assert.isBoolean(marketDataAge.isMarketDataLoading);
15 | });
16 | });
17 | }
18 |
--------------------------------------------------------------------------------
/test/assertions/market-data-nav-items.js:
--------------------------------------------------------------------------------
1 | import { assert } from 'chai';
2 |
3 | import assertComponentNavItem from './common/component-nav';
4 |
5 | export default function (marketDataNavItems) {
6 | assert.isDefined(marketDataNavItems, `marketDataNavItems isn't defined`);
7 | assert.isObject(marketDataNavItems, `marketDataNavItems isn't an object`);
8 |
9 | Object.keys(marketDataNavItems).forEach(navItem => {
10 | assertComponentNavItem(marketDataNavItems[navItem], navItem);
11 | });
12 | }
13 |
--------------------------------------------------------------------------------
/test/assertions/market-data-updater.js:
--------------------------------------------------------------------------------
1 | import {assert} from 'chai';
2 |
3 | export default function (marketDataUpdater) {
4 | describe('augur-ui-react-components marketDataUpdater', () => {
5 | it('marketDataUpdater', () => {
6 | assert.isObject(marketDataUpdater);
7 | });
8 |
9 | it('marketDataUpdater.update', () => {
10 | assert.isFunction(marketDataUpdater.update);
11 | });
12 |
13 | it('marketDataUpdater.updateIntervalSecs', () => {
14 | assert.isNumber(marketDataUpdater.updateIntervalSecs);
15 | });
16 | });
17 | }
18 |
--------------------------------------------------------------------------------
/test/assertions/market-reporting-nav-items.js:
--------------------------------------------------------------------------------
1 | import { assert } from 'chai';
2 |
3 | import assertComponentNavItem from './common/component-nav';
4 |
5 | export default function (marketReportingNavItems) {
6 | assert.isDefined(marketReportingNavItems, `marketReportingNavItems isn't defined`);
7 | assert.isObject(marketReportingNavItems, `marketReportingNavItems isn't an object`);
8 |
9 | Object.keys(marketReportingNavItems).forEach(navItem => {
10 | assertComponentNavItem(marketReportingNavItems[navItem], navItem);
11 | });
12 | }
13 |
--------------------------------------------------------------------------------
/test/assertions/market-user-data-nav-items.js:
--------------------------------------------------------------------------------
1 | import { assert } from 'chai';
2 |
3 | import assertComponentNavItem from './common/component-nav';
4 |
5 | export default function (marketUserDataNavItems) {
6 | assert.isDefined(marketUserDataNavItems, `marketUserDataNavItems isn't defined`);
7 | assert.isObject(marketUserDataNavItems, `marketUserDataNavItems isn't an object`);
8 |
9 | Object.keys(marketUserDataNavItems).forEach(navItem => {
10 | assertComponentNavItem(marketUserDataNavItems[navItem], navItem);
11 | });
12 | }
13 |
--------------------------------------------------------------------------------
/test/assertions/markets-header.js:
--------------------------------------------------------------------------------
1 | import { assert } from 'chai';
2 |
3 | export default function(marketsHeader) {
4 | assert.isDefined(marketsHeader, `marketsHeader isn't defined`);
5 | assert.isObject(marketsHeader, `marketsHeader isn't an object`);
6 | }
7 |
--------------------------------------------------------------------------------
/test/assertions/markets-totals.js:
--------------------------------------------------------------------------------
1 | import { assert } from 'chai';
2 |
3 | export default function(marketsTotals) {
4 | assert.isDefined(marketsTotals, `marketsTotals isn't defined`);
5 | assert.isObject(marketsTotals, `marketsTotals isn't an object`);
6 |
7 | checkDefinedAndNumber(marketsTotals.numAll, `numAll`);
8 | checkDefinedAndNumber(marketsTotals.numFavorites, `numFavorites`);
9 | checkDefinedAndNumber(marketsTotals.numFiltered, `numFiltered`);
10 | checkDefinedAndNumber(marketsTotals.numPendingReports, `numPendingReports`);
11 | checkDefinedAndNumber(marketsTotals.numUnpaginated, `numUnpaginated`);
12 | }
13 |
14 |
15 | function checkDefinedAndNumber(obj, name) {
16 | assert.isDefined(obj, `marketsTotals.${name} isn't defined`);
17 | assert.isNumber(obj, `marketsTotals.${name} isn't a number`);
18 | }
19 |
--------------------------------------------------------------------------------
/test/assertions/markets.js:
--------------------------------------------------------------------------------
1 | import { assert } from 'chai';
2 |
3 | export default function (markets) {
4 | assert.isDefined(markets, `markets is not defined`);
5 | assert.isArray(markets, `markets isn't an array`);
6 | }
7 |
--------------------------------------------------------------------------------
/test/assertions/my-markets-summary.js:
--------------------------------------------------------------------------------
1 | import { assert } from 'chai';
2 |
3 | export default function (myMarketsSummary){
4 | describe(`augur-ui-react-components myMarketsSummary's shape`, () => {
5 | assert.isDefined(myMarketsSummary);
6 | assert.isObject(myMarketsSummary);
7 |
8 | assertMyMarketsSummary(myMarketsSummary);
9 | });
10 | };
11 |
12 | export function assertMyMarketsSummary(summary){
13 | describe(`summary's shape`, () => {
14 | assert.isDefined(summary);
15 | assert.isObject(summary);
16 |
17 | it('numMarkets', () => {
18 | assert.isDefined(summary.numMarkets);
19 | assert.isNumber(summary.numMarkets);
20 | });
21 | });
22 | };
23 |
--------------------------------------------------------------------------------
/test/assertions/my-reports-summary.js:
--------------------------------------------------------------------------------
1 | import { assert } from 'chai';
2 | import assertFormattedNumber from '../../test/assertions/common/formatted-number';
3 |
4 | export default function (reportsSummary) {
5 | assert.isDefined(reportsSummary, `reportsSummary isn't defined`);
6 | assert.isObject(reportsSummary, `reportsSummary isn't an object`);
7 |
8 | assertFormattedNumber(reportsSummary.numReports, 'reportsSummary.numReports');
9 | assertFormattedNumber(reportsSummary.netRep, 'reportsSummary.netRep');
10 | };
11 |
12 |
--------------------------------------------------------------------------------
/test/assertions/order-cancellation.js:
--------------------------------------------------------------------------------
1 | import { assert } from 'chai';
2 |
3 | export default function (orderCancellation) {
4 | describe('augur-ui-react-components orderCancellation', () => {
5 | it('orderCancellation', () => {
6 | assert.isObject(orderCancellation);
7 | });
8 |
9 | it('orderCancellation.cancelOrder', () => {
10 | assert.isFunction(orderCancellation.cancelOrder);
11 | });
12 |
13 | it('orderCancellation.abortCancelOrderConfirmation', () => {
14 | assert.isFunction(orderCancellation.abortCancelOrderConfirmation);
15 | });
16 |
17 | it('orderCancellation.showCancelOrderConfirmation', () => {
18 | assert.isFunction(orderCancellation.showCancelOrderConfirmation);
19 | });
20 |
21 | it('orderCancellation.cancellationStatuses', () => {
22 | assert.isObject(orderCancellation.cancellationStatuses);
23 | assert.deepEqual(orderCancellation.cancellationStatuses, {
24 | CANCELLATION_CONFIRMATION: 'CANCELLATION_CONFIRMATION',
25 | CANCELLING: 'CANCELLING',
26 | CANCELLED: 'CANCELLED',
27 | CANCELLATION_FAILED: 'CANCELLATION_FAILED'
28 | });
29 | });
30 | });
31 | };
32 |
--------------------------------------------------------------------------------
/test/assertions/outcome-trade-nav-items.js:
--------------------------------------------------------------------------------
1 | import { assert } from 'chai';
2 |
3 | import assertComponentNavItem from './common/component-nav';
4 |
5 | export default function (marketDataNavItems) {
6 | assert.isDefined(marketDataNavItems, `marketDataNavItems isn't defined`);
7 | assert.isObject(marketDataNavItems, `marketDataNavItems isn't an object`);
8 |
9 | Object.keys(marketDataNavItems).forEach(navItem => {
10 | assertComponentNavItem(marketDataNavItems[navItem], navItem);
11 | });
12 | }
13 |
--------------------------------------------------------------------------------
/test/assertions/portfolio-nav-items.js:
--------------------------------------------------------------------------------
1 | import { assert } from 'chai';
2 |
3 | import assertNavItem from './common/nav-item';
4 |
5 | export default function (portfolioNavItems){
6 | describe(`augur-ui-react-components portfolio's navItems state`, () => {
7 | assert.isDefined(portfolioNavItems);
8 | assert.isArray(portfolioNavItems);
9 |
10 | portfolioNavItems.forEach(navItem => { assertNavItem(navItem, 'portfolio.navItem') });
11 | });
12 | };
--------------------------------------------------------------------------------
/test/assertions/portfolio-summaries.js:
--------------------------------------------------------------------------------
1 | import { assert } from 'chai';
2 |
3 | export default function (portfolioSummaries){
4 | describe(`augur-ui-react-components portfolio's summaries shape`, () => {
5 | assert.isDefined(portfolioSummaries);
6 | assert.isArray(portfolioSummaries);
7 |
8 | portfolioSummaries.forEach(summary => { assertSummary(summary) });
9 | });
10 | }
11 |
12 | function assertSummary(summary){
13 | describe(`summary's shape`, () => {
14 | it('label', () => {
15 | assert.isDefined(summary.label);
16 | assert.isString(summary.label);
17 | });
18 |
19 | it('value', () => {
20 | assert.isDefined(summary.value);
21 | assert.isString(summary.value);
22 | });
23 | });
24 | };
25 |
--------------------------------------------------------------------------------
/test/assertions/portfolio-totals.js:
--------------------------------------------------------------------------------
1 | import { assert } from 'chai';
2 |
3 | import assertFormattedNumber from '../../test/assertions/common/formatted-number';
4 |
5 | export default function (portfolioTotals){
6 | describe(`augur-ui-react-components portfolioTotals' shape`, () => {
7 | assert.isDefined(portfolioTotals);
8 | assert.isObject(portfolioTotals);
9 |
10 | it('net', () => {
11 | assert.isDefined(portfolioTotals.netChange);
12 | assertFormattedNumber(portfolioTotals.netChange, 'portfolio.totals.netChange');
13 | });
14 | });
15 | };
--------------------------------------------------------------------------------
/test/assertions/portfolio.js:
--------------------------------------------------------------------------------
1 | import { assert } from 'chai';
2 |
3 | export default function (portfolio){
4 | describe('augur-ui-react-components portfolio state', () => {
5 | assert.isDefined(portfolio);
6 | assert.isObject(portfolio);
7 | });
8 | };
--------------------------------------------------------------------------------
/test/assertions/positions-summary.js:
--------------------------------------------------------------------------------
1 | import { assert } from 'chai';
2 | import assertFormattedNumber from '../../test/assertions/common/formatted-number';
3 |
4 | export default function (positionsSummary) {
5 | assert.isDefined(positionsSummary, `positionsSummary isn't defined`);
6 | assert.isObject(positionsSummary, `positionsSummary isn't an object`);
7 |
8 | assertFormattedNumber(positionsSummary.numPositions, 'positionsSummary.numPositions');
9 | assertFormattedNumber(positionsSummary.purchasePrice, 'positionsSummary.purchasePrice');
10 | assertFormattedNumber(positionsSummary.qtyShares, 'positionsSummary.qtyShares');
11 | assertFormattedNumber(positionsSummary.realizedNet, 'positionsSummary.realizedNet');
12 | assertFormattedNumber(positionsSummary.unrealizedNet, 'positionsSummary.unrealizedNet');
13 | assertFormattedNumber(positionsSummary.totalNet, 'positionsSummary.totalNet');
14 | };
15 |
16 |
--------------------------------------------------------------------------------
/test/assertions/reportable-outcomes.js:
--------------------------------------------------------------------------------
1 | import { assert } from 'chai';
2 |
3 | export default function (reportableOutcomes) {
4 | describe(`augur-ui-react-components reportableOutcomes' shape`, () => {
5 | assert.isDefined(reportableOutcomes, `'reportableOutcomes' is not defined`);
6 | assert.isArray(reportableOutcomes, `'reportableOutcomes' is not an array`);
7 |
8 | reportableOutcomes.forEach(outcome => {
9 | it('id', () => {
10 | assert.isDefined(outcome.id, `reportableOutcomes' id is not defined`);
11 | assert.isString(outcome.id, `reportableOutcomes' id is not a string`);
12 | });
13 |
14 | it('name', () => {
15 | assert.isDefined(outcome.name, `reportableOutcomes' name is not defined`);
16 | assert.isString(outcome.name, `reportableOutcomes' name is not a string`);
17 | });
18 | });
19 | });
20 | };
--------------------------------------------------------------------------------
/test/assertions/scalar-share-denomination.js:
--------------------------------------------------------------------------------
1 | import { assert } from 'chai';
2 |
3 | export default function (scalarShareDenomination) {
4 | assert.isDefined(scalarShareDenomination, `scalarShareDenomination isn't defined`);
5 | assert.isObject(scalarShareDenomination, `scalarShareDenomination isn't an object`);
6 |
7 |
8 | describe('scalarShareDenomination.markets', () => {
9 | const markets = scalarShareDenomination.markets;
10 |
11 | assert.isDefined(markets, `markets isn't defined`);
12 | assert.isObject(markets, `markets isn't an object`);
13 |
14 | Object.keys(markets || {}).forEach(market => {
15 | assert.isDefined(markets[market], `markets.market isn't defined`);
16 | assert.isString(markets[market], `markets.market isn't a string`);
17 | });
18 |
19 | });
20 |
21 | describe('scalarShareDenomination.denominations', () => {
22 | const denominations = scalarShareDenomination.denominations;
23 |
24 | assert.isDefined(denominations, `denominations isn't defined`);
25 | assert.isArray(denominations, `denominations isn't an array`);
26 |
27 | (denominations || []).forEach(denomination => {
28 | assert.isDefined(denomination, `denominations.denomination isn't defined`);
29 | assert.isObject(denomination, `denominations.denomination isn't an object`);
30 |
31 | assert.isDefined(denomination.label, `denomination.label isn't defined`);
32 | assert.isString(denomination.label, `denomination.label isn't a string`);
33 |
34 | assert.isDefined(denomination.value, `denomination.value isn't defined`);
35 | assert.isString(denomination.value, `denomination.value isn't a string`);
36 | });
37 | });
38 |
39 | assert.isDefined(scalarShareDenomination.updateSelectedShareDenomination, `updateSelectedShareDenomination isn't defined`);
40 | assert.isFunction(scalarShareDenomination.updateSelectedShareDenomination, `updateSelectedShareDenomination isn't a function`);
41 | }
42 |
--------------------------------------------------------------------------------
/test/assertions/search-sort.js:
--------------------------------------------------------------------------------
1 | import { assert } from 'chai';
2 |
3 | export default function(searchSort) {
4 | assert.isDefined(searchSort, `searchSort isn't defined`);
5 | assert.isObject(searchSort, `searchSort isn't an object`);
6 | assert.isDefined(searchSort.onChangeSort, `searchSort.onChangeSort isn't defined`);
7 | assert.isFunction(searchSort.onChangeSort, `searchSort.onChangeSort isn't a function`);
8 | assertionSelectedSort(searchSort.selectedSort);
9 | assertionSortOptions(searchSort.sortOptions);
10 | }
11 |
12 | function assertionSelectedSort(actual) {
13 | assert.isDefined(actual, `selectedSort isn't defined`);
14 | assert.isObject(actual, `selectedSort isn't an Object`);
15 | assert.isDefined(actual.prop, `selectedSort.prop isn't defined`);
16 | assert.isString(actual.prop, `selectedSort.prop isn't a string`);
17 | assert.isDefined(actual.isDesc, `selectedSort.isDesc isn't defined`);
18 | assert.isBoolean(actual.isDesc, `selectedSort.isDesc isn't a boolean`);
19 | }
20 |
21 | function assertionSortOptions(actual) {
22 | assert.isDefined(actual, `sortOptions isn't defined`);
23 | assert.isArray(actual, `sortOptions isn't an array`);
24 |
25 | assert.isDefined(actual[0], `sortOptions[0] doesn't exist`);
26 | assert.isObject(actual[0], `sortOptions[0] isn't an object`);
27 | assert.isDefined(actual[0].label, `sortOptions[0].label isn't defined`);
28 | assert.isString(actual[0].label, `sortOptions[0].label isn't a string`);
29 | assert.isDefined(actual[0].value, `sortOptions[0].value isn't defined`);
30 | assert.isString(actual[0].value, `sortOptions[0].value isn't a string`);
31 | }
32 |
33 |
--------------------------------------------------------------------------------
/test/assertions/selected-outcome.js:
--------------------------------------------------------------------------------
1 | import { assert } from 'chai';
2 |
3 | export default function (selectedOutcome) {
4 | assert.isObject(selectedOutcome, `selectedOutcome isn't an object`);
5 | assert.isDefined(selectedOutcome.selectedOutcomeID, `selectedOutcome isn't defined`);
6 | assert.isFunction(selectedOutcome.updateSelectedOutcome, `updateSelectedOutcome isn't a function`);
7 | assert.isDefined(selectedOutcome.updateSelectedOutcome, `updateSelectedOutcome isn't defined`);
8 | };
9 |
10 |
--------------------------------------------------------------------------------
/test/assertions/selected-user-open-orders-group.js:
--------------------------------------------------------------------------------
1 | import { assert } from 'chai';
2 |
3 | export default function (selectedUserOpenOrdersGroup) {
4 | describe('augur-ui-react-components selectedUserOpenOrdersGroup', () => {
5 | it('should exist', () => {
6 | assert.isDefined(selectedUserOpenOrdersGroup, `selectedUserOpenOrdersGroup is empty.`);
7 | });
8 |
9 | it('should be object', () => {
10 | assert.isObject(selectedUserOpenOrdersGroup, `selectedUserOpenOrdersGroup is not object.`);
11 | });
12 |
13 | describe('selectedUserOpenOrdersGroupID', () => {
14 | it('should exist', () => {
15 | assert.isDefined(selectedUserOpenOrdersGroup.selectedUserOpenOrdersGroupID, `selectedUserOpenOrdersGroupID is not defined.`);
16 | });
17 | });
18 |
19 | describe('updateSelectedUserOpenOrdersGroup', () => {
20 | it('should be function', () => {
21 | assert.isFunction(selectedUserOpenOrdersGroup.updateSelectedUserOpenOrdersGroup, `updateSelectedUserOpenOrdersGroup is not function.`);
22 | });
23 | });
24 | });
25 | };
26 |
--------------------------------------------------------------------------------
/test/assertions/settings.js:
--------------------------------------------------------------------------------
1 | import { assert } from 'chai';
2 |
3 | export default function (settings) {
4 | assert.isDefined(settings, `settings isn't defined`);
5 | assert.isObject(settings, `settings isn't an object`);
6 |
7 | // TODO -- needs to be fleshed out
8 | }
9 |
--------------------------------------------------------------------------------
/test/assertions/site-header.js:
--------------------------------------------------------------------------------
1 | import { assert } from 'chai';
2 | import assertLoginAccount from './login-account';
3 | import assertActivePage from './active-view';
4 | import assertPositionsSummary from './positions-summary';
5 | import assertTransactionsTotals from './transactions-totals';
6 | import assertIsTransactionsWorking from './is-transactions-working';
7 |
8 | export default function(siteHeader) {
9 | assert.isDefined(siteHeader, `siteHeader isn't defined`);
10 | assert.isObject(siteHeader, `siteHeader isn't a object`);
11 | assertLoginAccount(siteHeader.loginAccount);
12 | assertActivePage(siteHeader.activePage);
13 | assertPositionsSummary(siteHeader.positionsSummary);
14 | assertTransactionsTotals(siteHeader.transactionsTotals);
15 | assertIsTransactionsWorking(siteHeader.isTransactionsWorking);
16 | }
17 |
--------------------------------------------------------------------------------
/test/assertions/tags.js:
--------------------------------------------------------------------------------
1 | import { assert } from 'chai';
2 |
3 | export default function (tags) {
4 |
5 | assert.isDefined(tags, `filters isn't defined`);
6 | assert.isArray(tags, `filters isn't an array`);
7 |
8 | tags.forEach((tag) => {
9 | assert.isDefined(tag, `[0].options[0] isn't defined`);
10 | assert.isObject(tag, `[0].options[0] isn't a object`);
11 |
12 | assert.isDefined(tag.name, `[0].options[0].name isn't defined`);
13 | assert.isString(tag.name, `[0].options[0].name isn't a string`);
14 |
15 | assert.isDefined(tag.value, `[0].options[0].value isn't defined`);
16 | assert.isString(tag.value, `[0].options[0].value isn't a string`);
17 |
18 | assert.isDefined(tag.numMatched, `[0].options[0].numMatched isn't defined`);
19 | assert.isNumber(tag.numMatched, `[0].options[0].numMatched isn't a number`);
20 |
21 | assert.isDefined(tag.isSelected, `[0].options[0].isSelected isn't defined`);
22 | assert.isBoolean(tag.isSelected, `[0].options[0].isSelected isn't a boolean`);
23 |
24 | assert.isDefined(tag.onClick, `[0].options[0].onClick isn't defined`);
25 | assert.isFunction(tag.onClick, `[0].options[0].onClick isn't a function`);
26 | });
27 | }
28 |
--------------------------------------------------------------------------------
/test/assertions/trade-commit-lock.js:
--------------------------------------------------------------------------------
1 | import { assert } from 'chai';
2 |
3 | export default function (tradeCommitLock) {
4 | assert.isDefined(tradeCommitLock, 'tradeCommitLock is not defined');
5 | assert.isObject(tradeCommitLock, 'tradeCommitLock is not an object');
6 |
7 | it('isLocked', () => {
8 | assert.isDefined(tradeCommitLock.isLocked, `'tradeCommitLock.isLocked' is not defined`);
9 | assert.isBoolean(tradeCommitLock.isLocked, `'tradeCommitLock.isLocked' is not a boolean`);
10 | });
11 | }
--------------------------------------------------------------------------------
/test/assertions/transactions-totals.js:
--------------------------------------------------------------------------------
1 | import { assert } from 'chai';
2 |
3 | export default function(transactionsTotals) {
4 | assert.isObject(transactionsTotals);
5 |
6 | assert.isString(transactionsTotals.title);
7 | assert.isString(transactionsTotals.shortTitle);
8 |
9 | assert.isNumber(transactionsTotals.numWorking);
10 | assert.isNumber(transactionsTotals.numPending);
11 | assert.isNumber(transactionsTotals.numComplete);
12 | assert.isNumber(transactionsTotals.numWorkingAndPending);
13 | assert.isNumber(transactionsTotals.numTotal);
14 | }
15 |
--------------------------------------------------------------------------------
/test/assertions/transactions.js:
--------------------------------------------------------------------------------
1 | import { assert } from 'chai';
2 |
3 | export default function (transactions) {
4 | assert.isDefined(transactions, `transactions isn't defined`);
5 | assert.isArray(transactions, `transactions isn't an array`);
6 |
7 | transactions.forEach(transaction => assertTransaction(transactions[0]));
8 | }
9 |
10 | function assertTransaction(transaction) {
11 | assert.isString(transaction.id);
12 | assert.isString(transaction.type);
13 | assert.isString(transaction.status);
14 | if (transaction.data) {
15 | assert.isObject(transaction);
16 | }
17 | }
--------------------------------------------------------------------------------
/test/assertions/url.js:
--------------------------------------------------------------------------------
1 | import { assert } from 'chai';
2 |
3 | export default function (url) {
4 | assert.isDefined(url, `url isn't defined`);
5 | assert.isString(url, `url isn't a string`);
6 | }
--------------------------------------------------------------------------------
/test/mocha.opts:
--------------------------------------------------------------------------------
1 | --compilers js:babel-register
2 | --recursive
3 |
--------------------------------------------------------------------------------
/test/selectors-test.js:
--------------------------------------------------------------------------------
1 | import selectors from '../src/selectors';
2 | import assertions from '../src/assertions';
3 |
4 | Object.defineProperty(selectors, 'render', {
5 | value: () => console.log('fake render'),
6 | enumerable: false
7 | });
8 |
9 | Object.keys(selectors).forEach(selectorKey => {
10 | console.log('-->', selectorKey);
11 | if (typeof assertions[selectorKey] !== 'function') {
12 | throw new Error(`missing assertion ${selectorKey}`)
13 | }
14 | assertions[selectorKey](selectors[selectorKey]);
15 | });
16 |
--------------------------------------------------------------------------------