From e3a522aa5ef51733018156212553701a1fa0c7cc Mon Sep 17 00:00:00 2001 From: Stuart Taylor Date: Mon, 29 Jan 2018 17:26:03 +0000 Subject: [PATCH] feat(tool-panel): Make buttons look and act like current productiion (#16580) --- common/app/routes/Challenges/Bug-Modal.jsx | 95 ------------------- common/app/routes/Challenges/Help-Modal.jsx | 36 ++----- common/app/routes/Challenges/Side-Panel.jsx | 14 +-- common/app/routes/Challenges/Tool-Panel.jsx | 42 ++++---- common/app/routes/Challenges/challenges.less | 4 + common/app/routes/Challenges/redux/index.js | 19 +--- .../app/routes/Challenges/redux/modal-epic.js | 86 +---------------- .../Challenges/views/project/Project.jsx | 7 +- .../Challenges/views/project/Tool-Panel.jsx | 41 +++++--- 9 files changed, 68 insertions(+), 276 deletions(-) delete mode 100644 common/app/routes/Challenges/Bug-Modal.jsx diff --git a/common/app/routes/Challenges/Bug-Modal.jsx b/common/app/routes/Challenges/Bug-Modal.jsx deleted file mode 100644 index 3b2a48ae3f..0000000000 --- a/common/app/routes/Challenges/Bug-Modal.jsx +++ /dev/null @@ -1,95 +0,0 @@ -import React, { PureComponent } from 'react'; -import PropTypes from 'prop-types'; -import { connect } from 'react-redux'; -import { Button, Modal } from 'react-bootstrap'; - -import ns from './ns.json'; -import { - createIssue, - openIssueSearch, - closeBugModal, - - bugModalSelector -} from './redux'; - -const mapStateToProps = state => ({ isOpen: bugModalSelector(state) }); -const mapDispatchToProps = { createIssue, openIssueSearch, closeBugModal }; -const bugLink = 'http://forum.freecodecamp.org/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 { - render() { - const { - isOpen, - closeBugModal, - openIssueSearch, - createIssue - } = this.props; - return ( - - - Did you find a bug? - - × - - - -

- Before you submit a new issue, - read "How to Report a Bug" and - browse other issues with this challenge. -

- - - - -
-
- ); - } -} - -BugModal.displayName = 'BugModal'; -BugModal.propTypes = propTypes; - -export default connect(mapStateToProps, mapDispatchToProps)(BugModal); diff --git a/common/app/routes/Challenges/Help-Modal.jsx b/common/app/routes/Challenges/Help-Modal.jsx index fa6ad26931..4ca4ca0126 100644 --- a/common/app/routes/Challenges/Help-Modal.jsx +++ b/common/app/routes/Challenges/Help-Modal.jsx @@ -6,20 +6,18 @@ import { Button, Modal } from 'react-bootstrap'; import ns from './ns.json'; import { createQuestion, - openHelpChatRoom, closeHelpModal, helpModalSelector } from './redux'; import { RSA } from '../../../utils/constantStrings.json'; const mapStateToProps = state => ({ isOpen: helpModalSelector(state) }); -const mapDispatchToProps = { createQuestion, openHelpChatRoom, closeHelpModal }; +const mapDispatchToProps = { createQuestion, closeHelpModal }; const propTypes = { - closeHelpModal: PropTypes.func, - createQuestion: PropTypes.func, - isOpen: PropTypes.bool, - openHelpChatRoom: PropTypes.func + closeHelpModal: PropTypes.func.isRequired, + createQuestion: PropTypes.func.isRequired, + isOpen: PropTypes.bool }; export class HelpModal extends PureComponent { @@ -27,7 +25,6 @@ export class HelpModal extends PureComponent { const { isOpen, closeHelpModal, - openHelpChatRoom, createQuestion } = this.props; return ( @@ -44,20 +41,11 @@ export class HelpModal extends PureComponent { -

- If you've already tried the Read-Search-Ask method, - then you can ask for help on the freeCodeCamp forum. +

+ If you've already tried the  + Read-Search-Ask  + method, then you can ask for help on the freeCodeCamp forum.

- - +
+
+ } -
- {guideUrl && -
- -
-
- } -
diff --git a/common/app/routes/Challenges/challenges.less b/common/app/routes/Challenges/challenges.less index 47e43c49cb..73375c9276 100644 --- a/common/app/routes/Challenges/challenges.less +++ b/common/app/routes/Challenges/challenges.less @@ -234,4 +234,8 @@ width: 100%; } +.@{ns}-help-modal-heading > a { + font-size: inherit; +} + &{ @import "./views/index.less"; } diff --git a/common/app/routes/Challenges/redux/index.js b/common/app/routes/Challenges/redux/index.js index 9a74eb0f23..d8aff4e464 100644 --- a/common/app/routes/Challenges/redux/index.js +++ b/common/app/routes/Challenges/redux/index.js @@ -77,17 +77,10 @@ export const types = createTypes([ createAsyncTypes('submitChallenge'), 'moveToNextChallenge', - // bug - 'openBugModal', - 'closeBugModal', - 'openIssueSearch', - 'createIssue', - // help 'openHelpModal', 'closeHelpModal', 'createQuestion', - 'openHelpChatRoom', // panes 'toggleClassicEditor', @@ -157,17 +150,10 @@ export const submitChallengeComplete = createAction( export const moveToNextChallenge = createAction(types.moveToNextChallenge); -// bug -export const openBugModal = createAction(types.openBugModal); -export const closeBugModal = createAction(types.closeBugModal); -export const openIssueSearch = createAction(types.openIssueSearch); -export const createIssue = createAction(types.createIssue); - // help export const openHelpModal = createAction(types.openHelpModal); export const closeHelpModal = createAction(types.closeHelpModal); export const createQuestion = createAction(types.createQuestion); -export const openHelpChatRoom = createAction(types.openHelpChatRoom); // code storage export const storedCodeFound = createAction( @@ -221,8 +207,9 @@ export const challengeModalSelector = challengeSelector(state).type !== 'backend' ); -export const bugModalSelector = state => getNS(state).isBugOpen; export const helpModalSelector = state => getNS(state).isHelpOpen; +export const guideURLSelector = state => + `https://guide.freecodecamp.org/certificates/${getNS(state).challenge}`; export const challengeRequiredSelector = state => challengeSelector(state).required || []; @@ -334,8 +321,6 @@ export default combineReducers( ...state, output: (state.output || '') + output }), - [types.openBugModal]: state => ({ ...state, isBugOpen: true }), - [types.closeBugModal]: state => ({ ...state, isBugOpen: false }), [types.openHelpModal]: state => ({ ...state, isHelpOpen: true }), [types.closeHelpModal]: state => ({ ...state, isHelpOpen: false }) }), diff --git a/common/app/routes/Challenges/redux/modal-epic.js b/common/app/routes/Challenges/redux/modal-epic.js index 8cbf28d503..a26f74b009 100644 --- a/common/app/routes/Challenges/redux/modal-epic.js +++ b/common/app/routes/Challenges/redux/modal-epic.js @@ -1,8 +1,6 @@ -import { combineEpics, ofType } from 'redux-epic'; +import { ofType } from 'redux-epic'; import { types, - chatRoomSelector, - closeBugModal, closeHelpModal } from '../redux'; @@ -30,81 +28,6 @@ function filesToMarkdown(files = {}) { }, '\n'); } -export function openIssueSearchEpic(actions, { getState }, { window }) { - return actions::ofType(types.openIssueSearch).map(() => { - const state = getState(); - const challengeName = currentChallengeSelector(state); - - window.open( - 'https://forum.freecodecamp.org/search?q=' + - window.encodeURIComponent(challengeName) - ); - - return closeBugModal(); - }); -} - -export function createIssueEpic(actions, { getState }, { window }) { - return actions::ofType(types.createIssue).map(() => { - const state = getState(); - const files = filesSelector(state); - const challengeName = currentChallengeSelector(state); - const { - navigator: { userAgent }, - location: { href } - } = window; - const titleText = 'Need assistance in ' + challengeName; - let textMessage = [ - '#### Challenge Name\n', - '[', - challengeName, - '](', - href, - ') has an issue.\n', - '#### Issue Description\n', - '\n\n\n', - '#### Browser Information\n', - '\n', - 'User Agent is: ', - userAgent, - '.\n\n', - '#### Screenshot\n', - '\n\n\n', - '#### Your Code' - ].join(''); - - const body = filesToMarkdown(files); - if (body.length > 10) { - textMessage += body; - } - - window.open( - 'https://forum.freecodecamp.org/new-topic' - + '?category=General' - + '&title=' + window.encodeURIComponent(titleText) - + '&body=' + window.encodeURIComponent(textMessage), - '_blank' - ); - - return closeBugModal(); - }); -} - -export function openHelpChatRoomEpic(actions, { getState }, { window }) { - return actions::ofType(types.openHelpChatRoom).map(() => { - const state = getState(); - const helpChatRoom = chatRoomSelector(state); - - window.open( - 'https://gitter.im/freecodecamp/' + - window.encodeURIComponent(helpChatRoom) - ); - - return closeHelpModal(); - }); -} - export function createQuestionEpic(actions, { getState }, { window }) { return actions::ofType(types.createQuestion).map(() => { const state = getState(); @@ -138,9 +61,4 @@ export function createQuestionEpic(actions, { getState }, { window }) { }); } -export default combineEpics( - openIssueSearchEpic, - createIssueEpic, - openHelpChatRoomEpic, - createQuestionEpic -); +export default createQuestionEpic; diff --git a/common/app/routes/Challenges/views/project/Project.jsx b/common/app/routes/Challenges/views/project/Project.jsx index 83bd4aa3a2..b8eb5de4ad 100644 --- a/common/app/routes/Challenges/views/project/Project.jsx +++ b/common/app/routes/Challenges/views/project/Project.jsx @@ -6,7 +6,7 @@ import { Col, Image } from 'react-bootstrap'; import SidePanel from './Side-Panel.jsx'; import ToolPanel from './Tool-Panel.jsx'; -import BugModal from '../../Bug-Modal.jsx'; +import HelpModal from '../../Help-Modal.jsx'; import { challengeMetaSelector } from '../../redux'; import { challengeSelector } from '../../../../redux'; @@ -45,7 +45,7 @@ export class Project extends PureComponent { isCompleted, description } = this.props; - const imageURL = '//i.imgur.com/' + image + '.png'; + const imageURL = 'https://i.imgur.com/' + image + '.png'; return (
-
- + ); } diff --git a/common/app/routes/Challenges/views/project/Tool-Panel.jsx b/common/app/routes/Challenges/views/project/Tool-Panel.jsx index 96c3a34a76..44bb6e91a3 100644 --- a/common/app/routes/Challenges/views/project/Tool-Panel.jsx +++ b/common/app/routes/Challenges/views/project/Tool-Panel.jsx @@ -13,9 +13,10 @@ import { submittingSelector } from './redux'; import { submitChallenge, - openBugModal, - chatRoomSelector + openHelpModal, + chatRoomSelector, + guideURLSelector } from '../../redux'; import { @@ -28,32 +29,36 @@ import { } from '../../../../utils/challengeTypes'; const propTypes = { + guideUrl: PropTypes.string, helpChatRoom: PropTypes.string.isRequired, isFrontEnd: PropTypes.bool, isSignedIn: PropTypes.bool, isSimple: PropTypes.bool, isSubmitting: PropTypes.bool, - openBugModal: PropTypes.func.isRequired, + openHelpModal: PropTypes.func.isRequired, submitChallenge: PropTypes.func.isRequired }; const mapDispatchToProps = { - submitChallenge, - openBugModal + openHelpModal, + submitChallenge }; const mapStateToProps = createSelector( challengeSelector, signInLoadingSelector, submittingSelector, chatRoomSelector, + guideURLSelector, ( { challengeType = simpleProject }, showLoading, isSubmitting, helpChatRoom, + guideUrl ) => ({ + guideUrl, + helpChatRoom, isSignedIn: !showLoading, isSubmitting, - helpChatRoom, isSimple: challengeType === simpleProject, isFrontEnd: challengeType === frontEndProject }) @@ -78,13 +83,14 @@ export class ToolPanel extends PureComponent { render() { const { + guideUrl, + helpChatRoom, isFrontEnd, isSimple, isSignedIn, isSubmitting, - helpChatRoom, - submitChallenge, - openBugModal + openHelpModal, + submitChallenge } = this.props; const FormElement = isFrontEnd ? FrontEndForm : BackEndForm; @@ -96,7 +102,7 @@ export class ToolPanel extends PureComponent { }
- + +