From c96ce255989393f18000837f4f9d74f37e53d339 Mon Sep 17 00:00:00 2001 From: Stuart Taylor Date: Thu, 12 Jan 2017 06:54:43 +0000 Subject: [PATCH] Enable react/sort-prop-types rule --- .eslintrc | 1 + common/app/App.jsx | 28 +++++++-------- .../components/Nav/Avatar-Points-Nav-Item.jsx | 14 +++++--- common/app/components/NotFound/index.jsx | 15 ++++---- .../challenges/components/Bug-Modal.jsx | 16 +++++---- .../routes/challenges/components/Output.jsx | 10 +++--- .../app/routes/challenges/components/Show.jsx | 34 +++++++++--------- .../challenges/components/Solution-Input.jsx | 11 +++--- .../components/backend/Back-End.jsx | 26 ++++++++------ .../challenges/components/classic/Classic.jsx | 36 ++++++++++--------- .../challenges/components/classic/Editor.jsx | 31 +++++++++------- .../challenges/components/classic/Preview.jsx | 5 +-- .../components/classic/Side-Panel.jsx | 36 +++++++++---------- .../challenges/components/map/Block.jsx | 24 +++++++------ .../challenges/components/map/Header.jsx | 22 +++++++----- .../routes/challenges/components/map/Map.jsx | 20 ++++++----- .../challenges/components/map/Super-Block.jsx | 24 +++++++------ .../challenges/components/project/Forms.jsx | 10 +++--- .../challenges/components/project/Project.jsx | 19 +++++----- .../components/project/Side-Panel.jsx | 17 +++++---- .../components/project/Tool-Panel.jsx | 6 ++-- .../challenges/components/step/Step.jsx | 2 +- .../challenges/components/video/Lecture.jsx | 22 ++++++------ .../challenges/components/video/Questions.jsx | 36 +++++++++---------- .../challenges/components/video/Video.jsx | 24 ++++++------- .../settings/components/Email-Setting.jsx | 21 ++++++----- .../settings/components/Language-Settings.jsx | 1 + .../settings/components/Locked-Settings.jsx | 11 +++--- .../routes/settings/components/Settings.jsx | 24 ++++++------- .../settings/components/Social-Settings.jsx | 13 ++++--- .../routes/update-email/Update-Email.jsx | 21 +++++------ common/app/toasts/Toasts.jsx | 13 +++---- package.json | 2 +- 33 files changed, 322 insertions(+), 273 deletions(-) diff --git a/.eslintrc b/.eslintrc index b6eccc73a4..1bad008c04 100644 --- a/.eslintrc +++ b/.eslintrc @@ -189,6 +189,7 @@ "react/prop-types": 2, "react/react-in-jsx-scope": 2, "react/self-closing-comp": 2, + "react/sort-prop-types": 2, "import/default": 2, "import/export": 2, diff --git a/common/app/App.jsx b/common/app/App.jsx index b6fcbad01c..3194911859 100644 --- a/common/app/App.jsx +++ b/common/app/App.jsx @@ -56,23 +56,23 @@ const mapStateToProps = createSelector( const propTypes = { children: PropTypes.node, - username: PropTypes.string, - isSignedIn: PropTypes.bool, - points: PropTypes.number, - picture: PropTypes.string, - toast: PropTypes.object, - updateNavHeight: PropTypes.func, - initWindowHeight: PropTypes.func, - submitChallenge: PropTypes.func, + closeDropdown: PropTypes.func.isRequired, fetchUser: PropTypes.func, - showLoading: PropTypes.bool, - params: PropTypes.object, - updateAppLang: PropTypes.func.isRequired, - trackEvent: PropTypes.func.isRequired, + initWindowHeight: PropTypes.func, + isNavDropdownOpen: PropTypes.bool, + isSignedIn: PropTypes.bool, loadCurrentChallenge: PropTypes.func.isRequired, openDropdown: PropTypes.func.isRequired, - closeDropdown: PropTypes.func.isRequired, - isNavDropdownOpen: PropTypes.bool + params: PropTypes.object, + picture: PropTypes.string, + points: PropTypes.number, + showLoading: PropTypes.bool, + submitChallenge: PropTypes.func, + toast: PropTypes.object, + trackEvent: PropTypes.func.isRequired, + updateAppLang: PropTypes.func.isRequired, + updateNavHeight: PropTypes.func, + username: PropTypes.string }; // export plain class for testing diff --git a/common/app/components/Nav/Avatar-Points-Nav-Item.jsx b/common/app/components/Nav/Avatar-Points-Nav-Item.jsx index f2483ef2df..d8907f2b1b 100644 --- a/common/app/components/Nav/Avatar-Points-Nav-Item.jsx +++ b/common/app/components/Nav/Avatar-Points-Nav-Item.jsx @@ -3,6 +3,13 @@ import { Link } from 'react-router'; // this is separated out to prevent react bootstrap's // NavBar from injecting unknown props to the li component + +const propTypes = { + picture: PropTypes.string, + points: PropTypes.number, + username: PropTypes.string +}; + export default function AvatarPointsNavItem({ picture, points, username }) { return (
  • ({ isOpen: state.challengesApp.isBugOpen }); const actions = { createIssue, openIssueSearch, closeBugModal }; const bugLink = 'http://forum.freecodecamp.com/t/how-to-report-a-bug/19543'; +const propTypes = { + closeBugModal: PropTypes.func, + createIssue: PropTypes.func, + isOpen: PropTypes.bool, + openIssueSearch: PropTypes.func +}; + export class BugModal extends PureComponent { - static propTypes = { - isOpen: PropTypes.bool, - closeBugModal: PropTypes.func, - openIssueSearch: PropTypes.func, - createIssue: PropTypes.func - }; render() { const { @@ -81,4 +82,7 @@ export class BugModal extends PureComponent { } } +BugModal.displayName = 'BugModal'; +BugModal.propTypes = propTypes; + export default connect(mapStateToProps, actions)(BugModal); diff --git a/common/app/routes/challenges/components/Output.jsx b/common/app/routes/challenges/components/Output.jsx index 1969f6d3ee..476c4324d4 100644 --- a/common/app/routes/challenges/components/Output.jsx +++ b/common/app/routes/challenges/components/Output.jsx @@ -12,6 +12,11 @@ const defaultOptions = { lineWrapping: true }; +const propTypes = { + defaultOutput: PropTypes.string, + output: PropTypes.string +}; + export default class Output extends PureComponent { render() { const { output, defaultOutput } = this.props; @@ -29,7 +34,4 @@ export default class Output extends PureComponent { } Output.displayName = 'Output'; -Output.propTypes = { - output: PropTypes.string, - defaultOutput: PropTypes.string -}; +Output.propTypes = propTypes; diff --git a/common/app/routes/challenges/components/Show.jsx b/common/app/routes/challenges/components/Show.jsx index 66925b068a..c5b79922e7 100644 --- a/common/app/routes/challenges/components/Show.jsx +++ b/common/app/routes/challenges/components/Show.jsx @@ -77,23 +77,22 @@ const link = 'http://forum.freecodecamp.com/t/' + 'guidelines-for-translating-free-code-camp' + '-to-any-language/19111'; -export class Challenges extends PureComponent { - static displayName = 'Challenges'; +const propTypes = { + areChallengesLoaded: PropTypes.bool, + fetchChallenges: PropTypes.func.isRequired, + isStep: PropTypes.bool, + isTranslated: PropTypes.bool, + lang: PropTypes.string.isRequired, + makeToast: PropTypes.func.isRequired, + params: PropTypes.object.isRequired, + replaceChallenge: PropTypes.func.isRequired, + resetUi: PropTypes.func.isRequired, + title: PropTypes.string, + updateTitle: PropTypes.func.isRequired, + viewType: PropTypes.string + }; - static propTypes = { - title: PropTypes.string, - viewType: PropTypes.string, - isStep: PropTypes.bool, - fetchChallenges: PropTypes.func.isRequired, - replaceChallenge: PropTypes.func.isRequired, - params: PropTypes.object.isRequired, - areChallengesLoaded: PropTypes.bool, - resetUi: PropTypes.func.isRequired, - updateTitle: PropTypes.func.isRequired, - makeToast: PropTypes.func.isRequired, - lang: PropTypes.string.isRequired, - isTranslated: PropTypes.bool - }; +export class Challenges extends PureComponent { componentWillMount() { const { lang, isTranslated, makeToast } = this.props; @@ -153,6 +152,9 @@ export class Challenges extends PureComponent { } } +Challenges.displayName = 'Challenges'; +Challenges.propTypes = propTypes; + export default compose( connect(mapStateToProps, bindableActions), contain(fetchOptions) diff --git a/common/app/routes/challenges/components/Solution-Input.jsx b/common/app/routes/challenges/components/Solution-Input.jsx index 2fb518e37b..afbf2cdc23 100644 --- a/common/app/routes/challenges/components/Solution-Input.jsx +++ b/common/app/routes/challenges/components/Solution-Input.jsx @@ -2,6 +2,11 @@ import React, { PropTypes } from 'react'; import { HelpBlock, FormGroup, FormControl } from 'react-bootstrap'; import { getValidationState, DOMOnlyProps } from '../../../utils/form'; +const propTypes = { + placeholder: PropTypes.string, + solution: PropTypes.object +}; + export default function SolutionInput({ solution, placeholder }) { const validationState = getValidationState(solution); return ( @@ -24,7 +29,5 @@ export default function SolutionInput({ solution, placeholder }) { ); } -SolutionInput.propTypes = { - solution: PropTypes.object, - placeholder: PropTypes.string -}; +SolutionInput.displayName = 'SolutionInput'; +SolutionInput.propTypes = propTypes; diff --git a/common/app/routes/challenges/components/backend/Back-End.jsx b/common/app/routes/challenges/components/backend/Back-End.jsx index 327f022cf8..6ebf301168 100644 --- a/common/app/routes/challenges/components/backend/Back-End.jsx +++ b/common/app/routes/challenges/components/backend/Back-End.jsx @@ -19,19 +19,23 @@ import { createFormValidator } from '../../../../utils/form.js'; -const propTypes = { - id: PropTypes.string, - title: PropTypes.string, - description: PropTypes.arrayOf(PropTypes.string), - tests: PropTypes.array, - output: PropTypes.string, - executeChallenge: PropTypes.func.isRequired, - submitChallenge: PropTypes.func.isRequired, - // provided by redux form - submitting: PropTypes.bool, +// provided by redux form +const reduxFormPropTypes = { fields: PropTypes.object, + handleSubmit: PropTypes.func.isRequired, resetForm: PropTypes.func.isRequired, - handleSubmit: PropTypes.func.isRequired + submitting: PropTypes.bool +}; + +const propTypes = { + description: PropTypes.arrayOf(PropTypes.string), + executeChallenge: PropTypes.func.isRequired, + id: PropTypes.string, + output: PropTypes.string, + submitChallenge: PropTypes.func.isRequired, + tests: PropTypes.array, + title: PropTypes.string, + ...reduxFormPropTypes }; const fields = [ 'solution' ]; diff --git a/common/app/routes/challenges/components/classic/Classic.jsx b/common/app/routes/challenges/components/classic/Classic.jsx index 01b78f94d0..aaaae44a22 100644 --- a/common/app/routes/challenges/components/classic/Classic.jsx +++ b/common/app/routes/challenges/components/classic/Classic.jsx @@ -57,24 +57,23 @@ const bindableActions = { updateSuccessMessage }; -export class Challenge extends PureComponent { - static displayName = 'Challenge'; +const propTypes = { + closeChallengeModal: PropTypes.func, + content: PropTypes.string, + executeChallenge: PropTypes.func, + file: PropTypes.object, + id: PropTypes.string, + isChallengeModalOpen: PropTypes.bool, + loadCode: PropTypes.func, + mode: PropTypes.string, + showPreview: PropTypes.bool, + submitChallenge: PropTypes.func, + successMessage: PropTypes.string, + updateFile: PropTypes.func, + updateSuccessMessage: PropTypes.func +}; - static propTypes = { - id: PropTypes.string, - showPreview: PropTypes.bool, - content: PropTypes.string, - mode: PropTypes.string, - file: PropTypes.object, - updateFile: PropTypes.func, - executeChallenge: PropTypes.func, - loadCode: PropTypes.func, - submitChallenge: PropTypes.func, - isChallengeModalOpen: PropTypes.bool, - closeChallengeModal: PropTypes.func, - successMessage: PropTypes.string, - updateSuccessMessage: PropTypes.func - }; +export class Challenge extends PureComponent { componentDidMount() { this.props.loadCode(); @@ -148,4 +147,7 @@ export class Challenge extends PureComponent { } } +Challenge.displayName = 'Challenge'; +Challenge.propTypes = propTypes; + export default connect(mapStateToProps, bindableActions)(Challenge); diff --git a/common/app/routes/challenges/components/classic/Editor.jsx b/common/app/routes/challenges/components/classic/Editor.jsx index ec4841077d..f35eb37cde 100644 --- a/common/app/routes/challenges/components/classic/Editor.jsx +++ b/common/app/routes/challenges/components/classic/Editor.jsx @@ -32,25 +32,25 @@ const options = { gutters: ['CodeMirror-lint-markers'] }; +const defaultProps = { + content: '// Happy Coding!', + mode: 'javascript' +}; + +const propTypes = { + content: PropTypes.string, + executeChallenge: PropTypes.func, + height: PropTypes.number, + mode: PropTypes.string, + updateFile: PropTypes.func +}; + export class Editor extends PureComponent { constructor(...args) { super(...args); this._editorContent$ = new Subject(); this.handleChange = this.handleChange.bind(this); } - static displayName = 'Editor'; - static propTypes = { - executeChallenge: PropTypes.func, - height: PropTypes.number, - content: PropTypes.string, - mode: PropTypes.string, - updateFile: PropTypes.func - }; - - static defaultProps = { - content: '// Happy Coding!', - mode: 'javascript' - }; createOptions = createSelector( state => state.options, @@ -148,4 +148,9 @@ export class Editor extends PureComponent { } } +Editor.defaultProps = defaultProps; +Editor.displayName = 'Editor'; +Editor.propTypes = propTypes; + + export default connect(mapStateToProps)(Editor); diff --git a/common/app/routes/challenges/components/classic/Preview.jsx b/common/app/routes/challenges/components/classic/Preview.jsx index 21f42aa846..ce0fdb1e13 100644 --- a/common/app/routes/challenges/components/classic/Preview.jsx +++ b/common/app/routes/challenges/components/classic/Preview.jsx @@ -2,9 +2,8 @@ import React from 'react'; import PureComponent from 'react-pure-render/component'; const mainId = 'fcc-main-frame'; -export default class extends PureComponent { - static displayName = 'Preview'; +export default class Preview extends PureComponent { render() { return (
    { @@ -174,6 +171,9 @@ export class SidePanel extends PureComponent { } } +SidePanel.displayName = 'SidePanel'; +SidePanel.propTypes = propTypes; + export default connect( mapStateToProps, mapDispatchToProps diff --git a/common/app/routes/challenges/components/map/Block.jsx b/common/app/routes/challenges/components/map/Block.jsx index 57f6ea2d50..e07e185013 100644 --- a/common/app/routes/challenges/components/map/Block.jsx +++ b/common/app/routes/challenges/components/map/Block.jsx @@ -29,22 +29,21 @@ const makeMapStateToProps = () => createSelector( }; } ); +const propTypes = { + challenges: PropTypes.array, + dashedName: PropTypes.string, + isHidden: PropTypes.bool, + isOpen: PropTypes.bool, + time: PropTypes.string, + title: PropTypes.string, + toggleThisPanel: PropTypes.func +}; + export class Block extends PureComponent { constructor(...props) { super(...props); this.handleSelect = this.handleSelect.bind(this); } - static displayName = 'Block'; - static propTypes = { - title: PropTypes.string, - dashedName: PropTypes.string, - time: PropTypes.string, - isOpen: PropTypes.bool, - isHidden: PropTypes.bool, - challenges: PropTypes.array, - toggleThisPanel: PropTypes.func - }; - handleSelect(eventKey, e) { e.preventDefault(); this.props.toggleThisPanel(eventKey); @@ -108,4 +107,7 @@ export class Block extends PureComponent { } } +Block.displayName = 'Block'; +Block.propTypes = propTypes; + export default connect(makeMapStateToProps, dispatchActions)(Block); diff --git a/common/app/routes/challenges/components/map/Header.jsx b/common/app/routes/challenges/components/map/Header.jsx index 935d81d7e8..1a2af91e78 100644 --- a/common/app/routes/challenges/components/map/Header.jsx +++ b/common/app/routes/challenges/components/map/Header.jsx @@ -23,21 +23,21 @@ const mapStateToProps = state => ({ isAllCollapsed: state.challengesApp.mapUi.isAllCollapsed, filter: state.challengesApp.filter }); +const propTypes = { + clearFilter: PropTypes.func, + collapseAll: PropTypes.func, + expandAll: PropTypes.func, + filter: PropTypes.string, + isAllCollapsed: PropTypes.bool, + updateFilter: PropTypes.func +}; + export class Header extends PureComponent { constructor(...props) { super(...props); this.handleKeyDown = this.handleKeyDown.bind(this); this.handleClearButton = this.handleClearButton.bind(this); } - static displayName = 'MapHeader'; - static propTypes = { - isAllCollapsed: PropTypes.bool, - filter: PropTypes.string, - clearFilter: PropTypes.func, - updateFilter: PropTypes.func, - collapseAll: PropTypes.func, - expandAll: PropTypes.func - }; handleKeyDown(e) { if (e.keyCode === ESC) { @@ -116,4 +116,8 @@ export class Header extends PureComponent { ); } } + +Header.displayName = 'MapHeader'; +Header.propTypes = propTypes; + export default connect(mapStateToProps, bindableActions)(Header); diff --git a/common/app/routes/challenges/components/map/Map.jsx b/common/app/routes/challenges/components/map/Map.jsx index e340b96696..cb3f39919a 100644 --- a/common/app/routes/challenges/components/map/Map.jsx +++ b/common/app/routes/challenges/components/map/Map.jsx @@ -27,16 +27,15 @@ const fetchOptions = { return Array.isArray(superBlocks) && superBlocks.length > 1; } }; -export class ShowMap extends PureComponent { - static displayName = 'Map'; - static propTypes = { - superBlocks: PropTypes.array, - height: PropTypes.number, - updateTitle: PropTypes.func.isRequired, - params: PropTypes.object, - fetchChallenges: PropTypes.func.isRequired - }; +const propTypes = { + fetchChallenges: PropTypes.func.isRequired, + height: PropTypes.number, + params: PropTypes.object, + superBlocks: PropTypes.array, + updateTitle: PropTypes.func.isRequired +}; +export class ShowMap extends PureComponent { componentWillMount() { // if no params then map is open in drawer // do not update title @@ -81,6 +80,9 @@ export class ShowMap extends PureComponent { } } +ShowMap.displayName = 'Map'; +ShowMap.propTypes = propTypes; + export default compose( connect(mapStateToProps, bindableActions), contain(fetchOptions) diff --git a/common/app/routes/challenges/components/map/Super-Block.jsx b/common/app/routes/challenges/components/map/Super-Block.jsx index 986c42534f..8f6e4e439e 100644 --- a/common/app/routes/challenges/components/map/Super-Block.jsx +++ b/common/app/routes/challenges/components/map/Super-Block.jsx @@ -36,22 +36,21 @@ const makeMapStateToProps = () => { ); }; +const propTypes = { + blocks: PropTypes.array, + dashedName: PropTypes.string, + isHidden: PropTypes.bool, + isOpen: PropTypes.bool, + message: PropTypes.string, + title: PropTypes.string, + toggleThisPanel: PropTypes.func +}; + export class SuperBlock extends PureComponent { constructor(...props) { super(...props); this.handleSelect = this.handleSelect.bind(this); } - static displayName = 'SuperBlock'; - static propTypes = { - title: PropTypes.string, - dashedName: PropTypes.string, - blocks: PropTypes.array, - isOpen: PropTypes.bool, - isHidden: PropTypes.bool, - message: PropTypes.string, - toggleThisPanel: PropTypes.func - }; - handleSelect(eventKey, e) { e.preventDefault(); this.props.toggleThisPanel(eventKey); @@ -126,6 +125,9 @@ export class SuperBlock extends PureComponent { } } +SuperBlock.displayName = 'SuperBlock'; +SuperBlock.propTypes = propTypes; + export default connect( makeMapStateToProps, dispatchActions diff --git a/common/app/routes/challenges/components/project/Forms.jsx b/common/app/routes/challenges/components/project/Forms.jsx index bbaf3265ac..d1a7c6b825 100644 --- a/common/app/routes/challenges/components/project/Forms.jsx +++ b/common/app/routes/challenges/components/project/Forms.jsx @@ -16,13 +16,13 @@ import { import { submitChallenge, showProjectSubmit } from '../../redux/actions'; const propTypes = { - isSignedIn: PropTypes.bool, - isSubmitting: PropTypes.bool, - showProjectSubmit: PropTypes.func, fields: PropTypes.object, handleSubmit: PropTypes.func, - submitChallenge: PropTypes.func, - resetForm: PropTypes.func + isSignedIn: PropTypes.bool, + isSubmitting: PropTypes.bool, + resetForm: PropTypes.func, + showProjectSubmit: PropTypes.func, + submitChallenge: PropTypes.func }; const bindableActions = { diff --git a/common/app/routes/challenges/components/project/Project.jsx b/common/app/routes/challenges/components/project/Project.jsx index bd40394d05..cf14b84022 100644 --- a/common/app/routes/challenges/components/project/Project.jsx +++ b/common/app/routes/challenges/components/project/Project.jsx @@ -29,17 +29,15 @@ const mapStateToProps = createSelector( description }) ); +const propTypes = { + description: PropTypes.arrayOf(PropTypes.string), + id: PropTypes.string, + isCompleted: PropTypes.bool, + title: PropTypes.string, + videoId: PropTypes.string +}; export class Project extends PureComponent { - static displayName = 'Project'; - static propTypes = { - id: PropTypes.string, - videoId: PropTypes.string, - title: PropTypes.string, - description: PropTypes.arrayOf(PropTypes.string), - isCompleted: PropTypes.bool - }; - render() { const { id, @@ -78,6 +76,9 @@ export class Project extends PureComponent { } } +Project.displayName = 'Project'; +Project.propTypes = propTypes; + export default connect( mapStateToProps )(Project); diff --git a/common/app/routes/challenges/components/project/Side-Panel.jsx b/common/app/routes/challenges/components/project/Side-Panel.jsx index e4ecdd6d25..014231b60c 100644 --- a/common/app/routes/challenges/components/project/Side-Panel.jsx +++ b/common/app/routes/challenges/components/project/Side-Panel.jsx @@ -2,14 +2,14 @@ import React, { PropTypes } from 'react'; import PureComponent from 'react-pure-render/component'; -export default class SidePanel extends PureComponent { - static propTypes = { - title: PropTypes.string, - description: PropTypes.arrayOf(PropTypes.string), - isCompleted: PropTypes.bool, - isSignedIn: PropTypes.bool - }; +const propTypes = { + description: PropTypes.arrayOf(PropTypes.string), + isCompleted: PropTypes.bool, + isSignedIn: PropTypes.bool, + title: PropTypes.string +}; +export default class SidePanel extends PureComponent { renderIcon(isCompleted) { if (!isCompleted) { return null; @@ -48,3 +48,6 @@ export default class SidePanel extends PureComponent { ); } } + +SidePanel.displayName = 'ProjectSidePanel'; +SidePanel.propTypes = propTypes; diff --git a/common/app/routes/challenges/components/project/Tool-Panel.jsx b/common/app/routes/challenges/components/project/Tool-Panel.jsx index 19bb93f2eb..cf0c941a15 100644 --- a/common/app/routes/challenges/components/project/Tool-Panel.jsx +++ b/common/app/routes/challenges/components/project/Tool-Panel.jsx @@ -17,11 +17,11 @@ import { } from '../../../../utils/challengeTypes'; const propTypes = { + helpChatRoom: PropTypes.string.isRequired, + isFrontEnd: PropTypes.bool, isSignedIn: PropTypes.bool, isSimple: PropTypes.bool, - isFrontEnd: PropTypes.bool, isSubmitting: PropTypes.bool, - helpChatRoom: PropTypes.string.isRequired, openBugModal: PropTypes.func.isRequired, submitChallenge: PropTypes.func.isRequired }; @@ -109,8 +109,8 @@ export class ToolPanel extends PureComponent { } } +ToolPanel.displayName = 'ProjectToolPanel'; ToolPanel.propTypes = propTypes; -ToolPanel.displayName = 'ToolPanel'; export default connect( mapStateToProps, diff --git a/common/app/routes/challenges/components/step/Step.jsx b/common/app/routes/challenges/components/step/Step.jsx index 194cca73a2..22693501ab 100644 --- a/common/app/routes/challenges/components/step/Step.jsx +++ b/common/app/routes/challenges/components/step/Step.jsx @@ -62,9 +62,9 @@ const propTypes = { numOfSteps: PropTypes.number, openLightBoxImage: PropTypes.func.isRequired, step: PropTypes.array, - steps: PropTypes.array, stepBackward: PropTypes.func, stepForward: PropTypes.func, + steps: PropTypes.array, submitChallenge: PropTypes.func.isRequired, updateUnlockedSteps: PropTypes.func.isRequired }; diff --git a/common/app/routes/challenges/components/video/Lecture.jsx b/common/app/routes/challenges/components/video/Lecture.jsx index d3bac55694..fbe9284326 100644 --- a/common/app/routes/challenges/components/video/Lecture.jsx +++ b/common/app/routes/challenges/components/video/Lecture.jsx @@ -31,20 +31,15 @@ const embedOpts = { width: '853', height: '480' }; +const propTypes = { + dashedName: PropTypes.string, + description: PropTypes.array, + id: PropTypes.string, + toggleQuestionView: PropTypes.func, + videoId: PropTypes.string +}; export class Lecture extends React.Component { - static displayName = 'Lecture'; - - static propTypes = { - // actions - toggleQuestionView: PropTypes.func, - // ui - id: PropTypes.string, - videoId: PropTypes.string, - description: PropTypes.array, - dashedName: PropTypes.string - }; - shouldComponentUpdate(nextProps) { const { props } = this; return nextProps.id !== props.id; @@ -111,6 +106,9 @@ export class Lecture extends React.Component { } } +Lecture.displayName = 'Lecture'; +Lecture.propTypes = propTypes; + export default connect( mapStateToProps, { toggleQuestionView } diff --git a/common/app/routes/challenges/components/video/Questions.jsx b/common/app/routes/challenges/components/video/Questions.jsx index e753b7fbe1..3062095426 100644 --- a/common/app/routes/challenges/components/video/Questions.jsx +++ b/common/app/routes/challenges/components/video/Questions.jsx @@ -47,27 +47,22 @@ const mapStateToProps = createSelector( isSignedIn }) ); +const propTypes = { + answerQuestion: PropTypes.func, + currentQuestion: PropTypes.number, + delta: PropTypes.array, + grabQuestion: PropTypes.func, + isCorrect: PropTypes.bool, + isPressed: PropTypes.bool, + isSignedIn: PropTypes.bool, + mouse: PropTypes.array, + moveQuestion: PropTypes.func, + releaseQuestion: PropTypes.func, + shouldShakeQuestion: PropTypes.bool, + tests: PropTypes.array +}; class Question extends React.Component { - static displayName = 'Questions'; - - static propTypes = { - // actions - answerQuestion: PropTypes.func, - releaseQuestion: PropTypes.func, - moveQuestion: PropTypes.func, - grabQuestion: PropTypes.func, - // ui state - tests: PropTypes.array, - mouse: PropTypes.array, - delta: PropTypes.array, - isCorrect: PropTypes.bool, - isPressed: PropTypes.bool, - isSignedIn: PropTypes.bool, - currentQuestion: PropTypes.number, - shouldShakeQuestion: PropTypes.bool - }; - handleMouseUp(e, answer, info) { e.stopPropagation(); if (!this.props.isPressed) { @@ -191,4 +186,7 @@ class Question extends React.Component { } } +Question.displayName = 'Question'; +Question.propTypes = propTypes; + export default connect(mapStateToProps, actionsToBind)(Question); diff --git a/common/app/routes/challenges/components/video/Video.jsx b/common/app/routes/challenges/components/video/Video.jsx index 2bb00cf0fc..b9785f2f26 100644 --- a/common/app/routes/challenges/components/video/Video.jsx +++ b/common/app/routes/challenges/components/video/Video.jsx @@ -18,21 +18,15 @@ const mapStateToProps = createSelector( shouldShowQuestions }) ); +const propTypes = { + params: PropTypes.object, + resetUi: PropTypes.func, + shouldShowQuestions: PropTypes.bool, + title: PropTypes.string, + updateTitle: PropTypes.func +}; -// export plain component for testing export class Video extends React.Component { - static displayName = 'Video'; - - static propTypes = { - // actions - resetUi: PropTypes.func, - // ui - title: PropTypes.string, - params: PropTypes.object, - shouldShowQuestions: PropTypes.bool, - updateTitle: PropTypes.func - }; - componentWillMount() { const { updateTitle, title } = this.props; updateTitle(title); @@ -78,7 +72,9 @@ export class Video extends React.Component { } } -// export redux aware component +Video.displayName = 'Video'; +Video.propTypes = propTypes; + export default connect( mapStateToProps, bindableActions diff --git a/common/app/routes/settings/components/Email-Setting.jsx b/common/app/routes/settings/components/Email-Setting.jsx index 76b940bb70..e83a847103 100644 --- a/common/app/routes/settings/components/Email-Setting.jsx +++ b/common/app/routes/settings/components/Email-Setting.jsx @@ -4,6 +4,16 @@ import { Button, Row, Col } from 'react-bootstrap'; import FA from 'react-fontawesome'; import classnames from 'classnames'; +const propTypes = { + email: PropTypes.string, + sendMonthlyEmail: PropTypes.bool, + sendNotificationEmail: PropTypes.bool, + sendQuincyEmail: PropTypes.bool, + toggleMonthlyEmail: PropTypes.func.isRequired, + toggleNotificationEmail: PropTypes.func.isRequired, + toggleQuincyEmail: PropTypes.func.isRequired +}; + export function UpdateEmailButton() { return ( { buttons }
    ); } -SocialSettings.propTypes = { - isGithubCool: PropTypes.bool, - isTwitter: PropTypes.bool, - isLinkedIn: PropTypes.bool -}; +SocialSettings.displayName = 'SocialSettings'; +SocialSettings.propTypes = propTypes; diff --git a/common/app/routes/settings/routes/update-email/Update-Email.jsx b/common/app/routes/settings/routes/update-email/Update-Email.jsx index 04d82f803d..b6c5cf87da 100644 --- a/common/app/routes/settings/routes/update-email/Update-Email.jsx +++ b/common/app/routes/settings/routes/update-email/Update-Email.jsx @@ -35,22 +35,20 @@ const mapStateToProps = state => { isVerified: !!emailVerified }; }; +const propTypes = { + fields: PropTypes.object.isRequired, + handleSubmit: PropTypes.func.isRequired, + isEmailThere: PropTypes.bool, + isVerified: PropTypes.bool, + submitting: PropTypes.bool, + updateMyEmail: PropTypes.func.isRequired +}; export class UpdateEmail extends React.Component { constructor(...props) { super(...props); this.handleSubmit = this.handleSubmit.bind(this); } - static displayName = 'UpdateEmail'; - static propTypes = { - isEmailThere: PropTypes.bool, - isVerified: PropTypes.bool, - fields: PropTypes.object.isRequired, - submitting: PropTypes.bool, - handleSubmit: PropTypes.func.isRequired, - updateMyEmail: PropTypes.func.isRequired - }; - handleSubmit(e) { e.preventDefault(); this.props.handleSubmit(({ email }) => this.props.updateMyEmail(email))(e); @@ -133,6 +131,9 @@ export class UpdateEmail extends React.Component { } } +UpdateEmail.displayName = 'UpdateEmail'; +UpdateEmail.propTypes = propTypes; + export default reduxForm( { form: 'update-email', diff --git a/common/app/toasts/Toasts.jsx b/common/app/toasts/Toasts.jsx index 3f82df82d4..035bc4b466 100644 --- a/common/app/toasts/Toasts.jsx +++ b/common/app/toasts/Toasts.jsx @@ -58,18 +58,16 @@ const addDispatchableActionsToToast = createSelector( }; }) ); +const propTypes = { + dispatch: PropTypes.func, + toasts: PropTypes.arrayOf(PropTypes.object) +}; export class Toasts extends React.Component { constructor(...props) { super(...props); this.handleDismiss = this.handleDismiss.bind(this); } - static displayName = 'Toasts'; - static propTypes = { - toasts: PropTypes.arrayOf(PropTypes.object), - dispatch: PropTypes.func - }; - styleFactory(index, style) { return { ...style, bottom: `${4 + index * 8}rem` }; } @@ -93,4 +91,7 @@ export class Toasts extends React.Component { } } +Toasts.displayName = 'Toasts'; +Toasts.propTypes = propTypes; + export default connect(mapStateToProps)(Toasts); diff --git a/package.json b/package.json index bb72097a7d..f71e085b8b 100644 --- a/package.json +++ b/package.json @@ -134,7 +134,7 @@ "eslint": "^3.1.0", "eslint-plugin-import": "^2.0.1", "eslint-plugin-prefer-object-spread": "^1.1.0", - "eslint-plugin-react": "^6.2.0", + "eslint-plugin-react": "^6.9.0", "gulp": "^3.9.0", "gulp-babel": "^6.1.1", "gulp-concat": "^2.6.0",