diff --git a/package.json b/package.json index f6c7705..61c0d8b 100755 --- a/package.json +++ b/package.json @@ -15,10 +15,19 @@ "react": "^16.12.0", "react-dom": "^16.12.0", "react-redux": "^7.2.0", - "redux": "^4.0.5" + "redux": "^4.0.5", + "save-dev": "0.0.1-security" }, "devDependencies": { - "react-scripts": "3.4.0" + "enzyme": "^3.11.0", + "enzyme-adapter-react-16": "^1.15.2", + "react-scripts": "^3.4.0", + "react-test-renderer": "^16.13.1" }, - "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/App.test.js b/src/App.test.js index b84af98..8ff66bf 100755 --- a/src/App.test.js +++ b/src/App.test.js @@ -1,8 +1,19 @@ import React from 'react'; import ReactDOM from 'react-dom'; import App from './App'; +import PageList from './components/PageList' +import shallow from 'enzyme' it('renders without crashing', () => { const div = document.createElement('div'); ReactDOM.render(, div); }); + +describe('PageList component',()=>{ + const props = { + totalPageNumber:6, + curPageNumber:1, + } +}) + + diff --git a/src/actions/PlayersActions.js b/src/actions/PlayersActions.js index 8f427c2..9368fc9 100755 --- a/src/actions/PlayersActions.js +++ b/src/actions/PlayersActions.js @@ -1,9 +1,10 @@ import * as types from '../constants/ActionTypes'; -export function addPlayer(name) { +export function addPlayer(name,optionId) { return { type: types.ADD_PLAYER, name, + optionId, }; } @@ -20,3 +21,10 @@ export function starPlayer(id) { id, }; } + +export function changePage(curPageNumber) { + return { + type: types.CHANGE_PAGE, + curPageNumber, + }; +} diff --git a/src/components/AddPlayerInput.css b/src/components/AddPlayerInput.css index 1507c6e..3f6d975 100755 --- a/src/components/AddPlayerInput.css +++ b/src/components/AddPlayerInput.css @@ -4,3 +4,7 @@ border-left: 0; border-right: 0; } + +.inlineBlock{ + display:inline-block +} diff --git a/src/components/AddPlayerInput.js b/src/components/AddPlayerInput.js index 5d914d8..3047a9d 100755 --- a/src/components/AddPlayerInput.js +++ b/src/components/AddPlayerInput.js @@ -2,19 +2,25 @@ import React, { Component } from 'react'; import classnames from 'classnames'; import PropTypes from 'prop-types'; import styles from './AddPlayerInput.css'; +import PositionSelect from './PositionSelect' class AddPlayerInput extends Component { render() { + const { positionList } = this.props; return ( - + + /> + + + ); } @@ -22,9 +28,14 @@ class AddPlayerInput extends Component { super(props, context); this.state = { name: this.props.name || '', + optionId: 0, }; } + handleSelectChange(optionId){ + this.setState({ optionId: optionId }); + } + handleChange(e) { this.setState({ name: e.target.value }); } @@ -32,7 +43,7 @@ class AddPlayerInput extends Component { handleSubmit(e) { const name = e.target.value.trim(); if (e.which === 13) { - this.props.addPlayer(name); + this.props.addPlayer(name,this.state.optionId); this.setState({ name: '' }); } } diff --git a/src/components/PageList.css b/src/components/PageList.css new file mode 100644 index 0000000..0514a7b --- /dev/null +++ b/src/components/PageList.css @@ -0,0 +1,24 @@ +.pageList{ + padding-left: 0; + margin-bottom: 0; + list-style: none; + } + +.pageBtnAction{ + width: 20px; + height: 20px; + background: white; + text-align: center; + float: left; + margin-left: 5px; + cursor: pointer; + } +.active{ + color: white; + background-color: #5c75b0; +} +.pageBtnAction:focus, +.pageBtnAction:hover { + color: white; + background-color: #5c75b0; +} diff --git a/src/components/PageList.js b/src/components/PageList.js new file mode 100644 index 0000000..afce59b --- /dev/null +++ b/src/components/PageList.js @@ -0,0 +1,23 @@ +import React, { Component } from 'react'; +import styles from './PageList.css'; +import classNames from 'classnames' + +class PageList extends Component { + render() { + let totalPageList = []; + for(let i = 0;i < this.props.totalPageNumber;i++){ + totalPageList.push({pageId:i+1}); + } + return ( + + ); + } +} + +export default PageList; \ No newline at end of file diff --git a/src/components/PositionSelect.css b/src/components/PositionSelect.css new file mode 100644 index 0000000..95b17ec --- /dev/null +++ b/src/components/PositionSelect.css @@ -0,0 +1,6 @@ +.positionOption{ + position: absolute; + display: inline-block; + height: 34px; + border-radius: 4px; +} \ No newline at end of file diff --git a/src/components/PositionSelect.js b/src/components/PositionSelect.js new file mode 100644 index 0000000..a1ef0eb --- /dev/null +++ b/src/components/PositionSelect.js @@ -0,0 +1,23 @@ +import React, { Component } from 'react'; +import {styles} from './PositionSelect.css' + +class PositionSelect extends Component { + render() { + const { + positionList + } = this.props; + return () + } + + onSelectChange(e){ + this.props.onSelectChange(e.target.value.trim()); + } +} + +export default PositionSelect; \ No newline at end of file diff --git a/src/components/index.js b/src/components/index.js index 12ce117..15709ef 100755 --- a/src/components/index.js +++ b/src/components/index.js @@ -1,3 +1,5 @@ export { default as AddPlayerInput } from './AddPlayerInput'; export { default as PlayerList } from './PlayerList'; export { default as PlayerListItem } from './PlayerListItem'; +export { default as PageList } from './PageList'; + diff --git a/src/constants/ActionTypes.js b/src/constants/ActionTypes.js index b796fae..505b906 100755 --- a/src/constants/ActionTypes.js +++ b/src/constants/ActionTypes.js @@ -1,3 +1,4 @@ export const ADD_PLAYER = 'ADD_PLAYER'; export const STAR_PLAYER = 'STAR_PLAYER'; export const DELETE_PLAYER = 'DELETE_PLAYER'; +export const CHANGE_PAGE = 'CHANGE_PAGE'; \ No newline at end of file diff --git a/src/containers/PlayerListApp.js b/src/containers/PlayerListApp.js index 0e4bfa5..a20600a 100755 --- a/src/containers/PlayerListApp.js +++ b/src/containers/PlayerListApp.js @@ -1,27 +1,29 @@ import React, { Component } from 'react'; import styles from './PlayerListApp.css'; import { connect } from 'react-redux'; +import _ from 'lodash' -import { addPlayer, deletePlayer, starPlayer } from '../actions/PlayersActions'; -import { PlayerList, AddPlayerInput } from '../components'; +import { addPlayer, deletePlayer, starPlayer, changePage} from '../actions/PlayersActions'; +import { PlayerList, AddPlayerInput, PageList } from '../components'; class PlayerListApp extends Component { render() { const { - playerlist: { playersById }, + playerlist: { playersById, curPageNumber,pageSize,positionList} } = this.props; const actions = { addPlayer: this.props.addPlayer, deletePlayer: this.props.deletePlayer, starPlayer: this.props.starPlayer, + changePage: this.props.changePage }; - return (

