diff --git a/.babelrc b/.babelrc
deleted file mode 100644
index 620b7071f8..0000000000
--- a/.babelrc
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "presets": ["stage-2", "react", "es2015"]
-}
diff --git a/.editorconfig b/.editorconfig
deleted file mode 100644
index ca7a3d5aa0..0000000000
--- a/.editorconfig
+++ /dev/null
@@ -1,10 +0,0 @@
-root = true
-
-[*]
-end_of_line = lf
-insert_final_newline = true
-
-[*.{js,jsx}]
-charset = utf-8
-indent_style = space
-indent_size = 2
diff --git a/.env_example b/.env_example
new file mode 100644
index 0000000000..2781cf6af5
--- /dev/null
+++ b/.env_example
@@ -0,0 +1 @@
+VITE_API_HOST=https://api.opendota.com
\ No newline at end of file
diff --git a/.eslintignore b/.eslintignore
deleted file mode 100644
index aad2e90496..0000000000
--- a/.eslintignore
+++ /dev/null
@@ -1,3 +0,0 @@
-node_modules
-build
-webpack.config.js
diff --git a/.eslintrc.json b/.eslintrc.json
deleted file mode 100644
index 33948f3120..0000000000
--- a/.eslintrc.json
+++ /dev/null
@@ -1,11 +0,0 @@
-{
- "parserOptions": {
- "ecmaFeatures": { "experimentalObjectRestSpread": true }
- },
- "extends": "airbnb",
- "rules": {
- "react/prop-types": 0,
- "max-len": ["error", 150],
- "no-shadow": 0
- }
-}
diff --git a/.github/ISSUE_TEMPLATE/Bug_report.md b/.github/ISSUE_TEMPLATE/Bug_report.md
new file mode 100644
index 0000000000..e59f5c0f9d
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/Bug_report.md
@@ -0,0 +1,29 @@
+---
+name: 🐛 Bug Report
+about: If something isn't working as expected 🤔.
+---
+
+**Current Behavior**
+A clear and concise description of the behavior.
+
+**Expected behavior/code**
+A clear and concise description of what you expected to happen (or code).
+
+**Console Output**
+Please provide your browsers console log if possible. Most browsers will open the console via F12.
+
+```
+please paste console output in here
+```
+
+**Environment**
+
+- Browser Version: [e.g. Chrome 64.0, Firefox 57, Edge 17]
+- OS: [e.g. OSX 10.13.4, Windows 10 or Linux Distribution]
+
+**Possible Solution**
+
+
+
+**Additional context/Screenshots**
+Add any other context about the problem here. If applicable, add screenshots to help explain.
diff --git a/.github/ISSUE_TEMPLATE/Feature_request.md b/.github/ISSUE_TEMPLATE/Feature_request.md
new file mode 100644
index 0000000000..83d138eb98
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/Feature_request.md
@@ -0,0 +1,17 @@
+---
+name: 🚀 Feature Request
+about: I have a suggestion (and might want to implement 🙂)!
+---
+
+**Is your feature request related to a problem? Please describe.**
+A clear and concise description of what the problem is. Ex. I have an issue when [...]
+
+**Describe the solution you'd like**
+A clear and concise description of what you want to happen. Add any considered drawbacks.
+
+**Describe alternatives you've considered**
+A clear and concise description of any alternative solutions or features you've considered.
+
+**Teachability, Documentation, Adoption, Migration Strategy**
+If you can, explain how users will be able to use this and possibly write out a version the docs.
+Maybe a screenshot or design?
diff --git a/.github/ISSUE_TEMPLATE/Support.md b/.github/ISSUE_TEMPLATE/Support.md
new file mode 100644
index 0000000000..3e41358dce
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/Support.md
@@ -0,0 +1,12 @@
+---
+name: 🤗 Support Question
+about: If you have a question 💬, please check out our Discord!
+---
+
+**Explain your question as detailed as possible**
+
+I need help with...
+
+---
+
+If you have a support request or question please also check our Discord Server: https://discord.gg/opendota
diff --git a/.github/browserstack_logo.png b/.github/browserstack_logo.png
new file mode 100644
index 0000000000..6428883808
Binary files /dev/null and b/.github/browserstack_logo.png differ
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
new file mode 100644
index 0000000000..1bf21e6625
--- /dev/null
+++ b/.github/dependabot.yml
@@ -0,0 +1,7 @@
+version: 2
+updates:
+ - package-ecosystem: npm
+ directory: "/"
+ schedule:
+ interval: daily
+ open-pull-requests-limit: 10
diff --git a/.github/workflows/nodejs.yml b/.github/workflows/nodejs.yml
new file mode 100644
index 0000000000..54bd8717c1
--- /dev/null
+++ b/.github/workflows/nodejs.yml
@@ -0,0 +1,37 @@
+# This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node
+# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
+
+name: Node.js CI
+
+on:
+ push:
+ branches: [master]
+ pull_request:
+ branches: [master]
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v2
+ - name: Use Node.js
+ uses: actions/setup-node@v1
+ with:
+ node-version: 24.x
+ - run: npm ci
+ - run: npm run build --if-present
+ env:
+ CI: true
+ NODE_ENV: production
+ - run: cp build/index.html build/404.html
+ - name: Push to remote
+ if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }}
+ run: |
+ git config --global user.name "github-actions[bot]"
+ git config --global user.email "opendota+github-actions[bot]@users.noreply.github.com"
+ rm .gitignore
+ git checkout -b release
+ git add --all
+ git commit --quiet -m "Built from ${{ github.sha }}"
+ git push origin release -f
diff --git a/.gitignore b/.gitignore
index cfada684a4..0333e784a6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,10 @@
node_modules
+.vscode
.idea
npm-debug.log
build
.DS_STORE
+*.swp
+.env
+yarn.lock
+.vite
diff --git a/.nojekyll b/.nojekyll
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 2db1c96897..0000000000
--- a/.travis.yml
+++ /dev/null
@@ -1,15 +0,0 @@
-language: node_js
-node_js:
-- 'node'
-notifications:
- email:
- - howardc93@gmail.com
- - aqc2109@columbia.edu
-script:
-- npm run build
-deploy:
- provider: script
- skip_cleanup: true
- on:
- branch: master
- script: bash deploy.sh
diff --git a/404.html b/404.html
deleted file mode 120000
index 64233a9e95..0000000000
--- a/404.html
+++ /dev/null
@@ -1 +0,0 @@
-index.html
\ No newline at end of file
diff --git a/CNAME b/CNAME
deleted file mode 100644
index 7cc9cf13ed..0000000000
--- a/CNAME
+++ /dev/null
@@ -1 +0,0 @@
-ui.yasp.co
\ No newline at end of file
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000000..815e74f939
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2020 The OpenDota Project
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/README.md b/README.md
index cbd142d28e..8d7d5a52ff 100644
--- a/README.md
+++ b/README.md
@@ -1,32 +1,40 @@
-# ui
-[](https://travis-ci.org/yasp-dota/ui)
+# opendota-web
-Web UI for YASP. This is a SPA (single-page application) built with React, Redux, and React-Router.
+[](https://www.codetriage.com/odota/web)
-Quickstart
-----
-* Install Node.js (6.0.0 or greater) (on Ubuntu, `curl -sL https://deb.nodesource.com/setup_6.x | sudo -E bash - && sudo apt-get install -y nodejs`)
-* `npm install`
-* `npm start`
-* Visit port 8080 on your development machine. You can configure the port used by webpack-dev-server in `webpack.config.js`.
-* Ready to make a pull request? Run `npm run build` to make sure the build runs and there are no linting errors.
+OpenDota Web UI: A web interface for viewing Dota 2 data. This utilizes the [OpenDota API](https://docs.opendota.com), which is also an [open source project](https://github.com/odota/core).
-Tech stack
-----
-* View layer: React
-* State management: Redux
-* CSS: css-modules & postcss
-* New to React/Redux? Read these articles on React and watch these egghead series by Redux creator Dan Abramov.
+## Quickstart
-Thinking in React: https://facebook.github.io/react/docs/thinking-in-react.html
+- Clone the repo using `git clone git@github.com:odota/web.git`
+- Install Node.js (v16 or greater) (download [installer](https://nodejs.org/en/download/) or [install via package manager](https://nodejs.org/en/download/package-manager/))
+- `npm install`
+- `npm start`
+- Visit port 5173 on your development machine.
-Getting started with Redux: https://egghead.io/courses/getting-started-with-redux
+## Contributing
-Idiomatic Redux: https://egghead.io/courses/building-react-applications-with-idiomatic-redux
+- Make some changes.
+- `npm run typecheck` to check your code for typing errors.
+- `npm test` to check all app routes for uncaught JavaScript errors.
+- Submit a pull request. Wait for review and merge.
+- Congratulations! You're a contributor.
-ES6 guide: https://github.com/lukehoban/es6features
+## Configuration
-Notes
-----
-* For ease of development, the SPA is pointed to production YASP by default. This means you don't need to set up the entire stack/get sample data.
-* You can configure it to point to your own instance (if you are working on a backend feature) in `yasp.config.js`.
+- You can set the following environment variables:
+ - VITE_API_HOST: Changes the API that the UI requests data from (default https://api.opendota.com)
+ - SSL_CRT_FILE/SSL_KEY_FILE: Causes the development server to use HTTPS
+
+## Tech Stack
+
+- View: React/Redux
+- CSS: styled-components
+
+## Notes
+
+- You don't have to set up the entire stack (databases, etc.), or worry about getting starter data, since the UI points to the production API.
+- Use the configuration to point to your own API (if you are working on a new feature and want to start building the UI before it's deployed to production).
+- Discord: https://discord.gg/opendota
+ - Strongly recommended for active developers! We move fast and it's helpful to be up to speed with everything that's happening.
+- If you're interested in contributing regularly, let us know and we'll add you to the organization.
diff --git a/actions/appBarActions.js b/actions/appBarActions.js
deleted file mode 100644
index bc844102d8..0000000000
--- a/actions/appBarActions.js
+++ /dev/null
@@ -1,9 +0,0 @@
-const OPEN = 'yasp/appBar/OPEN';
-
-export const appBarActions = {
- OPEN,
-};
-
-export const openMenu = () => ({
- type: OPEN,
-});
diff --git a/actions/constantsActions.js b/actions/constantsActions.js
deleted file mode 100644
index 92696d1ed0..0000000000
--- a/actions/constantsActions.js
+++ /dev/null
@@ -1,43 +0,0 @@
-import fetch from 'isomorphic-fetch';
-import { HOST_URL } from '../actions';
-const url = '/api/constants';
-const REQUEST = 'yasp/constants/REQUEST';
-const OK = 'yasp/constants/OK';
-const ERROR = 'yasp/constants/ERROR';
-
-export const constantsActions = {
- REQUEST,
- OK,
- ERROR,
-};
-
-const getConstantsRequest = () => ({
- type: REQUEST,
-});
-const getConstantsOk = (payload) => ({
- type: OK,
- payload,
-});
-const getConstantsError = (payload) => ({
- type: ERROR,
- payload,
-});
-
-export const getConstants = (host = HOST_URL) => (dispatch) => {
- getConstantsRequest();
- return fetch(`${host}${url}`, { credentials: 'include' })
- .then(response => response.json())
- .then(json => {
- const links = Object.keys(json.navbar_pages).map(
- (key) => ({ path: `/${key}`, name: json.navbar_pages[key].name })
- );
- const transformedData = {
- ...json,
- links,
- };
- dispatch(getConstantsOk(transformedData));
- })
- .catch(error => {
- dispatch(getConstantsError(error));
- });
-};
diff --git a/actions/index.js b/actions/index.js
deleted file mode 100644
index 91c3404f1a..0000000000
--- a/actions/index.js
+++ /dev/null
@@ -1,28 +0,0 @@
-import { metadataActions, getMetadata } from './metadataActions';
-import { constantsActions, getConstants } from './constantsActions';
-import { playerActions, getPlayer } from './playerActions';
-import { matchActions, getMatch, setMatchSort } from './matchActions';
-import { playerMatchesActions, getPlayerMatches, setPlayerMatchesSort } from './playerMatchesActions';
-import { appBarActions, openMenu } from './appBarActions';
-import { searchActions, getSearchResult } from './searchActions';
-import { HOST_URL } from '../yasp.config';
-
-export {
- metadataActions,
- getMetadata,
- constantsActions,
- getConstants,
- playerActions,
- getPlayer,
- matchActions,
- getMatch,
- setMatchSort,
- playerMatchesActions,
- getPlayerMatches,
- setPlayerMatchesSort,
- appBarActions,
- openMenu,
- getSearchResult,
- searchActions,
- HOST_URL,
-};
diff --git a/actions/matchActions.js b/actions/matchActions.js
deleted file mode 100644
index 54614732c7..0000000000
--- a/actions/matchActions.js
+++ /dev/null
@@ -1,44 +0,0 @@
-import fetch from 'isomorphic-fetch';
-import { HOST_URL } from '../actions';
-
-const url = '/api/matches/';
-
-const REQUEST = 'yasp/match/REQUEST';
-const OK = 'yasp/match/OK';
-const ERROR = 'yasp/match/ERROR';
-const SORT = 'yasp/match/SORT';
-
-export const matchActions = {
- REQUEST,
- OK,
- ERROR,
- SORT,
-};
-
-const getMatchRequest = () => ({ type: REQUEST });
-
-const getMatchOk = (payload) => ({
- type: OK,
- payload,
-});
-
-const getMatchError = (payload) => ({
- type: ERROR,
- payload,
-});
-
-
-export const setMatchSort = (sortField, sortState, sortFn) => ({
- type: SORT,
- sortField,
- sortState,
- sortFn,
-});
-
-export const getMatch = (matchId) => (dispatch) => {
- dispatch(getMatchRequest());
- return fetch(`${HOST_URL}${url}${matchId}`)
- .then(response => response.json())
- .then(json => dispatch(getMatchOk(json)))
- .catch(error => dispatch(getMatchError(error)));
-};
diff --git a/actions/metadataActions.js b/actions/metadataActions.js
deleted file mode 100644
index 03cd1f861f..0000000000
--- a/actions/metadataActions.js
+++ /dev/null
@@ -1,34 +0,0 @@
-import fetch from 'isomorphic-fetch';
-import { HOST_URL } from '../actions';
-const url = '/api/metadata';
-const REQUEST = 'yasp/metadata/REQUEST';
-const OK = 'yasp/metadata/OK';
-const ERROR = 'yasp/metadata/ERROR';
-
-export const metadataActions = {
- REQUEST,
- OK,
- ERROR,
-};
-
-const getMetadataRequest = () => ({
- type: REQUEST,
-});
-const getMetadataOk = (payload) => ({
- type: OK,
- payload,
-});
-const getMetadataError = (payload) => ({
- type: ERROR,
- payload,
-});
-
-export const getMetadata = (host = HOST_URL) => (dispatch) => {
- getMetadataRequest();
- return fetch(`${host}${url}`, { credentials: 'include' })
- .then(response => response.json())
- .then(json => dispatch(getMetadataOk(json)))
- .catch(error => {
- dispatch(getMetadataError(error));
- });
-};
diff --git a/actions/playerActions.js b/actions/playerActions.js
deleted file mode 100644
index 414353d99e..0000000000
--- a/actions/playerActions.js
+++ /dev/null
@@ -1,43 +0,0 @@
-import fetch from 'isomorphic-fetch';
-import { HOST_URL } from '.';
-import { getPlayerMatchesOk, getPlayerMatchesRequest, getPlayerMatchesError } from './playerMatchesActions';
-
-const url = '/api/players';
-
-const REQUEST = 'yasp/player/REQUEST';
-const OK = 'yasp/player/OK';
-const ERROR = 'yasp/player/ERROR';
-
-export const playerActions = {
- REQUEST,
- OK,
- ERROR,
-};
-
-const getPlayerRequest = () => ({ type: REQUEST });
-
-const getPlayerOk = (payload) => ({
- type: OK,
- payload,
-});
-
-const getPlayerError = (payload) => ({
- type: ERROR,
- payload,
-});
-
-export const getPlayer = (accountId, host = HOST_URL) => (dispatch) => {
- dispatch(getPlayerRequest());
- dispatch(getPlayerMatchesRequest());
- return fetch(`${host}${url}/${accountId}`)
- .then(response => response.json())
- .then(json => {
- const { matches, ...playerData } = json;
- dispatch(getPlayerOk(playerData));
- dispatch(getPlayerMatchesOk(matches));
- })
- .catch(error => {
- dispatch(getPlayerError(error));
- dispatch(getPlayerMatchesError(error));
- });
-};
diff --git a/actions/playerMatchesActions.js b/actions/playerMatchesActions.js
deleted file mode 100644
index 20092d87b0..0000000000
--- a/actions/playerMatchesActions.js
+++ /dev/null
@@ -1,43 +0,0 @@
-import fetch from 'isomorphic-fetch';
-import { HOST_URL } from './';
-
-const url = (playerId, numMatches) => `/api/players/${playerId}/matches?limit=${numMatches}`;
-
-const REQUEST = 'yasp/playerMatches/REQUEST';
-const OK = 'yasp/playerMatches/OK';
-const ERROR = 'yasp/playerMatches/ERROR';
-const SORT = 'yasp/playerMatches/SORT';
-
-export const playerMatchesActions = {
- REQUEST,
- OK,
- ERROR,
- SORT,
-};
-
-export const setPlayerMatchesSort = (sortField, sortState, sortFn) => ({
- type: SORT,
- sortField,
- sortState,
- sortFn,
-});
-
-export const getPlayerMatchesRequest = () => ({ type: REQUEST });
-
-export const getPlayerMatchesOk = (payload) => ({
- type: OK,
- payload,
-});
-
-export const getPlayerMatchesError = (payload) => ({
- type: ERROR,
- payload,
-});
-
-export const getPlayerMatches = (playerId, numMatches, host = HOST_URL) => (dispatch) => {
- dispatch(getPlayerMatchesRequest());
- return fetch(`${host}${url(playerId, numMatches)}`, { credentials: 'include' })
- .then(response => response.json())
- .then(json => dispatch(getPlayerMatchesOk(json.matches)))
- .catch(error => dispatch(getPlayerMatchesError(error)));
-};
diff --git a/actions/searchActions.js b/actions/searchActions.js
deleted file mode 100644
index d6e9646806..0000000000
--- a/actions/searchActions.js
+++ /dev/null
@@ -1,37 +0,0 @@
-import fetch from 'isomorphic-fetch';
-import { HOST_URL } from '../actions';
-
-const url = '/api/search';
-
-const START = 'yasp/search/START';
-const DONE = 'yasp/search/DONE';
-const ERROR = 'yasp/search/ERROR';
-
-export const searchActions = {
- START,
- DONE,
- ERROR,
-};
-
-const getSearchStart = () => ({
- type: START,
-});
-
-const getSearchDone = (payload) => ({
- type: DONE,
- payload,
-});
-
-const getSearchError = (payload) => ({
- type: ERROR,
- payload,
-});
-
-export const getSearchResult = (query) => (dispatch) => {
- dispatch(getSearchStart());
-
- return fetch(`${HOST_URL}${url}?q=${query}`)
- .then(res => res.json())
- .then(json => dispatch(getSearchDone(json)))
- .catch(err => dispatch(getSearchError(err)));
-};
diff --git a/assets/Roboto-Bold.ttf b/assets/Roboto-Bold.ttf
deleted file mode 100755
index a355c27cde..0000000000
Binary files a/assets/Roboto-Bold.ttf and /dev/null differ
diff --git a/assets/Roboto-Light.ttf b/assets/Roboto-Light.ttf
deleted file mode 100755
index 94c6bcc67e..0000000000
Binary files a/assets/Roboto-Light.ttf and /dev/null differ
diff --git a/assets/Roboto-LightItalic.ttf b/assets/Roboto-LightItalic.ttf
deleted file mode 100755
index 04cc002302..0000000000
Binary files a/assets/Roboto-LightItalic.ttf and /dev/null differ
diff --git a/assets/flaticon.css b/assets/flaticon.css
deleted file mode 100644
index 6d555dd88f..0000000000
--- a/assets/flaticon.css
+++ /dev/null
@@ -1,17 +0,0 @@
-@font-face {
- font-family: "Flaticon";
- src: url("/assets/flaticon.eot");
- src: url("/assets/flaticon.eot#iefix") format("embedded-opentype"),
- url("/assets/flaticon.woff") format("woff"),
- url("/assets/flaticon.ttf") format("truetype"),
- url("/assets/flaticon.svg") format("svg");
- font-weight: normal;
- font-style: normal;
-}
-[class^="flaticon-"]:before, [class*=" flaticon-"]:before,
-[class^="flaticon-"]:after, [class*=" flaticon-"]:after {
- font-family: Flaticon;
- font-style: normal;
-}.flaticon-1:before {
- content: "\e000";
-}
diff --git a/assets/flaticon.eot b/assets/flaticon.eot
deleted file mode 100644
index 9351a1454f..0000000000
Binary files a/assets/flaticon.eot and /dev/null differ
diff --git a/assets/flaticon.svg b/assets/flaticon.svg
deleted file mode 100644
index f9fc0aea19..0000000000
--- a/assets/flaticon.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-
-
-
diff --git a/assets/flaticon.ttf b/assets/flaticon.ttf
deleted file mode 100644
index 87e35402b8..0000000000
Binary files a/assets/flaticon.ttf and /dev/null differ
diff --git a/assets/flaticon.woff b/assets/flaticon.woff
deleted file mode 100644
index ebe80763e4..0000000000
Binary files a/assets/flaticon.woff and /dev/null differ
diff --git a/components/AccountWidget/AccountWidget.css b/components/AccountWidget/AccountWidget.css
deleted file mode 100644
index 00a0bca3a2..0000000000
--- a/components/AccountWidget/AccountWidget.css
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-.container li {
- display: inline-block;
- padding-left: 10px;
-}
diff --git a/components/AccountWidget/AccountWidget.jsx b/components/AccountWidget/AccountWidget.jsx
deleted file mode 100644
index 2e47ca2c71..0000000000
--- a/components/AccountWidget/AccountWidget.jsx
+++ /dev/null
@@ -1,42 +0,0 @@
-import React from 'react';
-import { connect } from 'react-redux';
-import Spinner from '../Spinner';
-import Error from '../Error';
-import { REDUCER_KEY } from '../../reducers';
-import { getPlayer } from '../../actions';
-import { Link } from 'react-router';
-import styles from './AccountWidget.css';
-
-// Maybe we can factor out this ternary into a function?
-const AccountWidget = ({ loading, error, user }) => (
-
- {loading && !error &&
}
- {error &&
}
- {!error && !loading && user ? (
-
- )
- :
Login
- }
-
-);
-
-export { AccountWidget };
-
-const mapStateToProps = (state) => {
- const { error, loading, user } = state[REDUCER_KEY].gotMetadata;
-
- return {
- loading,
- error,
- user,
- };
-};
-
-const mapDispatchToProps = (dispatch) => ({
- getPlayer: (playerId) => dispatch(getPlayer(playerId)),
-});
-
-export default connect(mapStateToProps, mapDispatchToProps)(AccountWidget);
diff --git a/components/AccountWidget/index.js b/components/AccountWidget/index.js
deleted file mode 100644
index bf69a44feb..0000000000
--- a/components/AccountWidget/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import AccountWidget from './AccountWidget';
-
-export default AccountWidget;
diff --git a/components/App/App.css b/components/App/App.css
deleted file mode 100644
index f2c2478ff6..0000000000
--- a/components/App/App.css
+++ /dev/null
@@ -1,22 +0,0 @@
-@import "../palette.css";
-
-.container {
- transition: var(--normalTransition);
- position: relative;
- display: flex;
- flex-direction:column;
- height: 100%;
-}
-
-.drawerOpen {
- left: 256px;
-}
-
-.drawerClosed {
- left: 0;
-}
-
-.body {
- padding: 50px;
- flex-grow: 1;
-}
diff --git a/components/App/App.jsx b/components/App/App.jsx
deleted file mode 100644
index e686691f2d..0000000000
--- a/components/App/App.jsx
+++ /dev/null
@@ -1,26 +0,0 @@
-import React from 'react';
-import Header from '../Header';
-import Footer from '../Footer';
-import getMuiTheme from 'material-ui/styles/getMuiTheme';
-import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
-import styles from './App.css';
-import { connect } from 'react-redux';
-import { REDUCER_KEY } from '../../reducers';
-
-const App = ({ children, open }) => (
-
-
-
-);
-
-const mapStateToProps = (state) => ({
- open: state[REDUCER_KEY].appBar.open,
-});
-
-export default connect(mapStateToProps)(App);
diff --git a/components/App/index.js b/components/App/index.js
deleted file mode 100644
index f1f2a246e9..0000000000
--- a/components/App/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import App from './App';
-
-export default App;
diff --git a/components/Cheese/Cheese.css b/components/Cheese/Cheese.css
deleted file mode 100644
index ca4366c5c8..0000000000
--- a/components/Cheese/Cheese.css
+++ /dev/null
@@ -1,23 +0,0 @@
-.container {
- display: flex;
- flex-direction: row;
- justify-content: space-around;
- flex-wrap: wrap;
-
- @media only screen and (max-width: 650px) {
- flex-direction: column;
- }
-}
-
-.percent {
- margin-bottom: 10px;
-}
-
-.section {
- width: calc(100% / 3);
- text-align: center;
- @media only screen and (max-width: 650px) {
- width: 100%;
- margin-bottom: 25px;
- }
-}
diff --git a/components/Cheese/Cheese.jsx b/components/Cheese/Cheese.jsx
deleted file mode 100644
index 4ff84cca6d..0000000000
--- a/components/Cheese/Cheese.jsx
+++ /dev/null
@@ -1,56 +0,0 @@
-import React from 'react';
-import { connect } from 'react-redux';
-import { REDUCER_KEY } from '../../reducers';
-import Spinner from '../Spinner';
-import styles from './Cheese.css';
-import LinearProgress from 'material-ui/LinearProgress';
-import CheeseButton from './CheeseButton';
-
-const Cheese = ({ donations, error, loading }) => {
- const { goal, cheese } = donations;
- const percent = cheese / goal;
-
- const getCheeseMeter = () => (
-
-
{(percent * 100).toFixed(2)}%
-
- {percent >= 1 &&
- Woo!!! Thanks guys! No more ads! - Resets in X days.
}
-
- );
-
- return (
-
-
-
Buy some cheese. Help pay for servers. Reaching the goal every month keeps us running.
-
-
-
-
Monthly Cheese Goal
-
- {error && }
- {loading && }
- { /* TODO - this should be it's own component called cheese meter */
- !error && !loading
- && getCheeseMeter(donations.goal, donations.cheese)
- }
-
-
-
-
-
-
-
- );
-};
-
-const mapStateToProps = (state) => {
- const { loading, error, donations } = state[REDUCER_KEY].gotMetadata;
-
- return {
- loading,
- error,
- donations,
- };
-};
-
-export default connect(mapStateToProps)(Cheese);
diff --git a/components/Cheese/CheeseButton.css b/components/Cheese/CheeseButton.css
deleted file mode 100644
index 6937100029..0000000000
--- a/components/Cheese/CheeseButton.css
+++ /dev/null
@@ -1,14 +0,0 @@
-@import "../palette.css";
-
-:export { backgroundColor: var(--defaultPrimaryColor) }
-:export { hoverColor: color(var(--defaultPrimaryColor) lightness(-10%)) }
-
-.cheese {
- font-family: Flaticon;
- font-size: 40px;
- text-shadow: 0 0 10px #ff0;
- margin: 0 10px;
- &::before {
- content: "\E000";
- }
-}
diff --git a/components/Cheese/CheeseButton.jsx b/components/Cheese/CheeseButton.jsx
deleted file mode 100644
index 571d7932e9..0000000000
--- a/components/Cheese/CheeseButton.jsx
+++ /dev/null
@@ -1,20 +0,0 @@
-import React from 'react';
-import FontIcon from 'material-ui/FontIcon';
-import { Link } from 'react-router';
-import styles from './CheeseButton.css';
-import FlatButton from 'material-ui/FlatButton';
-
-export default () => (
-
-
-
-
-
-
-);
diff --git a/components/Cheese/index.js b/components/Cheese/index.js
deleted file mode 100644
index 297a584deb..0000000000
--- a/components/Cheese/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import Cheese from './Cheese';
-
-export default Cheese;
diff --git a/components/Constants/createConstantsWrapper.jsx b/components/Constants/createConstantsWrapper.jsx
deleted file mode 100644
index 7d99931537..0000000000
--- a/components/Constants/createConstantsWrapper.jsx
+++ /dev/null
@@ -1,29 +0,0 @@
-import React from 'react';
-import { connect } from 'react-redux';
-import { REDUCER_KEY } from '../../reducers';
-import Spinner from '../Spinner';
-import Error from '../Error';
-
-export default (Component) => {
- const ConstantsWrapper = (props) => {
- const { error, loading, ...realProps } = props;
- return (
-
- {loading && !error && }
- {error && }
- {!loading && !error && }
-
- );
- };
-
- const mapStateToProps = (state) => {
- const { error, loading } = state[REDUCER_KEY].gotConstants;
-
- return {
- error,
- loading,
- };
- };
-
- return connect(mapStateToProps)(ConstantsWrapper);
-};
diff --git a/components/Constants/index.js b/components/Constants/index.js
deleted file mode 100644
index 49f048204b..0000000000
--- a/components/Constants/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import createConstantsWrapper from './createConstantsWrapper';
-
-export default createConstantsWrapper;
diff --git a/components/Error/Error.jsx b/components/Error/Error.jsx
deleted file mode 100644
index 6470aa2f88..0000000000
--- a/components/Error/Error.jsx
+++ /dev/null
@@ -1,3 +0,0 @@
-import React from 'react';
-
-export default () => Whoops! Something went wrong.
;
diff --git a/components/Error/index.js b/components/Error/index.js
deleted file mode 100644
index 591ec17265..0000000000
--- a/components/Error/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import Error from './Error';
-
-export default Error;
diff --git a/components/Footer/Footer.css b/components/Footer/Footer.css
deleted file mode 100644
index 1694fbcefe..0000000000
--- a/components/Footer/Footer.css
+++ /dev/null
@@ -1,17 +0,0 @@
-@import "../palette.css";
-
-.footer {
- padding: 20px;
- background-color: var(--primaryTextColor);
- color: #fff;
-}
-
-.links {
- background-color: var(--primaryTextColor);
- color: #fff;
- display: flex;
- flex-direction: row;
- flex-wrap: wrap;
- justify-content: center;
- padding: 1em 1em 1em 1em;
-}
diff --git a/components/Footer/Footer.jsx b/components/Footer/Footer.jsx
deleted file mode 100644
index 007f2f5e17..0000000000
--- a/components/Footer/Footer.jsx
+++ /dev/null
@@ -1,14 +0,0 @@
-import React from 'react';
-import Cheese from '../Cheese';
-import styles from './Footer.css';
-
-const Footer = () => (
-
-);
-
-export default Footer;
-
-// tooltips();
-// formatHtml();
diff --git a/components/Footer/FooterLinks.jsx b/components/Footer/FooterLinks.jsx
deleted file mode 100644
index e7dec3d4c9..0000000000
--- a/components/Footer/FooterLinks.jsx
+++ /dev/null
@@ -1,14 +0,0 @@
-import React from 'react';
-import styles from './Footer.css';
-
-export default () => (
-
- An open source volunteer project
- • Privacy & Terms
- • Follow on
- • Join us on Discord
- • Dota 2 API powered by
- • Parsing by clarity
- • Cheese icon by Belc on flaticon
-
-);
diff --git a/components/Footer/index.js b/components/Footer/index.js
deleted file mode 100644
index dcdcbe0b4e..0000000000
--- a/components/Footer/index.js
+++ /dev/null
@@ -1,5 +0,0 @@
-import Footer from './Footer';
-import FooterLinks from './FooterLinks';
-
-export default Footer;
-export { FooterLinks };
diff --git a/components/Header/Header.container.js b/components/Header/Header.container.js
deleted file mode 100644
index b05daaaea7..0000000000
--- a/components/Header/Header.container.js
+++ /dev/null
@@ -1,9 +0,0 @@
-import { connect } from 'react-redux';
-import Header from './Header';
-import { openMenu } from '../../actions';
-
-const mapDispatchToProps = (dispatch) => ({
- openMenu: () => dispatch(openMenu()),
-});
-
-export default connect(null, mapDispatchToProps)(Header);
diff --git a/components/Header/Header.css b/components/Header/Header.css
deleted file mode 100644
index 33f1de8c36..0000000000
--- a/components/Header/Header.css
+++ /dev/null
@@ -1,12 +0,0 @@
-@import "../palette.css";
-
-.header {
- background-color: var(--defaultPrimaryColor) !important;
-
- & a {
- color: #fff;
- &:hover {
- color: var(--primaryTextColor);
- }
- }
-}
diff --git a/components/Header/Header.jsx b/components/Header/Header.jsx
deleted file mode 100644
index ff56cd5e15..0000000000
--- a/components/Header/Header.jsx
+++ /dev/null
@@ -1,19 +0,0 @@
-import React from 'react';
-import Logo from '../Logo';
-import { NavDrawer } from '../NavBar';
-import AccountWidget from '../AccountWidget';
-import AppBar from 'material-ui/AppBar';
-import styles from './Header.css';
-
-export default ({ openMenu }) => (
-
-
)}
- iconStyleRight={{ marginRight: 0 }}
- title={(
)}
- onLeftIconButtonTouchTap={() => openMenu()}
- />
-
-
-);
diff --git a/components/Header/index.js b/components/Header/index.js
deleted file mode 100644
index 9b1e901062..0000000000
--- a/components/Header/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import Header from './Header.container';
-
-export default Header;
diff --git a/components/Home/Home.jsx b/components/Home/Home.jsx
deleted file mode 100644
index c72a383e36..0000000000
--- a/components/Home/Home.jsx
+++ /dev/null
@@ -1,12 +0,0 @@
-import React from 'react';
-import { connect } from 'react-redux';
-
-const Home = () => (
- This is a home page!
-);
-
-function mapStateToProps(data) {
- return { content: data.content };
-}
-
-export default connect(mapStateToProps)(Home);
diff --git a/components/Home/index.js b/components/Home/index.js
deleted file mode 100644
index fbe3fed6bf..0000000000
--- a/components/Home/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import Home from './Home';
-
-export default Home;
diff --git a/components/Logo/Logo.jsx b/components/Logo/Logo.jsx
deleted file mode 100644
index 04369f63b5..0000000000
--- a/components/Logo/Logo.jsx
+++ /dev/null
@@ -1,15 +0,0 @@
-import React from 'react';
-import { Link } from 'react-router';
-
-export default () => (
-
-);
diff --git a/components/Logo/index.js b/components/Logo/index.js
deleted file mode 100644
index 72acb339d7..0000000000
--- a/components/Logo/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import Logo from './Logo';
-
-export default Logo;
diff --git a/components/Match/Match.jsx b/components/Match/Match.jsx
deleted file mode 100644
index b149d620fb..0000000000
--- a/components/Match/Match.jsx
+++ /dev/null
@@ -1,39 +0,0 @@
-import React from 'react';
-import { MatchTable } from '../Table';
-import { getMatch } from '../../actions';
-import { connect } from 'react-redux';
-
-const Match = () => (
-
-
-
-);
-
-const mapStateToProps = (state, { params }) => ({ matchId: params.match_id });
-
-const mapDispatchToProps = (dispatch) => ({
- sort: (column) => dispatch(getMatch(column)),
- getMatch: (matchId) => dispatch(getMatch(matchId)),
-});
-
-class RequestLayer extends React.Component {
- componentDidMount() {
- this.props.getMatch(this.props.routeParams.match_id);
- }
-
- componentWillUpdate(nextProps) {
- if (this.props.match_id !== nextProps.match_id) {
- this.props.getMatch(nextProps.match_id);
- }
- }
-
- render() {
- return (
-
-
-
- );
- }
-}
-
-export default connect(mapStateToProps, mapDispatchToProps)(RequestLayer);
diff --git a/components/Match/index.js b/components/Match/index.js
deleted file mode 100644
index 15231febd1..0000000000
--- a/components/Match/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import Match from './Match';
-
-export default Match;
diff --git a/components/NavBar/NavBar.css b/components/NavBar/NavBar.css
deleted file mode 100644
index 92709f1ba1..0000000000
--- a/components/NavBar/NavBar.css
+++ /dev/null
@@ -1,13 +0,0 @@
-@import "../palette.css";
-
-.listItem {
- padding: 20px;
- font-size: var(--mediumLargeFontSize);
-
- color: var(--primaryTextColor);
-
- &:hover {
- background-color: var(--primaryTextColor);
- color: #fff;
- }
-}
diff --git a/components/NavBar/NavBar.jsx b/components/NavBar/NavBar.jsx
deleted file mode 100644
index 05ab7aee97..0000000000
--- a/components/NavBar/NavBar.jsx
+++ /dev/null
@@ -1,41 +0,0 @@
-import React from 'react';
-import { connect } from 'react-redux';
-import Spinner from '../Spinner';
-import Error from '../Error';
-import { REDUCER_KEY } from '../../reducers';
-import { Link } from 'react-router';
-import Divider from 'material-ui/Divider';
-import styles from './NavBar.css';
-import { openMenu } from '../../actions';
-
-const NavBar = ({ loading, error, links, toggleMenu }) => {
- const getNavLinks = (navLinks) =>
- navLinks.map((link, index) => (
-
-
- {link.name}
-
-
-
- ));
-
- return (
-
- {loading && !error && }
- {error && }
- {!loading && !error && getNavLinks(links)}
-
- );
-};
-
-const mapStateToProps = (state) => {
- const { loading, error, links } = state[REDUCER_KEY].gotConstants;
-
- return {
- loading,
- error,
- links,
- };
-};
-
-export default connect(mapStateToProps, { toggleMenu: openMenu })(NavBar);
diff --git a/components/NavBar/NavDrawer.css b/components/NavBar/NavDrawer.css
deleted file mode 100644
index 15a47957ab..0000000000
--- a/components/NavBar/NavDrawer.css
+++ /dev/null
@@ -1,10 +0,0 @@
-.container {
- display: flex;
- flex-direction:column;
- min-height: 100%;
- position: relative;
-}
-
-.navigation {
- flex-grow: 1;
-}
diff --git a/components/NavBar/NavDrawer.jsx b/components/NavBar/NavDrawer.jsx
deleted file mode 100644
index 07e4b6cdf0..0000000000
--- a/components/NavBar/NavDrawer.jsx
+++ /dev/null
@@ -1,27 +0,0 @@
-import React from 'react';
-import { connect } from 'react-redux';
-import NavBar from './NavBar';
-import Drawer from 'material-ui/Drawer';
-import { FooterLinks } from '../Footer';
-import { REDUCER_KEY } from '../../reducers';
-import styles from './NavDrawer.css';
-import { openMenu } from '../../actions';
-
-const NavDrawer = ({ open, openMenu }) => (
-
-
-
-);
-
-const mapStateToProps = (state) => ({
- open: state[REDUCER_KEY].appBar.open,
-});
-
-export default connect(mapStateToProps, { openMenu })(NavDrawer);
diff --git a/components/NavBar/index.js b/components/NavBar/index.js
deleted file mode 100644
index ebdd1269ae..0000000000
--- a/components/NavBar/index.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import NavBar from './NavBar';
-import NavDrawer from './NavDrawer';
-
-export {
- NavBar,
- NavDrawer,
-};
diff --git a/components/Player/Player.jsx b/components/Player/Player.jsx
deleted file mode 100644
index 19d9a2f77d..0000000000
--- a/components/Player/Player.jsx
+++ /dev/null
@@ -1,58 +0,0 @@
-import React from 'react';
-import { PlayerMatchesTable } from '../Table';
-import PlayerHeader from './PlayerHeader';
-import Error from '../Error';
-import { getPlayer } from '../../actions';
-import { connect } from 'react-redux';
-import styles from './PlayerHeader.css';
-
-const Player = ({ playerId }) => {
- if (!playerId) {
- return ;
- }
-
- return (
-
- );
-};
-
-const mapStateToProps = (state, { params }) => ({ playerId: params.account_id });
-
-const mapDispatchToProps = (dispatch) => ({
- getPlayer: (playerId) => dispatch(getPlayer(playerId)),
-});
-
-class RequestLayer extends React.Component {
- componentDidMount() {
- this.props.getPlayer(this.props.playerId);
- }
-
- componentWillUpdate(nextProps) {
- if (this.props.playerId !== nextProps.playerId) {
- this.props.getPlayer(nextProps.playerId);
- }
- }
-
- render() {
- return ;
- }
-}
-
-export default connect(mapStateToProps, mapDispatchToProps)(RequestLayer);
-
-// const mapStateToProps = (state) => ({
-// profile: player.getProfile(state),
-// win: player.getWin(state),
-// lose: player.getLose(state),
-// mmrEstimate: player.getMmrEstimate(state),
-// soloMmrEstimate: player.getSoloMmrEstimate(state),
-// competitiveRank: player.getCompetitiveRank(state),
-// loading: player.getLoading(state),
-// error: player.getError(state),
-// });
diff --git a/components/Player/PlayerHeader.css b/components/Player/PlayerHeader.css
deleted file mode 100644
index 747e315dc8..0000000000
--- a/components/Player/PlayerHeader.css
+++ /dev/null
@@ -1,82 +0,0 @@
-@import "../palette.css";
-
-.header {
- margin-bottom: 30px;
-}
-
-.image {
- display: inline-block;
- height: 30px;
- width: 30px;
- background-size: cover;
-}
-
-.nameContainer {
- display: flex;
- flex-direction: row;
- font-size: 26px;
- text-transform: uppercase;
- margin-bottom: 20px;
-}
-
-.pictureContainer {
- display: flex;
- flex-direction: column;
- justify-content: center;
-}
-
-.playerName {
- display: flex;
- flex-direction: column;
- justify-content: center;
- margin: 0 10px;
-}
-
-.playerPicture {
- border-radius: 100px;
- height: 40px;
-}
-
-.playerPictureYasp {
- composes: playerPicture;
- border: 5px solid #BBF0FD;
-}
-
-.playerPictureCheese {
- composes: playerPicture;
- border: 5px solid #FFD700
-}
-
-.yaspBadge {
- composes: image;
-}
-
-.container {
- display: flex;
- flex-direction: row;
- margin: 0 0 5px 0;
- justify-content: space-between;
- flex-wrap: wrap;
-}
-
-
-@media only screen and (max-width: 650px) {
- .mmr {
- display: flex;
- flex-direction: row;
- justify-content: space-between;
- width: 100%;
- }
-
- .mmrContainer {
- width: 100%;
- margin-top: 15px;
- }
-
- .playerInfo {
- display: flex;
- flex-direction: column;
- align-items: center;
- width: 100%;
- }
-}
diff --git a/components/Player/PlayerHeader.jsx b/components/Player/PlayerHeader.jsx
deleted file mode 100644
index 67ee65834a..0000000000
--- a/components/Player/PlayerHeader.jsx
+++ /dev/null
@@ -1,15 +0,0 @@
-import React from 'react';
-import PlayerName from './PlayerName';
-import PlayerMMR from './PlayerMMR';
-import PlayerRecord from './PlayerRecord';
-import styles from './PlayerHeader.css';
-
-export default () => (
-
-);
diff --git a/components/Player/PlayerMMR.jsx b/components/Player/PlayerMMR.jsx
deleted file mode 100644
index 13a2433050..0000000000
--- a/components/Player/PlayerMMR.jsx
+++ /dev/null
@@ -1,37 +0,0 @@
-import React from 'react';
-import Error from '../Error';
-import Spinner from '../Spinner';
-import { connect } from 'react-redux';
-import { player } from '../../reducers';
-import styles from './PlayerHeader.css';
-
-export const PlayerMMR = ({ loading, error, rank, soloRank, mmrEstimate }) => {
- const getPlayerMMR = () => {
- if (error) return ;
- if (loading) return ;
- return (
-
-
Solo: {soloRank}
-
Party: {rank}
-
Estimate: {mmrEstimate.estimate}
-
- );
- };
-
- return (
-
- {getPlayerMMR()}
-
- );
-};
-
-const mapStateToProps = (state) => ({
- loading: player.getLoading(state),
- error: player.getError(state),
- rank: player.getCompetitiveRank(state),
- soloRank: player.getSoloMmrEstimate(state),
- mmrEstimate: player.getMmrEstimate(state),
-});
-
-
-export default connect(mapStateToProps)(PlayerMMR);
diff --git a/components/Player/PlayerName.jsx b/components/Player/PlayerName.jsx
deleted file mode 100644
index b38f70c169..0000000000
--- a/components/Player/PlayerName.jsx
+++ /dev/null
@@ -1,39 +0,0 @@
-import React from 'react';
-// import YaspBadge from './YaspBadge';
-import PlayerPicture from './PlayerPicture';
-import Error from '../Error';
-import Spinner from '../Spinner';
-import { connect } from 'react-redux';
-import { player } from '../../reducers';
-import styles from './PlayerHeader.css';
-
-const PlayerName = ({ playerName, registered, loading, error }) => {
- const getPlayerName = () => {
- if (error) return ;
- if (loading) return ;
-
- return (
-
- );
- };
-
- return {getPlayerName()}
;
-};
-
-export { PlayerName };
-
-// TODO - add account reducer for player so I can just call getX() instead of dot notation
-
-const mapStateToProps = (state) => ({
- loading: player.getLoading(state),
- error: player.getError(state),
- playerName: player.getPlayerName(state),
- registered: player.getLastLogin(state),
-});
-
-export default connect(mapStateToProps)(PlayerName);
diff --git a/components/Player/PlayerPicture.jsx b/components/Player/PlayerPicture.jsx
deleted file mode 100644
index 43bc920123..0000000000
--- a/components/Player/PlayerPicture.jsx
+++ /dev/null
@@ -1,29 +0,0 @@
-import React from 'react';
-import { connect } from 'react-redux';
-import { player } from '../../reducers';
-import Avatar from 'material-ui/Avatar';
-import styles from './PlayerHeader.css';
-
-const getPlayerStyle = (registered, cheese) => {
- if (cheese) return styles.playerPictureCheese;
- if (registered) return styles.playerPictureYasp;
- return styles.playerPicture;
-};
-
-const PlayerPicture = ({ picture, steamLink, cheese, registered }) => (
-
-
-
-);
-
-// TODO - refactor so that account is its own reducer with its own getX() functions
-
-const mapStateToProps = (state) => ({
- picture: player.getPicture(state),
- steamLink: player.getSteamLink(state),
- cheese: player.getCheese(state),
-});
-
-export { PlayerPicture };
-
-export default connect(mapStateToProps)(PlayerPicture);
diff --git a/components/Player/PlayerRecord.jsx b/components/Player/PlayerRecord.jsx
deleted file mode 100644
index 07b9580c8f..0000000000
--- a/components/Player/PlayerRecord.jsx
+++ /dev/null
@@ -1,36 +0,0 @@
-import React from 'react';
-import Error from '../Error';
-import Spinner from '../Spinner';
-import { connect } from 'react-redux';
-import { player } from '../../reducers';
-import styles from './PlayerHeader.css';
-
-export const PlayerRecord = ({ loading, error, wins, losses }) => {
- const calcWinPercent = (wins, losses) => Math.ceil(10000 * ((wins) / (wins + losses))) / 100;
-
- const getPlayerRecord = () => {
- if (error) return ;
- if (loading) return ;
- return (
-
-
{`${wins} - ${losses} (${calcWinPercent(wins, losses)}%)`}
-
- );
- };
-
- return (
-
- {getPlayerRecord()}
-
- );
-};
-
-const mapStateToProps = (state) => ({
- loading: player.getLoading(state),
- error: player.getError(state),
- wins: player.getWins(state),
- losses: player.getLosses(state),
-});
-
-
-export default connect(mapStateToProps)(PlayerRecord);
diff --git a/components/Player/PlayerStats.jsx b/components/Player/PlayerStats.jsx
deleted file mode 100644
index 083bdd95e0..0000000000
--- a/components/Player/PlayerStats.jsx
+++ /dev/null
@@ -1,10 +0,0 @@
-import React from 'react';
-import PlayerMMR from './PlayerMMR';
-import PlayerRecord from './PlayerRecord';
-
-export default () => (
-
-);
diff --git a/components/Player/YaspBadge.jsx b/components/Player/YaspBadge.jsx
deleted file mode 100644
index 0a2b6b3e3e..0000000000
--- a/components/Player/YaspBadge.jsx
+++ /dev/null
@@ -1,10 +0,0 @@
-import React from 'react';
-import { HOST_URL } from '../../yasp.config';
-import styles from './PlayerHeader.css';
-
-export default () => (
-
-);
diff --git a/components/Player/index.js b/components/Player/index.js
deleted file mode 100644
index 5914df86e3..0000000000
--- a/components/Player/index.js
+++ /dev/null
@@ -1,5 +0,0 @@
-import Player from './Player';
-import YaspBadge from './YaspBadge';
-
-export default Player;
-export { YaspBadge };
diff --git a/components/Search/Search.jsx b/components/Search/Search.jsx
deleted file mode 100644
index 532a4d83c1..0000000000
--- a/components/Search/Search.jsx
+++ /dev/null
@@ -1,36 +0,0 @@
-import React from 'react';
-
-import { connect } from 'react-redux';
-import { REDUCER_KEY } from '../../reducers';
-import { getSearchResult } from '../../actions';
-
-import SearchForm from './SearchForm';
-import SearchResult from './SearchResult';
-
-const Search = ({ dispatchSearch, data, loading, done }) => (
-
- dispatchSearch(value)}
- />
- {done ? : ''}
-
-);
-
-const mapStateToProps = (state) => {
- const { error, loading, done, searchResults } = state[REDUCER_KEY].gotSearch;
-
- return {
- loading,
- error,
- done,
- data: searchResults,
- };
-};
-
-const mapDispatchToProps = (dispatch) => ({
- dispatchSearch: (query) => dispatch(getSearchResult(query)),
-});
-
-export default connect(mapStateToProps, mapDispatchToProps)(Search);
diff --git a/components/Search/SearchForm.jsx b/components/Search/SearchForm.jsx
deleted file mode 100644
index ea1abb3a5a..0000000000
--- a/components/Search/SearchForm.jsx
+++ /dev/null
@@ -1,47 +0,0 @@
-import React from 'react';
-
-import TextField from 'material-ui/TextField';
-import RaisedButton from 'material-ui/RaisedButton';
-import ActionSearch from 'material-ui/svg-icons/action/search';
-import CircularProgress from 'material-ui/CircularProgress';
-
-import style from './search.css';
-
-const loadingStyle = {
- display: 'block',
- margin: '40px auto 0 auto',
-};
-
-const SearchForm = ({ hintText, onSubmit, disabled }) => {
- let queryValue = '';
-
- const formSubmit = (e) => {
- e.preventDefault();
- onSubmit(queryValue);
- };
- const loadingIndicator = () => (
-
-
-
- );
-
- return (
-
- );
-};
-
-export default SearchForm;
diff --git a/components/Search/SearchResult.jsx b/components/Search/SearchResult.jsx
deleted file mode 100644
index 895d0a6466..0000000000
--- a/components/Search/SearchResult.jsx
+++ /dev/null
@@ -1,24 +0,0 @@
-import React from 'react';
-import SearchResultItem from './SearchResultItem';
-import { List } from 'material-ui/List';
-import style from './search.css';
-
-export default ({ players }) => {
- let playerResult = players.map((player, idx) => (
-
- ));
-
- return (
-
-
- There are {players.length} results {/* TODO replace hardcoded text */}
-
-
{playerResult}
-
- );
-};
diff --git a/components/Search/SearchResultItem.jsx b/components/Search/SearchResultItem.jsx
deleted file mode 100644
index bbee4a5479..0000000000
--- a/components/Search/SearchResultItem.jsx
+++ /dev/null
@@ -1,18 +0,0 @@
-import React from 'react';
-import { Link } from 'react-router';
-import Divider from 'material-ui/Divider';
-import Avatar from 'material-ui/Avatar';
-import { ListItem } from 'material-ui/List';
-
-export default ({ steamId, name, avatarFullUrl }) => (
-
-);
diff --git a/components/Search/index.js b/components/Search/index.js
deleted file mode 100644
index 517d0ee89b..0000000000
--- a/components/Search/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import Search from './Search';
-
-export default Search;
diff --git a/components/Search/search.css b/components/Search/search.css
deleted file mode 100644
index 9d250f64d7..0000000000
--- a/components/Search/search.css
+++ /dev/null
@@ -1,7 +0,0 @@
-.searchResult {
- margin-top: 20px;
-}
-
-.loadingWrapper {
- margin-top: 40px;
-}
diff --git a/components/Spinner/Spinner.jsx b/components/Spinner/Spinner.jsx
deleted file mode 100644
index c47af2f4eb..0000000000
--- a/components/Spinner/Spinner.jsx
+++ /dev/null
@@ -1,4 +0,0 @@
-import React from 'react';
-import CircularProgress from 'material-ui/CircularProgress';
-
-export default ({ size = 1 }) =>
;
diff --git a/components/Spinner/index.js b/components/Spinner/index.js
deleted file mode 100644
index 0484da0db5..0000000000
--- a/components/Spinner/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import Spinner from './Spinner';
-
-export default Spinner;
diff --git a/components/TabBar/TabBar.jsx b/components/TabBar/TabBar.jsx
deleted file mode 100644
index bb90c2c52b..0000000000
--- a/components/TabBar/TabBar.jsx
+++ /dev/null
@@ -1,16 +0,0 @@
-import React from 'react';
-import { Tabs, Tab } from 'material-ui/Tabs';
-import { browserHistory } from 'react-router';
-
- // {overview && (
- // (
-
- browserHistory.push(tab.props.value)} />
- browserHistory.push(tab.props.value)} />
- browserHistory.push(tab.props.value)} />
-
-);
-export default TabBar;
diff --git a/components/TabBar/index.js b/components/TabBar/index.js
deleted file mode 100644
index 51ccf2ee93..0000000000
--- a/components/TabBar/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import TabBar from './TabBar';
-
-export default TabBar;
diff --git a/components/Table/MatchTable.container.jsx b/components/Table/MatchTable.container.jsx
deleted file mode 100644
index 56876a7a80..0000000000
--- a/components/Table/MatchTable.container.jsx
+++ /dev/null
@@ -1,31 +0,0 @@
-import { connect } from 'react-redux';
-import { REDUCER_KEY } from '../../reducers';
-import Table from './Table';
-import createConstantsWrapper from '../Constants';
-import { getMatch, setMatchSort } from '../../actions';
-import { overviewColumns } from './columnDefinitions';
-import { sortMatch, transformMatch } from '../../selectors';
-
-const mapStateToProps = (state) => {
- const { error, loading, sortState, sortField } = state[REDUCER_KEY].gotMatch.match.players;
-
- return {
- loading,
- error,
- data: sortState ? sortMatch(state) : transformMatch(state),
- // data: transformMatch(state),
- sortState,
- sortField,
- // important to set the columns here since we don't have wrapper anymore
- columns: overviewColumns,
- };
-};
-
-const mapDispatchToProps = (dispatch) => ({
- sortClick: (field, sortState, sortFn) => dispatch(setMatchSort(field, sortState, sortFn)),
- getMatch: (playerId, numMatches, host) => dispatch(getMatch(playerId, numMatches, host)),
-});
-
-const TableWrapper = connect(mapStateToProps, mapDispatchToProps)(Table);
-
-export default createConstantsWrapper(TableWrapper);
diff --git a/components/Table/PlayerMatchesTable.container.jsx b/components/Table/PlayerMatchesTable.container.jsx
deleted file mode 100644
index 124ff8eb2b..0000000000
--- a/components/Table/PlayerMatchesTable.container.jsx
+++ /dev/null
@@ -1,30 +0,0 @@
-import { connect } from 'react-redux';
-import { REDUCER_KEY } from '../../reducers';
-import Table from './Table';
-import createConstantsWrapper from '../Constants';
-import { getPlayerMatches, setPlayerMatchesSort } from '../../actions';
-import { playerMatchesColumns } from './columnDefinitions';
-import { sortPlayerMatches, transformPlayerMatches } from '../../selectors';
-
-const mapStateToProps = (state) => {
- const { error, loading, sortState, sortField } = state[REDUCER_KEY].gotPlayer.matches;
-
- return {
- loading,
- error,
- data: sortState ? sortPlayerMatches(state) : transformPlayerMatches(state),
- sortState,
- sortField,
- // important to set the columns here since we don't have wrapper anymore
- columns: playerMatchesColumns,
- };
-};
-
-const mapDispatchToProps = (dispatch) => ({
- sortClick: (field, sortState, sortFn) => dispatch(setPlayerMatchesSort(field, sortState, sortFn)),
- getPlayerMatches: (playerId, numMatches, host) => dispatch(getPlayerMatches(playerId, numMatches, host)),
-});
-
-const TableWrapper = connect(mapStateToProps, mapDispatchToProps)(Table);
-
-export default createConstantsWrapper(TableWrapper);
diff --git a/components/Table/Table.css b/components/Table/Table.css
deleted file mode 100644
index 66e72c27cd..0000000000
--- a/components/Table/Table.css
+++ /dev/null
@@ -1,48 +0,0 @@
-@import "../palette.css";
-
-.container {
- min-width: 100%;
- @media only screen and (max-width: 960px) {
- margin: 0 -25px;
- overflow-x: scroll;
- }
-}
-
-.innerContainer {
- @media only screen and (max-width: 960px) {
- min-width: 1325px;
- }
-}
-
-.header {
- background-color: var(--darkPrimaryColor)!important;
-}
-
-.headerCell {
- display: flex;
- flex-direction: row;
- justify-content: space-between;
- text-align: center;
- & * {
- color: #fff!important;
- }
- &:hover {
- cursor: pointer;
- & span, & div {
- color: var(--primaryTextColor)!important;
- }
- }
-}
-
-.row {
- background-color: #fff;
-}
-
-.row0 {
- composes: row;
-}
-
-.row1 {
- composes: row;
- background-color: #eee;
-}
diff --git a/components/Table/Table.jsx b/components/Table/Table.jsx
deleted file mode 100644
index dca2499c75..0000000000
--- a/components/Table/Table.jsx
+++ /dev/null
@@ -1,56 +0,0 @@
-// TODO - consume the new action, read it in mstp of table, pass down the sort fn action and the
-// sorted state through mstp/mdtp, and add the sorting functions to the column definition
-
-import React from 'react';
-import {
- Table as MaterialTable,
- TableBody as MaterialTableBody,
- TableHeader as MaterialTableHeader,
-} from 'material-ui/Table';
-import TableHeader from './TableHeader';
-import Spinner from '../Spinner';
-import Error from '../Error';
-import styles from './Table.css';
-import TableRow from './TableRow';
-import { getTotalWidth } from './tableHelpers';
-
-const Table = ({ data, columns, loading, error, sortState, sortField, sortClick }) => {
- const totalWidth = getTotalWidth(columns);
-
- const getTable = () => (
-
-
-
-
-
-
- {data.map((row, index) => (
-
- ))}
-
-
-
- );
-
- return (
-
- {loading && }
- {!loading && error && }
- {!loading && !error && getTable()}
-
- );
-};
-
-export default Table;
diff --git a/components/Table/TableHeader.jsx b/components/Table/TableHeader.jsx
deleted file mode 100644
index e7e78da790..0000000000
--- a/components/Table/TableHeader.jsx
+++ /dev/null
@@ -1,20 +0,0 @@
-import React from 'react';
-import { TableRow as MaterialTableRow } from 'material-ui/Table';
-import TableHeaderColumn from './TableHeaderColumn';
-
-const TableHeader = ({ columns, sortState, sortField, sortClick, totalWidth }) => (
-
- {columns.map((column, index) => (
-
- ))}
-
-);
-
-export default TableHeader;
diff --git a/components/Table/TableHeaderColumn.jsx b/components/Table/TableHeaderColumn.jsx
deleted file mode 100644
index 550678f0c9..0000000000
--- a/components/Table/TableHeaderColumn.jsx
+++ /dev/null
@@ -1,28 +0,0 @@
-import React from 'react';
-import {
- getWidthStyle,
- isSortField,
- getSortIcon,
-} from './tableHelpers';
-import { TableHeaderColumn as MaterialTableHeaderColumn } from 'material-ui/Table';
-import styles from './Table.css';
-import FontIcon from 'material-ui/FontIcon';
-import { Text } from '../Text';
-
-export default ({ column, sortClick, sortField, sortState, totalWidth }) => (
-
- sortClick(column.field, isSortField(sortField, column.field) ? sortState : '', column.sortFn)}
- >
- {column.displayName}
- {column.sortFn && (
-
- {getSortIcon(sortState, sortField, column.field)}
-
- )}
-
-
-);
diff --git a/components/Table/TableRow.jsx b/components/Table/TableRow.jsx
deleted file mode 100644
index 01212e2822..0000000000
--- a/components/Table/TableRow.jsx
+++ /dev/null
@@ -1,12 +0,0 @@
-import React from 'react';
-import { TableRow as MaterialTableRow } from 'material-ui/Table';
-import TableRowColumn from './TableRowColumn';
-import styles from './Table.css';
-
-export default ({ row, columns, totalWidth, index }) => (
-
- {columns.map((column, colIndex) => (
-
- ))}
-
-);
diff --git a/components/Table/TableRowColumn.jsx b/components/Table/TableRowColumn.jsx
deleted file mode 100644
index d67a063245..0000000000
--- a/components/Table/TableRowColumn.jsx
+++ /dev/null
@@ -1,10 +0,0 @@
-import React from 'react';
-import { TableRowColumn as MaterialTableRowColumn } from 'material-ui/Table';
-import { getWidthStyle } from './tableHelpers';
-
-export default ({ row, column, totalWidth }) => (
-
- {row && column.displayFn && column.displayFn({ row, column, field: row[column.field] })}
- {row && row[column.field] && !column.displayFn && (row[column.field].display || row[column.field].display)}
-
-);
diff --git a/components/Table/columnDefinitions/column.css b/components/Table/columnDefinitions/column.css
deleted file mode 100644
index 5890908cf7..0000000000
--- a/components/Table/columnDefinitions/column.css
+++ /dev/null
@@ -1,17 +0,0 @@
-.teamIndicator {
- opacity: .5;
- height: 30px;
- width: 7px;
- display: inline-block;
- margin-right: 3px;
-}
-
-.dire {
- composes: teamIndicator;
- background-color: #CD5C5C;
-}
-
-.radiant {
- composes: teamIndicator;
- background-color: #66CD00;
-}
diff --git a/components/Table/columnDefinitions/index.js b/components/Table/columnDefinitions/index.js
deleted file mode 100644
index d70057a4fa..0000000000
--- a/components/Table/columnDefinitions/index.js
+++ /dev/null
@@ -1,4 +0,0 @@
-import playerMatchesColumns from './playerMatchesColumns';
-import { overviewColumns } from './matchColumns';
-
-export { playerMatchesColumns, overviewColumns };
diff --git a/components/Table/columnDefinitions/matchColumns.jsx b/components/Table/columnDefinitions/matchColumns.jsx
deleted file mode 100644
index 496adc049c..0000000000
--- a/components/Table/columnDefinitions/matchColumns.jsx
+++ /dev/null
@@ -1,96 +0,0 @@
-import React from 'react';
-import { Link } from 'react-router';
-import { YaspBadge } from '../../Player';
-import { defaultSort } from './utility';
-import styles from './column.css';
-
-const overviewColumns = [{
- displayName: 'Hero',
- field: 'hero_id',
- width: 3.5,
- displayFn: ({ field, row }) => (
-
-
-
-
- {row.last_login && row.last_login.value &&
}
-
- {row.account_id.value ?
{row.personaname.value} : 'Anonymous'}
-
- ),
-}, {
- displayName: 'LVL',
- field: 'level',
- width: 1.5,
- sortFn: defaultSort,
-}, {
- displayName: 'K',
- field: 'kills',
- width: 1.5,
- sortFn: defaultSort,
-}, {
- displayName: 'D',
- field: 'deaths',
- width: 1.5,
- sortFn: defaultSort,
-}, {
- displayName: 'A',
- field: 'assists',
- width: 1.5,
- sortFn: defaultSort,
-}, {
- displayName: 'LH',
- field: 'last_hits',
- width: 2,
- sortFn: defaultSort,
-}, {
- displayName: 'D',
- field: 'denies',
- width: 1,
- sortFn: defaultSort,
-}, {
- displayName: 'G',
- field: '',
- width: 2,
- displayFn: ({ row }) => `${(row.gold_per_min.value * row.duration.value / 60 / 1000).toFixed(1)}K`,
-}, {
- displayName: 'GPM',
- field: 'gold_per_min',
- width: 2,
- sortFn: defaultSort,
-}, {
- displayName: 'XPM',
- field: 'xp_per_min',
- width: 2,
- sortFn: defaultSort,
-}, {
- displayName: 'HD',
- field: 'hero_damage',
- width: 2,
- sortFn: defaultSort,
-}, {
- displayName: 'TD',
- field: 'tower_damage',
- width: 2,
- sortFn: defaultSort,
-}, {
- displayName: 'HH',
- field: 'hero_healing',
- width: 1,
- sortFn: defaultSort,
-}, {
- displayName: 'Items',
- field: '',
- width: 7,
- displayFn: ({ row }) => {
- const itemArray = [];
- for (let i = 0; i < 6; i++) {
- if (row[`item_${i}`].display) {
- itemArray.push( );
- }
- }
- return itemArray;
- },
-}];
-
-export { overviewColumns };
diff --git a/components/Table/columnDefinitions/playerMatchesColumns.js b/components/Table/columnDefinitions/playerMatchesColumns.js
deleted file mode 100644
index 0084b18f7b..0000000000
--- a/components/Table/columnDefinitions/playerMatchesColumns.js
+++ /dev/null
@@ -1,52 +0,0 @@
-import React from 'react';
-import { defaultSort, useOriginalValueSort } from './utility';
-import { Link } from 'react-router';
-
-export default [{
- displayName: 'ID',
- field: 'match_id',
- width: 2,
- sortFn: defaultSort,
- displayFn: ({ field }) => {field.display},
-}, {
- displayName: 'Hero',
- field: 'hero_id',
- width: 1.5,
- sortFn: defaultSort,
- displayFn: ({ field }) => ,
-}, {
- displayName: 'W/L',
- field: 'radiant_win',
- width: 1.5,
- sortFn: defaultSort,
-}, {
- displayName: 'Mode',
- field: 'game_mode',
- width: 2.5,
- sortFn: defaultSort,
-}, {
- displayName: 'Date',
- field: 'start_time',
- width: 2,
- sortFn: useOriginalValueSort,
-}, {
- displayName: 'Duration',
- field: 'duration',
- width: 2,
- sortFn: useOriginalValueSort,
-}, {
- displayName: 'Kills',
- field: 'kills',
- width: 1.8,
- sortFn: defaultSort,
-}, {
- displayName: 'Deaths',
- field: 'deaths',
- width: 1.8,
- sortFn: defaultSort,
-}, {
- displayName: 'Assists',
- field: 'assists',
- width: 1.8,
- sortFn: defaultSort,
-}];
diff --git a/components/Table/columnDefinitions/utility.js b/components/Table/columnDefinitions/utility.js
deleted file mode 100644
index da2255e8d9..0000000000
--- a/components/Table/columnDefinitions/utility.js
+++ /dev/null
@@ -1,7 +0,0 @@
-export const defaultSort = (array, field, property = 'display') => array.sort((a, b) => {
- if (a[field][property] < b[field][property]) return -1;
- if (a[field][property] > b[field][property]) return 1;
- return 0;
-});
-
-export const useOriginalValueSort = (array, field) => defaultSort(array, field, 'value');
diff --git a/components/Table/index.js b/components/Table/index.js
deleted file mode 100644
index 9778ad24a2..0000000000
--- a/components/Table/index.js
+++ /dev/null
@@ -1,6 +0,0 @@
-import Table from './Table';
-import PlayerMatchesTable from './PlayerMatchesTable.container';
-import MatchTable from './MatchTable.container';
-
-export default Table;
-export { PlayerMatchesTable, MatchTable, Table };
diff --git a/components/Table/tableHelpers.js b/components/Table/tableHelpers.js
deleted file mode 100644
index f02ddda8b0..0000000000
--- a/components/Table/tableHelpers.js
+++ /dev/null
@@ -1,24 +0,0 @@
-const getTotalWidth = (columns) => columns.reduce((prev, current) => prev + current.width, 0);
-
-const getWidthStyle = (column, total) => ({ width: `${column / total}%` });
-
-const isSortField = (sortField, field) => sortField === field;
-
-const getSortIcon = (sortState, sortField, field) => {
- let sort = 'sort';
- if (isSortField(sortField, field)) {
- if (sortState === 'asc') {
- sort = 'arrow_upward';
- } else if (sortState === 'desc') {
- sort = 'arrow_downward';
- }
- }
- return sort;
-};
-
-export {
- getTotalWidth,
- getWidthStyle,
- isSortField,
- getSortIcon,
-};
diff --git a/components/Text/Text.css b/components/Text/Text.css
deleted file mode 100644
index ec254ed37a..0000000000
--- a/components/Text/Text.css
+++ /dev/null
@@ -1,5 +0,0 @@
-@import "../palette.css";
-
-.text {
- color: var(--primaryTextColor);
-}
diff --git a/components/Text/Text.jsx b/components/Text/Text.jsx
deleted file mode 100644
index 44b380491f..0000000000
--- a/components/Text/Text.jsx
+++ /dev/null
@@ -1,13 +0,0 @@
-import React from 'react';
-import styles from './Text.css';
-
-export default ({ color, size, children }) => {
- const propStyles = { };
- if (color) {
- propStyles.color = color;
- }
- if (size) {
- propStyles.fontSize = size;
- }
- return {children}
;
-};
diff --git a/components/Text/index.js b/components/Text/index.js
deleted file mode 100644
index adfffafb83..0000000000
--- a/components/Text/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import Text from './Text';
-
-export { Text };
diff --git a/components/palette.css b/components/palette.css
deleted file mode 100644
index a4df58ed75..0000000000
--- a/components/palette.css
+++ /dev/null
@@ -1,23 +0,0 @@
-:root {
- --darkPrimaryColor: #388E3C;
- --defaultPrimaryColor: #4CAF50;
- --lightPrimaryColor: #C8E6C9;
- --textPrimaryColor: #FFFFFF;
- --accentColor: #FF5722;
-
- --primaryTextColor: #212121;
- --secondaryTextColor: #727272;
-
- --primaryLinkColor: #42A5F5;
-
- --dividerColor: #B6B6B6;
-
- /* font sizes */
- --normalFontSize: 12px;
- --mediumLargeFontSize: 16px;
- --fontFamily: 'Roboto', sans-serif;
-
- --navDrawerWidth: 256px;
- --normalTransition: all 450ms cubic-bezier(0.23, 1, 0.32, 1) 0ms;
- --linearTransition: all 450ms linear 0ms;
-}
diff --git a/components/palette2.css b/components/palette2.css
deleted file mode 100644
index 285c869c62..0000000000
--- a/components/palette2.css
+++ /dev/null
@@ -1,8 +0,0 @@
-.dark-primary-color { background: #E64A19; }
-.default-primary-color { background: #FF5722; }
-.light-primary-color { background: #FFCCBC; }
-.text-primary-color { color: #FFFFFF; }
-.accent-color { background: #4CAF50; }
-.primary-text-color { color: #212121; }
-.secondary-text-color { color: #727272; }
-.divider-color { border-color: #B6B6B6; }
diff --git a/crowdin.yaml b/crowdin.yaml
new file mode 100644
index 0000000000..3abba759a9
--- /dev/null
+++ b/crowdin.yaml
@@ -0,0 +1,3 @@
+files:
+ - source: /src/lang/en-US.json
+ translation: /src/lang/%locale%.json
diff --git a/deploy.sh b/deploy.sh
deleted file mode 100755
index 4f392d9822..0000000000
--- a/deploy.sh
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/bin/bash
-
-git config user.name "Travis CI"
-git config user.email "travis@travis-ci.org"
-
-git remote add upstream "https://$GH_TOKEN@github.com/yasp-dota/ui.git"
-git add --all
-git add --force build
-git commit -m "Build $TRAVIS_COMMIT"
-git push -f upstream HEAD:gh-pages
\ No newline at end of file
diff --git a/dev/migrateLangFormat.ts b/dev/migrateLangFormat.ts
new file mode 100644
index 0000000000..bd03c28b91
--- /dev/null
+++ b/dev/migrateLangFormat.ts
@@ -0,0 +1,50 @@
+import fs from "node:fs";
+import path from "node:path";
+
+const langsPath = path.resolve(__dirname, "../src/lang");
+const oldLangsPath = path.resolve(__dirname, "../src/lang/old");
+const excludedLangKeys = ["title_template"];
+const langs = fs
+ .readdirSync(langsPath)
+ .filter((dir) => [".", "..", "old", "index.js"].includes(dir) === false);
+
+if (!fs.existsSync(oldLangsPath)) {
+ fs.mkdirSync(oldLangsPath);
+}
+
+langs.forEach((langFile) => {
+ // Make a backup of the old file.
+ if (!fs.existsSync(path.resolve(oldLangsPath, langFile))) {
+ fs.copyFileSync(
+ path.resolve(langsPath, langFile),
+ path.resolve(oldLangsPath, langFile),
+ );
+ }
+
+ const lang = JSON.parse(
+ fs.readFileSync(path.resolve(langsPath, langFile).toString()),
+ );
+ const pattern = /(%[^\s^%]+)/g;
+ const updatedLang = {};
+ Object.entries(lang).map(([langKey, string]) => {
+ let count = 0;
+ const replaced = string.split(pattern).map((split) => {
+ if (
+ excludedLangKeys.includes(langKey) === false &&
+ split.match(pattern)
+ ) {
+ // eslint-disable-next-line no-plusplus
+ return `{${count++}}`;
+ }
+
+ return split;
+ });
+ updatedLang[langKey] = replaced.join("");
+ return updatedLang[langKey];
+ });
+
+ fs.writeFileSync(
+ path.resolve(langsPath, langFile),
+ JSON.stringify(updatedLang, undefined, " "),
+ );
+});
diff --git a/dev/updateEmoticons.ts b/dev/updateEmoticons.ts
new file mode 100644
index 0000000000..f88fd408c3
--- /dev/null
+++ b/dev/updateEmoticons.ts
@@ -0,0 +1,13 @@
+import fs from "fs";
+
+process.chdir(__dirname);
+
+try {
+ fs.copyFileSync(
+ "../node_modules/dota2-emoticons/resources/images/emoticons",
+ "../assets/images/dota2/emoticons",
+ );
+ console.log("Success!");
+} catch (err) {
+ console.error(err);
+}
diff --git a/dev/updatelangvpk.ts b/dev/updatelangvpk.ts
new file mode 100644
index 0000000000..09371449a4
--- /dev/null
+++ b/dev/updatelangvpk.ts
@@ -0,0 +1,172 @@
+/* eslint-disable import/no-extraneous-dependencies, no-console, import/no-unresolved */
+import fs from "fs";
+import vdf from "vdf-parser";
+// For updating the opendota-ui lang files with data from the vpk
+
+const dontReplace = [
+ "npc_dota_brewmaster_earth_#",
+ "npc_dota_brewmaster_fire_#",
+ "npc_dota_brewmaster_storm_#",
+ "game_mode_22",
+];
+
+// links langTag to the language file in the vpk
+// null indicates that dota does not support this language
+const langTagNames = {
+ "bg-BG": "bulgarian",
+ "cs-CZ": "czech",
+ "da-DK": "danish",
+ "de-DE": "german",
+ "el-GR": "greek",
+ // 'en-US': 'english', // commented out because we don't want to mess up the spacing
+ "es-ES": "spanish",
+ "es-PE": "spanish",
+ "es-US": "spanish",
+ "fi-FI": "finnish",
+ "fr-FR": "french",
+ "he-IL": null,
+ "hu-HU": "hungarian",
+ "it-IT": "italian",
+ "ja-JP": "japanese",
+ "ko-KR": "korean",
+ "ms-MY": null,
+ "nl-NL": "dutch",
+ "no-NO": "norwegian",
+ "pl-PL": "polish",
+ "pt-BR": "portuguese",
+ "pt-PT": "portuguese",
+ "ro-RO": "romanian",
+ "ru-RU": "russian",
+ "sk-SK": null,
+ "sr-SP": null,
+ "sv-SE": "swedish",
+ "th-TH": "thai",
+ "tr-TR": "turkish",
+ "uk-UA": "ukrainian",
+ "vi-VN": null,
+ "zh-CN": "schinese",
+ "zh-TW": "tchinese",
+};
+
+// The rest of these are build later on
+const replacements = {
+ rune_0: "DOTA_Tooltip_rune_doubledamage",
+ rune_1: "DOTA_Tooltip_rune_haste",
+ rune_2: "DOTA_Tooltip_rune_illusion",
+ rune_3: "DOTA_Tooltip_rune_invisibility",
+ rune_4: "DOTA_Tooltip_rune_regeneration",
+ rune_5: "DOTA_Tooltip_rune_bounty",
+ rune_6: "DOTA_Tooltip_rune_arcane",
+};
+
+const langDir = "src/lang/";
+
+let englishLang = null;
+try {
+ englishLang = JSON.parse(fs.readFileSync(`${langDir}en-US.json`, "utf8"));
+} catch (ex) {
+ console.log("Couldn't find en-US.json in the specified directory");
+ process.exit(1);
+}
+
+const updateLang = (langTag, langName) => {
+ if (!langName) {
+ return; // Means dota doesn't have this lang file
+ }
+ const stringsUrl = `https://raw.githubusercontent.com/dotabuff/d2vpkr/master/dota/resource/dota_${langName}.json`;
+ const langFilename = `${langDir}${langTag}.json`;
+
+ request(stringsUrl, (err, resp, body) => {
+ console.log(`${langTag} <= ${langName}`);
+ if (err || resp.statusCode !== 200) {
+ console.log(`Error ${resp.statusCode} when getting ${langName}: ${err}`);
+ process.exit(1);
+ }
+ const strings = JSON.parse(body).lang.Tokens;
+
+ let lang = null;
+ try {
+ lang = JSON.parse(fs.readFileSync(langFilename, "utf8"));
+ } catch (ex) {
+ console.log(`${ex.name} when reading ${langTag}: ${ex.message}`);
+ process.exit(1);
+ }
+
+ Object.keys(replacements).forEach((key) => {
+ if (
+ (!lang[key] || lang[key] === englishLang[key]) &&
+ replacements[key] in strings
+ ) {
+ let result = strings[replacements[key]];
+ if (["chatwheel_71", "chatwheel_72"].indexOf(key) >= 0) {
+ result = result.replace(/%s1/, strings.DOTA_Shared_Unit_Control_Hero);
+ }
+ lang[key] = result;
+ }
+ });
+
+ let outString = JSON.stringify(lang, null, 2);
+ // Fix "key": "value" to "key":"value", because thats how it is currently
+ outString = outString.replace(/": "/g, '":"');
+
+ fs.writeFile(langFilename, outString, "utf8");
+ });
+};
+
+// Build the rest of replacements here
+// game modes
+for (let i = 0; `game_mode_${i}` in englishLang; i += 1) {
+ replacements[`game_mode_${i}`] = `game_mode_lobby_name_${i}`;
+}
+// npc_dota_(unitstrings)
+Object.keys(englishLang)
+ .filter((k) => k.match(/^npc_dota_/))
+ .forEach((key) => {
+ replacements[key] = key.replace("#", "1");
+ });
+replacements.npc_dota_phoenix_sun = "DOTA_Tooltip_ability_phoenix_supernova";
+replacements.npc_dota_weaver_swarm = "DOTA_Tooltip_ability_weaver_the_swarm";
+// regions, chat wheel, & call update
+request(
+ "https://raw.githubusercontent.com/dotabuff/d2vpkr/master/dota/scripts/regions.json",
+ (err, resp, body) => {
+ if (err || resp.statusCode !== 200) {
+ console.log("Error getting regions info from d2vpkr");
+ process.exit(1);
+ }
+ const { regions } = JSON.parse(body);
+
+ Object.keys(regions).forEach((key) => {
+ replacements[`region_${regions[key].region}`] = regions[
+ key
+ ].display_name.replace(/^#/, "");
+ });
+ request(
+ "https://raw.githubusercontent.com/dotabuff/d2vpkr/master/dota/scripts/chat_wheel.txt",
+ (_err, _resp, _body) => {
+ if (_err || _resp.statusCode !== 200) {
+ console.log("Error getting chat wheel info from d2vpkr");
+ process.exit(1);
+ }
+ const chatWheel = vdf.parse(_body).chat_wheel.messages;
+
+ Object.keys(chatWheel).forEach((key) => {
+ if (chatWheel[key].message[0] === "#") {
+ replacements[`chatwheel_${chatWheel[key].message_id}`] = chatWheel[
+ key
+ ].message.replace(/^#/, "");
+ }
+ });
+
+ // Remove ones we don't want to replace
+ dontReplace.forEach((key) => {
+ delete replacements[key];
+ });
+ console.log("Updating lang files...");
+ Object.keys(langTagNames).forEach((tag) =>
+ updateLang(tag, langTagNames[tag]),
+ );
+ },
+ );
+ },
+);
diff --git a/global.css b/global.css
deleted file mode 100644
index c0d9445bfa..0000000000
--- a/global.css
+++ /dev/null
@@ -1,33 +0,0 @@
-@import "./components/palette.css";
-
-:global(body) {
- margin: 0;
- color: var(--primaryTextColor);
- font-family: var(--fontFamily);
- height: 100%;
-}
-
-:global(.flaticon) {
- font-family: Flaticon;
-}
-
-:global(a) {
- text-decoration: none;
- color: var(--primaryLinkColor);
- &:hover {
- color: color(var(--primaryLinkColor) lightness(-33%));
- }
-}
-
-:global(li) {
- list-style-type: none;
-}
-
-:global(html) {
- height: 100%;
-}
-
-:global(#react) {
- height: 100%;
- overflow-x: hidden;
-}
diff --git a/index.html b/index.html
index 977fd421c6..8f60be4354 100644
--- a/index.html
+++ b/index.html
@@ -1,36 +1,94 @@
-
+
-
-
- YASP - Open Source Dota 2 Statistics
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+ OpenDota - Dota 2 Statistics
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
+ Looks like your browser isn't allowing scripts! Enable JavaScript to run
+ this app.
+
+
+
-