diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 0000000..6c9a860 --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,45 @@ +module.exports = { + parser: 'babel-eslint', + env: { + browser: true, + es6: true, + }, + extends: ['airbnb', 'airbnb/hooks', 'prettier', 'prettier/react', 'plugin:prettier/recommended'], + globals: { + Atomics: 'readonly', + SharedArrayBuffer: 'readonly', + }, + parserOptions: { + ecmaFeatures: { + jsx: true, + legacyDecorators: true, + }, + ecmaVersion: 2018, + sourceType: 'module', + }, + plugins: ['react', 'prettier'], + rules: { + 'import/extensions': 0, + 'prettier/prettier': 'error', + 'react/jsx-filename-extension': [1, { extensions: ['.js', '.jsx'] }], + + /* 确定不会发生改变的规则 */ + 'react/jsx-props-no-spreading': 0, // 允许 jsx 属性使用扩展运算符 + 'react/prop-types': 0, // 不需要使用 prop-types 检查组件 props + 'import/prefer-default-export': 0, // 不需要优先使用默认导出 + 'import/no-unresolved': 0, + 'react/no-array-index-key': 0, + /* 可能会改变的规则 */ + 'react/react-in-jsx-scope': 0, // 使用 jsx 的组件无需引入 React + // 移动端大部分不需要键盘事件 + 'jsx-a11y/click-events-have-key-events': 0, + // 无障碍暂时用不到 + 'jsx-a11y/no-static-element-interactions': 0, + // 后台返回的字段不是驼峰的 + camelcase: 0, + // 这个限制太片面了,https://github.com/eslint/eslint/issues/10482 + 'no-restricted-properties': 0, + // 全局方法无法使用 + 'no-restricted-globals': 0, + }, +}; diff --git a/package.json b/package.json index f6c7705..58daa27 100755 --- a/package.json +++ b/package.json @@ -11,14 +11,29 @@ "dependencies": { "classnames": "^2.2.6", "lodash": "^4.17.15", + "node-sass": "^4.14.1", "prop-types": "^15.7.2", "react": "^16.12.0", "react-dom": "^16.12.0", "react-redux": "^7.2.0", - "redux": "^4.0.5" + "redux": "^4.0.5", + "eslint": "^6.7.1", + "eslint-config-airbnb": "^18.0.1", + "eslint-config-prettier": "^6.7.0", + "eslint-plugin-import": "^2.18.2", + "eslint-plugin-jsx-a11y": "^6.2.3", + "eslint-plugin-prettier": "^3.1.1", + "eslint-plugin-react": "^7.16.0", + "eslint-plugin-react-hooks": "^1.7.0", + "prettier": "^1.19.1" }, "devDependencies": { "react-scripts": "3.4.0" }, - "browserslist": [">0.2%", "not dead", "not ie <= 11", "not op_mini all"] + "browserslist": [ + ">0.2%", + "not dead", + "not ie <= 11", + "not op_mini all" + ] } diff --git a/src/actions/PlayersActions.js b/src/actions/PlayersActions.js index 8f427c2..40108f2 100755 --- a/src/actions/PlayersActions.js +++ b/src/actions/PlayersActions.js @@ -1,22 +1,30 @@ -import * as types from '../constants/ActionTypes'; +import * as types from "../constants/ActionTypes"; -export function addPlayer(name) { +export function addPlayer(name, optionId) { return { type: types.ADD_PLAYER, name, + optionId }; } export function deletePlayer(id) { return { type: types.DELETE_PLAYER, - id, + id }; } export function starPlayer(id) { return { type: types.STAR_PLAYER, - id, + id + }; +} + +export function changePage(current) { + return { + type: types.CHANGE_PAGE, + current }; } diff --git a/src/components/AddPlayerInput.js b/src/components/AddPlayerInput.js index 5d914d8..0dd684e 100755 --- a/src/components/AddPlayerInput.js +++ b/src/components/AddPlayerInput.js @@ -1,27 +1,16 @@ -import React, { Component } from 'react'; -import classnames from 'classnames'; -import PropTypes from 'prop-types'; -import styles from './AddPlayerInput.css'; +import React, { Component } from "react"; +import classnames from "classnames"; +import PropTypes from "prop-types"; +import OptionSelect from "./OptionSelect/index.js"; +import styles from "./AddPlayerInput.css"; class AddPlayerInput extends Component { - render() { - return ( - - ); - } - constructor(props, context) { super(props, context); this.state = { - name: this.props.name || '', + // eslint-disable-next-line react/destructuring-assignment + name: this.props.name || "", + optionId: 0 }; } @@ -31,15 +20,42 @@ class AddPlayerInput extends Component { handleSubmit(e) { const name = e.target.value.trim(); + const { optionId } = this.state; if (e.which === 13) { - this.props.addPlayer(name); - this.setState({ name: '' }); + // eslint-disable-next-line react/destructuring-assignment + this.props.addPlayer(name, optionId); + this.setState({ name: "" }); } } + + handleSelectChange(optionId) { + this.setState({ optionId }); + } + + render() { + const { positionList } = this.props; + const { name } = this.state; + return ( + + this.handleSelectChange(e)} + /> + + + ); + } } AddPlayerInput.propTypes = { - addPlayer: PropTypes.func.isRequired, + addPlayer: PropTypes.func.isRequired }; export default AddPlayerInput; diff --git a/src/components/OptionSelect/index.js b/src/components/OptionSelect/index.js new file mode 100644 index 0000000..b921d00 --- /dev/null +++ b/src/components/OptionSelect/index.js @@ -0,0 +1,23 @@ +import React from "react"; + +function OptionSelect(props) { + const { positionList, onSelectChange } = props; + + const onChange = e => { + onSelectChange(e.target.value.trim()); + }; + + return ( + + ); +} + +export default OptionSelect; diff --git a/src/components/PageList/index.css b/src/components/PageList/index.css new file mode 100644 index 0000000..b3ed095 --- /dev/null +++ b/src/components/PageList/index.css @@ -0,0 +1,30 @@ +.pageList{ + padding-left: 0; + margin-bottom: 0; + list-style: none; + } + +.btnAction{ + width: 20px; + height: 20px; + background: white; + text-align: center; + float: left; + margin-left: 5px; + cursor: pointer; + border: 1px solid #5c75b0; + } +.active{ + color: white; + background-color: #5c75b0; +} +.btnAction:focus, +.btnAction:hover { + color: white; + background-color: #5c75b0; +} + +ul { + list-style-type: none; + padding: 0; +} diff --git a/src/components/PageList/index.js b/src/components/PageList/index.js new file mode 100644 index 0000000..265b4ed --- /dev/null +++ b/src/components/PageList/index.js @@ -0,0 +1,32 @@ +import React from "react"; +import classNames from "classnames"; +// eslint-disable-next-line no-unused-vars +import styles from "./index.css"; + +function PageList(props) { + const { total, changePage, current } = props; + const totalPageList = []; + for (let i = 0; i < total; i += 1) { + totalPageList.push({ pageId: i + 1 }); + } + return ( + + ); +} + +export default PageList; diff --git a/src/components/PlayerList.js b/src/components/PlayerList.js index 7b40246..275621a 100755 --- a/src/components/PlayerList.js +++ b/src/components/PlayerList.js @@ -1,13 +1,16 @@ -import React, { Component } from 'react'; -import PropTypes from 'prop-types'; -import styles from './PlayerList.css'; -import PlayerListItem from './PlayerListItem'; +/* eslint-disable react/forbid-prop-types */ +/* eslint-disable react/prefer-stateless-function */ +import React, { Component } from "react"; +import PropTypes from "prop-types"; +import styles from "./PlayerList.css"; +import PlayerListItem from "./PlayerListItem"; class PlayerList extends Component { render() { + const { players, actions } = this.props; return (