NBA Players

- - + + +
); } @@ -37,5 +39,6 @@ export default connect( addPlayer, deletePlayer, starPlayer, + changePage }, )(PlayerListApp); diff --git a/src/reducers/playerlist.js b/src/reducers/playerlist.js index 1bc7457..763cd7a 100755 --- a/src/reducers/playerlist.js +++ b/src/reducers/playerlist.js @@ -1,6 +1,9 @@ import * as types from '../constants/ActionTypes'; const initialState = { + curPageNumber: 0, + pageSize: 5, + positionList:[{'position':'SF'},{'position':'PG'}], playersById: [ { name: 'LeBron James', @@ -51,7 +54,7 @@ export default function players(state = initialState, action) { { name: action.name, team: 'LOS ANGELES LAKERS', - position: 'SF', + position: state.positionList[action.optionId].position, }, ], }; @@ -64,12 +67,17 @@ export default function players(state = initialState, action) { }; case types.STAR_PLAYER: let players = [...state.playersById]; - let player = players.find((item, index) => index === action.id); + let player = players.find((item, index) => index === action.id + state.curPageNumber * state.pageSize); player.starred = !player.starred; return { ...state, playersById: players, }; + case types.CHANGE_PAGE: + return { + ...state, + curPageNumber: action.curPageNumber, + }; default: return state;