feat: use eslint with prettier to format code

This commit is contained in:
Valeriy
2019-02-19 01:59:12 +03:00
committed by mrugesh mohapatra
parent be36915605
commit fc8c71ad16
70 changed files with 254 additions and 236 deletions

View File

@ -25,7 +25,7 @@ export default function addReturnToUrl() {
req.method !== 'GET' || req.method !== 'GET' ||
pathsOfNoReturnRegex.test(path) || pathsOfNoReturnRegex.test(path) ||
!whiteListRegex.test(path) || !whiteListRegex.test(path) ||
(/hot/i).test(req.path) /hot/i.test(req.path)
) { ) {
return next(); return next();
} }

View File

@ -8,7 +8,7 @@ export default function() {
}); });
return function csrf(req, res, next) { return function csrf(req, res, next) {
const path = req.path.split('/')[1]; const path = req.path.split('/')[1];
if ((/(^api$|^unauthenticated$|^internal$|^p$)/).test(path)) { if (/(^api$|^unauthenticated$|^internal$|^p$)/.test(path)) {
return next(); return next();
} }
return protection(req, res, next); return protection(req, res, next);

View File

@ -17,7 +17,7 @@ const getFirstChallenge = _.once(_getFirstChallenge);
* interface ChallengeMap { * interface ChallengeMap {
* result: { * result: {
* superBlocks: [ ...superBlockDashedName: String ] * superBlocks: [ ...superBlockDashedName: String ]
* }, * },
* entities: { * entities: {
* superBlock: { * superBlock: {
* [ ...superBlockDashedName ]: SuperBlock * [ ...superBlockDashedName ]: SuperBlock
@ -49,10 +49,12 @@ export function _cachedMap({ Block, Challenge }) {
}); });
const blockMap = Observable.combineLatest( const blockMap = Observable.combineLatest(
blocks.map(blocks => blocks.map(blocks =>
blocks.map(block => block.toJSON()).reduce((hash, block) => { blocks
hash[block.dashedName] = block; .map(block => block.toJSON())
return hash; .reduce((hash, block) => {
}, {}) hash[block.dashedName] = block;
return hash;
}, {})
), ),
challenges challenges
).map(([blocksMap, challenges]) => { ).map(([blocksMap, challenges]) => {

View File

@ -35,14 +35,14 @@ export const wrapPageElement = ({ element, props }) => {
</DefaultLayout> </DefaultLayout>
); );
} }
if ((/^\/guide(\/.*)*/).test(pathname)) { if (/^\/guide(\/.*)*/.test(pathname)) {
return ( return (
<DefaultLayout> <DefaultLayout>
<GuideLayout>{element}</GuideLayout> <GuideLayout>{element}</GuideLayout>
</DefaultLayout> </DefaultLayout>
); );
} }
if ((/^\/learn(\/.*)*/).test(pathname)) { if (/^\/learn(\/.*)*/.test(pathname)) {
return <DefaultLayout showFooter={false}>{element}</DefaultLayout>; return <DefaultLayout showFooter={false}>{element}</DefaultLayout>;
} }
return <DefaultLayout>{element}</DefaultLayout>; return <DefaultLayout>{element}</DefaultLayout>;

View File

@ -148,8 +148,8 @@ exports.onCreateWebpackConfig = ({ stage, rules, plugins, actions }) => {
/* eslint-disable max-len */ /* eslint-disable max-len */
exclude: modulePath => { exclude: modulePath => {
return ( return (
(/node_modules/).test(modulePath) && /node_modules/.test(modulePath) &&
!(/(ansi-styles|chalk|strict-uri-encode|react-freecodecamp-search)/).test( !/(ansi-styles|chalk|strict-uri-encode|react-freecodecamp-search)/.test(
modulePath modulePath
) )
); );

View File

@ -35,14 +35,14 @@ export const wrapPageElement = ({ element, props }) => {
</DefaultLayout> </DefaultLayout>
); );
} }
if ((/^\/guide(\/.*)*/).test(pathname)) { if (/^\/guide(\/.*)*/.test(pathname)) {
return ( return (
<DefaultLayout> <DefaultLayout>
<GuideLayout>{element}</GuideLayout> <GuideLayout>{element}</GuideLayout>
</DefaultLayout> </DefaultLayout>
); );
} }
if ((/^\/learn(\/.*)*/).test(pathname)) { if (/^\/learn(\/.*)*/.test(pathname)) {
return <DefaultLayout showFooter={false}>{element}</DefaultLayout>; return <DefaultLayout showFooter={false}>{element}</DefaultLayout>;
} }
return <DefaultLayout>{element}</DefaultLayout>; return <DefaultLayout>{element}</DefaultLayout>;

View File

@ -31,28 +31,26 @@ exports.sourceNodes = function sourceChallengesSourceNodes(
persistent: true persistent: true
}); });
watcher.on('ready', sourceAndCreateNodes).on( watcher.on('ready', sourceAndCreateNodes).on('change', filePath =>
'change', /\.md$/.test(filePath)
filePath => ? onSourceChange(filePath)
(/\.md$/).test(filePath) .then(challenge => {
? onSourceChange(filePath) reporter.info(
.then(challenge => { `File changed at ${filePath}, replacing challengeNode id ${
reporter.info( challenge.id
`File changed at ${filePath}, replacing challengeNode id ${ }`
challenge.id );
}` return createChallengeNode(challenge, reporter);
); })
return createChallengeNode(challenge, reporter); .then(createNode)
}) .catch(e =>
.then(createNode) reporter.error(`fcc-replace-challenge
.catch(e =>
reporter.error(`fcc-replace-challenge
${e.message} ${e.message}
`) `)
) )
: null : null
); );
function sourceAndCreateNodes() { function sourceAndCreateNodes() {

View File

@ -20,10 +20,7 @@ function markdownToHTML(node) {
} }
module.exports = function forumEmojiPlugin({ markdownAST }) { module.exports = function forumEmojiPlugin({ markdownAST }) {
visit( visit(markdownAST, 'image', imageNode =>
markdownAST, emojiRE.test(imageNode.title) ? markdownToHTML(imageNode) : imageNode
'image',
imageNode =>
emojiRE.test(imageNode.title) ? markdownToHTML(imageNode) : imageNode
); );
}; };

View File

@ -191,7 +191,7 @@ function ShowSettings(props) {
bsStyle='primary' bsStyle='primary'
className='btn-invert' className='btn-invert'
href={`/${username}`} href={`/${username}`}
> >
Show me my public portfolio Show me my public portfolio
</Button> </Button>
<Button <Button
@ -201,7 +201,7 @@ function ShowSettings(props) {
className='btn-invert' className='btn-invert'
href={'/signout'} href={'/signout'}
onClick={createHandleSignoutClick(hardGoTo)} onClick={createHandleSignoutClick(hardGoTo)}
> >
Sign me out of freeCodeCamp Sign me out of freeCodeCamp
</Button> </Button>
</FullWidthRow> </FullWidthRow>

View File

@ -33,7 +33,7 @@ function ShowUnsubscribed({ unsubscribeId }) {
bsSize='lg' bsSize='lg'
bsStyle='primary' bsStyle='primary'
href={`${apiLocation}/internal/resubscribe/${unsubscribeId}`} href={`${apiLocation}/internal/resubscribe/${unsubscribeId}`}
> >
You can click here to resubscribe You can click here to resubscribe
</Button> </Button>
</FullWidthRow> </FullWidthRow>

View File

@ -18,8 +18,8 @@ function DonateCompletion({ processing, reset, success, error = null }) {
const heading = processing const heading = processing
? 'We are processing your donation.' ? 'We are processing your donation.'
: success : success
? 'Your donation was successful.' ? 'Your donation was successful.'
: 'Something went wrong with your donation'; : 'Something went wrong with your donation';
return ( return (
<Alert bsStyle={style} className='donation-completion'> <Alert bsStyle={style} className='donation-completion'>
<h4>{heading}</h4> <h4>{heading}</h4>

View File

@ -184,7 +184,7 @@ class DonateForm extends Component {
disabled={!isFormValid} disabled={!isFormValid}
id='confirm-donation-btn' id='confirm-donation-btn'
type='submit' type='submit'
> >
Confirm your donation of $5 / month Confirm your donation of $5 / month
</Button> </Button>
<Spacer /> <Spacer />

View File

@ -20,9 +20,12 @@ import DonateText from './DonateText';
import '../Donation.css'; import '../Donation.css';
const mapStateToProps = createSelector(isDonationModalOpenSelector, show => ({ const mapStateToProps = createSelector(
show isDonationModalOpenSelector,
})); show => ({
show
})
);
const mapDispatchToProps = dispatch => const mapDispatchToProps = dispatch =>
bindActionCreators( bindActionCreators(

View File

@ -15,7 +15,7 @@ function Flash({ messages, onClose }) {
className='flash-message' className='flash-message'
key={id} key={id}
onDismiss={createDismissHandler(onClose, id)} onDismiss={createDismissHandler(onClose, id)}
> >
<div dangerouslySetInnerHTML={{ __html: message }} /> <div dangerouslySetInnerHTML={{ __html: message }} />
</Alert> </Alert>
)); ));

View File

@ -19,7 +19,7 @@ const ColHeader = ({ children, ...other }) => (
ColHeader.propTypes = propTypes; ColHeader.propTypes = propTypes;
const Link = ({ children, to, external, ...other }) => { const Link = ({ children, to, external, ...other }) => {
if (!external && (/^\/(?!\/)/).test(to)) { if (!external && /^\/(?!\/)/.test(to)) {
return ( return (
<GatsbyLink to={to} {...other}> <GatsbyLink to={to} {...other}>
{children} {children}

View File

@ -12,9 +12,12 @@ import { gtagReportConversion } from '../../../analytics/gtag';
import './login.css'; import './login.css';
const mapStateToProps = createSelector(isSignedInSelector, isSignedIn => ({ const mapStateToProps = createSelector(
isSignedIn isSignedInSelector,
})); isSignedIn => ({
isSignedIn
})
);
const mapDispatchToProps = dispatch => ({ const mapDispatchToProps = dispatch => ({
navigate: location => dispatch(hardGoTo(location)) navigate: location => dispatch(hardGoTo(location))
}); });
@ -38,7 +41,7 @@ function Login(props) {
className={ className={
(restProps.block ? 'btn-cta-big' : '') + ' signup-btn btn-cta' (restProps.block ? 'btn-cta-big' : '') + ' signup-btn btn-cta'
} }
> >
{children || 'Sign In'} {children || 'Sign In'}
</Button> </Button>
</a> </a>

View File

@ -6,9 +6,12 @@ import { createSelector } from 'reselect';
import { userSelector } from '../../../redux'; import { userSelector } from '../../../redux';
const mapStateToProps = createSelector(userSelector, ({ picture }) => ({ const mapStateToProps = createSelector(
picture userSelector,
})); ({ picture }) => ({
picture
})
);
function SignedIn({ picture }) { function SignedIn({ picture }) {
return ( return (

View File

@ -78,7 +78,7 @@ class Header extends Component {
className='menu-button' className='menu-button'
onClick={this.toggleClass} onClick={this.toggleClass}
ref={this.menuButtonRef} ref={this.menuButtonRef}
> >
Menu Menu
</span> </span>
<Media onChange={this.handleMediaChange} query='(max-width: 734px)' /> <Media onChange={this.handleMediaChange} query='(max-width: 734px)' />

View File

@ -93,14 +93,14 @@ export class Block extends Component {
<li <li
className={'map-challenge-title' + completedClass} className={'map-challenge-title' + completedClass}
key={'map-challenge' + challenge.fields.slug} key={'map-challenge' + challenge.fields.slug}
> >
<span className='badge map-badge'> <span className='badge map-badge'>
{i !== 0 && this.renderCheckMark(challenge.isCompleted)} {i !== 0 && this.renderCheckMark(challenge.isCompleted)}
</span> </span>
<Link <Link
onClick={this.handleChallengeClick(challenge.fields.slug)} onClick={this.handleChallengeClick(challenge.fields.slug)}
to={challenge.fields.slug} to={challenge.fields.slug}
> >
{challenge.title || challenge.frontmatter.title} {challenge.title || challenge.frontmatter.title}
</Link> </Link>
</li> </li>

View File

@ -14,9 +14,10 @@ import { ChallengeNode } from '../../../redux/propTypes';
const mapStateToProps = (state, ownProps) => { const mapStateToProps = (state, ownProps) => {
const expandedSelector = makeExpandedSuperBlockSelector(ownProps.superBlock); const expandedSelector = makeExpandedSuperBlockSelector(ownProps.superBlock);
return createSelector(expandedSelector, isExpanded => ({ isExpanded }))( return createSelector(
state expandedSelector,
); isExpanded => ({ isExpanded })
)(state);
}; };
function mapDispatchToProps(dispatch) { function mapDispatchToProps(dispatch) {

View File

@ -75,7 +75,7 @@ function Supporters({ isDonating, activeDonations }) {
bsStyle='primary' bsStyle='primary'
href='https://donate.freecodecamp.org' href='https://donate.freecodecamp.org'
target='_blank' target='_blank'
> >
Click here to become a Supporter Click here to become a Supporter
</Button> </Button>
</FullWidthRow> </FullWidthRow>

View File

@ -50,7 +50,7 @@ export function DynamicForm({
id={`dynamic-${id}`} id={`dynamic-${id}`}
onSubmit={handleSubmit(submit)} onSubmit={handleSubmit(submit)}
style={{ width: '100%' }} style={{ width: '100%' }}
> >
<FormFields errors={errors} fields={fields} options={options} /> <FormFields errors={errors} fields={fields} options={options} />
<BlockSaveWrapper> <BlockSaveWrapper>
{hideButton ? null : ( {hideButton ? null : (
@ -59,7 +59,7 @@ export function DynamicForm({
(allPristine && !enableSubmit) || (allPristine && !enableSubmit) ||
!!Object.keys(errors).filter(key => errors[key]).length !!Object.keys(errors).filter(key => errors[key]).length
} }
> >
{buttonText ? buttonText : null} {buttonText ? buttonText : null}
</BlockSaveButton> </BlockSaveButton>
)} )}

View File

@ -65,7 +65,7 @@ export function getValidationState(field) {
return null; return null;
} }
if ((/https?:\/\/glitch\.com\/edit\/#!\/.*/g).test(field.value)) { if (/https?:\/\/glitch\.com\/edit\/#!\/.*/g.test(field.value)) {
return 'glitch-warning'; return 'glitch-warning';
} }

View File

@ -36,7 +36,7 @@ export default function ToggleButton({
disabled={value} disabled={value}
type='radio' type='radio'
value={1} value={1}
> >
{onLabel} {onLabel}
</TB> </TB>
<TB <TB
@ -46,7 +46,7 @@ export default function ToggleButton({
disabled={!value} disabled={!value}
type='radio' type='radio'
value={2} value={2}
> >
{offLabel} {offLabel}
</TB> </TB>
</BSBG> </BSBG>

View File

@ -10,7 +10,7 @@ function BlockSaveButton({ children, ...restProps }) {
bsStyle='primary' bsStyle='primary'
type='submit' type='submit'
{...restProps} {...restProps}
> >
{children || 'Save'} {children || 'Save'}
</Button> </Button>
); );

View File

@ -155,7 +155,7 @@ class DefaultLayout extends Component {
}, },
{ name: 'keywords', content: metaKeywords.join(', ') } { name: 'keywords', content: metaKeywords.join(', ') }
]} ]}
> >
<style>{fontawesome.dom.css()}</style> <style>{fontawesome.dom.css()}</style>
</Helmet> </Helmet>
<Header disableSettings={disableSettings} /> <Header disableSettings={disableSettings} />

View File

@ -75,7 +75,7 @@ class GuideLayout extends React.Component {
md={4} md={4}
smHidden={!displaySideNav} smHidden={!displaySideNav}
xsHidden={!displaySideNav} xsHidden={!displaySideNav}
> >
<SideNav <SideNav
expandedState={expandedState} expandedState={expandedState}
onNavigate={this.handleNavigation} onNavigate={this.handleNavigation}
@ -88,13 +88,13 @@ class GuideLayout extends React.Component {
md={8} md={8}
smHidden={displaySideNav} smHidden={displaySideNav}
xsHidden={displaySideNav} xsHidden={displaySideNav}
> >
<main <main
className='content' className='content'
id='main' id='main'
ref={this.getContentRef} ref={this.getContentRef}
tabIndex='-1' tabIndex='-1'
> >
{this.props.children} {this.props.children}
</main> </main>
</Col> </Col>

View File

@ -29,7 +29,7 @@ function NoArticles() {
} }
rel='noopener noreferrer' rel='noopener noreferrer'
target='_blank' target='_blank'
> >
write one? write one?
</a> </a>
</span> </span>
@ -92,7 +92,7 @@ class NavPanel extends Component {
bsClass='panelStyle panel' bsClass='panelStyle panel'
id={`${dashedName}-panel`} id={`${dashedName}-panel`}
role='listitem' role='listitem'
> >
<Panel.Heading>{this.renderHeader()}</Panel.Heading> <Panel.Heading>{this.renderHeader()}</Panel.Heading>
{isExpanded ? <Panel.Body>{this.renderBody()}</Panel.Body> : null} {isExpanded ? <Panel.Body>{this.renderBody()}</Panel.Body> : null}
</Panel> </Panel>

View File

@ -57,7 +57,7 @@ class SideNav extends Component {
path={parent.path} path={parent.path}
title={title} title={title}
toggleDisplaySideNav={this.props.toggleDisplaySideNav} toggleDisplaySideNav={this.props.toggleDisplaySideNav}
> >
{children} {children}
</NavPanel> </NavPanel>
); );

View File

@ -81,7 +81,7 @@ function renderSettingsButton() {
bsSize='lg' bsSize='lg'
bsStyle='primary' bsStyle='primary'
className='btn-invert' className='btn-invert'
> >
Update my settings Update my settings
</Button> </Button>
</Link> </Link>

View File

@ -123,7 +123,7 @@ function renderCertShow(username, cert) {
bsSize='lg' bsSize='lg'
bsStyle='primary' bsStyle='primary'
className='btn-invert' className='btn-invert'
> >
View {cert.title} View {cert.title}
</Button> </Button>
</Link> </Link>

View File

@ -140,7 +140,7 @@ class Timeline extends Component {
aria-labelledby='contained-modal-title' aria-labelledby='contained-modal-title'
onHide={this.closeSolution} onHide={this.closeSolution}
show={solutionOpen} show={solutionOpen}
> >
<Modal.Header closeButton={true}> <Modal.Header closeButton={true}>
<Modal.Title id='contained-modal-title'> <Modal.Title id='contained-modal-title'>
{`${username}'s Solution to ${blockNameify(idToNameMap[id])}`} {`${username}'s Solution to ${blockNameify(idToNameMap[id])}`}

View File

@ -142,7 +142,7 @@ class CertificationSettings extends Component {
bsStyle='primary' bsStyle='primary'
className='btn-invert' className='btn-invert'
onClick={onClickHandler} onClick={onClickHandler}
> >
Show Code Show Code
</Button> </Button>
); );
@ -156,13 +156,13 @@ class CertificationSettings extends Component {
className='btn-invert' className='btn-invert'
id={`dropdown-for-${projectId}`} id={`dropdown-for-${projectId}`}
title='Show Solutions' title='Show Solutions'
> >
<MenuItem <MenuItem
bsStyle='primary' bsStyle='primary'
href={solution} href={solution}
rel='noopener noreferrer' rel='noopener noreferrer'
target='_blank' target='_blank'
> >
Front End Front End
</MenuItem> </MenuItem>
<MenuItem <MenuItem
@ -170,7 +170,7 @@ class CertificationSettings extends Component {
href={githubLink} href={githubLink}
rel='noopener noreferrer' rel='noopener noreferrer'
target='_blank' target='_blank'
> >
Back End Back End
</MenuItem> </MenuItem>
</DropdownButton> </DropdownButton>
@ -186,7 +186,7 @@ class CertificationSettings extends Component {
href={solution} href={solution}
rel='noopener noreferrer' rel='noopener noreferrer'
target='_blank' target='_blank'
> >
Show Solution Show Solution
</Button> </Button>
); );
@ -197,7 +197,7 @@ class CertificationSettings extends Component {
bsStyle='primary' bsStyle='primary'
className='btn-invert' className='btn-invert'
onClick={onClickHandler} onClick={onClickHandler}
> >
Show Code Show Code
</Button> </Button>
); );
@ -258,7 +258,7 @@ class CertificationSettings extends Component {
bsStyle='primary' bsStyle='primary'
href={certLocation} href={certLocation}
onClick={createClickHandler(superBlock)} onClick={createClickHandler(superBlock)}
> >
{isCert ? 'Show Certification' : 'Claim Certification'} {isCert ? 'Show Certification' : 'Claim Certification'}
</Button> </Button>
</td> </td>
@ -280,7 +280,7 @@ class CertificationSettings extends Component {
bsSize='large' bsSize='large'
onHide={this.handleSolutionModalHide} onHide={this.handleSolutionModalHide}
show={isOpen} show={isOpen}
> >
<Modal.Header className='this-one?' closeButton={true}> <Modal.Header className='this-one?' closeButton={true}>
<Modal.Title id='solution-viewer-modal-title'> <Modal.Title id='solution-viewer-modal-title'>
Solution for {projectTitle} Solution for {projectTitle}

View File

@ -189,7 +189,7 @@ class EmailSettings extends Component {
<FormGroup <FormGroup
controlId='new-email' controlId='new-email'
validationState={newEmailValidation} validationState={newEmailValidation}
> >
<ControlLabel>New Email</ControlLabel> <ControlLabel>New Email</ControlLabel>
<FormControl <FormControl
onChange={this.createHandleEmailFormChange('newEmail')} onChange={this.createHandleEmailFormChange('newEmail')}
@ -203,7 +203,7 @@ class EmailSettings extends Component {
<FormGroup <FormGroup
controlId='confirm-email' controlId='confirm-email'
validationState={confirmEmailValidation} validationState={confirmEmailValidation}
> >
<ControlLabel>Confirm New Email</ControlLabel> <ControlLabel>Confirm New Email</ControlLabel>
<FormControl <FormControl
onChange={this.createHandleEmailFormChange('confirmNewEmail')} onChange={this.createHandleEmailFormChange('confirmNewEmail')}

View File

@ -96,7 +96,7 @@ class InternetSettings extends Component {
<FormGroup <FormGroup
controlId='internet-github' controlId='internet-github'
validationState={this.getValidationStateFor(githubProfile)} validationState={this.getValidationStateFor(githubProfile)}
> >
<ControlLabel> <ControlLabel>
<strong>GitHub</strong> <strong>GitHub</strong>
</ControlLabel> </ControlLabel>
@ -109,7 +109,7 @@ class InternetSettings extends Component {
<FormGroup <FormGroup
controlId='internet-linkedin' controlId='internet-linkedin'
validationState={this.getValidationStateFor(linkedin)} validationState={this.getValidationStateFor(linkedin)}
> >
<ControlLabel> <ControlLabel>
<strong>LinkedIn</strong> <strong>LinkedIn</strong>
</ControlLabel> </ControlLabel>
@ -122,7 +122,7 @@ class InternetSettings extends Component {
<FormGroup <FormGroup
controlId='internet-picture' controlId='internet-picture'
validationState={this.getValidationStateFor(twitter)} validationState={this.getValidationStateFor(twitter)}
> >
<ControlLabel> <ControlLabel>
<strong>Twitter</strong> <strong>Twitter</strong>
</ControlLabel> </ControlLabel>
@ -135,7 +135,7 @@ class InternetSettings extends Component {
<FormGroup <FormGroup
controlId='internet-website' controlId='internet-website'
validationState={this.getValidationStateFor(website)} validationState={this.getValidationStateFor(website)}
> >
<ControlLabel> <ControlLabel>
<strong>Personal Website</strong> <strong>Personal Website</strong>
</ControlLabel> </ControlLabel>

View File

@ -177,7 +177,7 @@ class PortfolioSettings extends Component {
if (isImage && !maybeUrl) { if (isImage && !maybeUrl) {
return { state: null, message: '' }; return { state: null, message: '' };
} }
if (isImage && !(/\.(png|jpg|jpeg|gif)$/).test(maybeUrl)) { if (isImage && !/\.(png|jpg|jpeg|gif)$/.test(maybeUrl)) {
return { return {
state: 'error', state: 'error',
message: 'URL must link directly to an image file' message: 'URL must link directly to an image file'
@ -214,7 +214,7 @@ class PortfolioSettings extends Component {
validationState={ validationState={
pristine || (!pristine && !title) ? null : titleState pristine || (!pristine && !title) ? null : titleState
} }
> >
<ControlLabel>Title</ControlLabel> <ControlLabel>Title</ControlLabel>
<FormControl <FormControl
onChange={this.createOnChangeHandler(id, 'title')} onChange={this.createOnChangeHandler(id, 'title')}
@ -229,7 +229,7 @@ class PortfolioSettings extends Component {
validationState={ validationState={
pristine || (!pristine && !url) ? null : urlState pristine || (!pristine && !url) ? null : urlState
} }
> >
<ControlLabel>URL</ControlLabel> <ControlLabel>URL</ControlLabel>
<FormControl <FormControl
onChange={this.createOnChangeHandler(id, 'url')} onChange={this.createOnChangeHandler(id, 'url')}
@ -242,7 +242,7 @@ class PortfolioSettings extends Component {
<FormGroup <FormGroup
controlId={`${id}-image`} controlId={`${id}-image`}
validationState={pristine ? null : imageState} validationState={pristine ? null : imageState}
> >
<ControlLabel>Image</ControlLabel> <ControlLabel>Image</ControlLabel>
<FormControl <FormControl
onChange={this.createOnChangeHandler(id, 'image')} onChange={this.createOnChangeHandler(id, 'image')}
@ -254,7 +254,7 @@ class PortfolioSettings extends Component {
<FormGroup <FormGroup
controlId={`${id}-description`} controlId={`${id}-description`}
validationState={pristine ? null : descriptionState} validationState={pristine ? null : descriptionState}
> >
<ControlLabel>Description</ControlLabel> <ControlLabel>Description</ControlLabel>
<FormControl <FormControl
componentClass='textarea' componentClass='textarea'
@ -277,7 +277,7 @@ class PortfolioSettings extends Component {
/* eslint-enable camelcase */ /* eslint-enable camelcase */
}) })
} }
> >
Save this portfolio item Save this portfolio item
</BlockSaveButton> </BlockSaveButton>
<ButtonSpacer /> <ButtonSpacer />
@ -288,7 +288,7 @@ class PortfolioSettings extends Component {
className='btn-delete-portfolio' className='btn-delete-portfolio'
onClick={() => this.handleRemoveItem(id)} onClick={() => this.handleRemoveItem(id)}
type='button' type='button'
> >
Remove this portfolio item Remove this portfolio item
</Button> </Button>
</form> </form>
@ -325,7 +325,7 @@ class PortfolioSettings extends Component {
bsStyle='primary' bsStyle='primary'
onClick={this.handleAdd} onClick={this.handleAdd}
type='button' type='button'
> >
Add a new portfolio Item Add a new portfolio Item
</Button> </Button>
</FullWidthRow> </FullWidthRow>

View File

@ -14,10 +14,13 @@ import Spacer from '../helpers/Spacer';
import ToggleSetting from './ToggleSetting'; import ToggleSetting from './ToggleSetting';
import SectionHeader from './SectionHeader'; import SectionHeader from './SectionHeader';
const mapStateToProps = createSelector(userSelector, user => ({ const mapStateToProps = createSelector(
...user.profileUI, userSelector,
user user => ({
})); ...user.profileUI,
user
})
);
const mapDispatchToProps = dispatch => const mapDispatchToProps = dispatch =>
bindActionCreators({ submitProfileUI }, dispatch); bindActionCreators({ submitProfileUI }, dispatch);
@ -130,7 +133,7 @@ class PrivacySettings extends Component {
toggleFlag={this.toggleFlag('showLocation')} toggleFlag={this.toggleFlag('showLocation')}
/> />
<ToggleSetting <ToggleSetting
action='My &quot;about me&quot;' action='My "about me"'
flag={!showAbout} flag={!showAbout}
flagName='showAbout' flagName='showAbout'
offLabel='Public' offLabel='Public'
@ -203,7 +206,7 @@ class PrivacySettings extends Component {
href={`data:text/json;charset=utf-8,${encodeURIComponent( href={`data:text/json;charset=utf-8,${encodeURIComponent(
JSON.stringify(user) JSON.stringify(user)
)}`} )}`}
> >
Download your data Download your data
</Button> </Button>
</FullWidthRow> </FullWidthRow>

View File

@ -42,7 +42,7 @@ function SolutionViewer({
bsStyle='primary' bsStyle='primary'
className='solution-viewer' className='solution-viewer'
key={solution.slice(0, 10)} key={solution.slice(0, 10)}
> >
<Panel.Heading>JS</Panel.Heading> <Panel.Heading>JS</Panel.Heading>
<Panel.Body> <Panel.Body>
<pre> <pre>

View File

@ -91,9 +91,8 @@ class UsernameSettings extends Component {
characterValidation: { valid } characterValidation: { valid }
} = this.state; } = this.state;
return this.setState( return this.setState({ submitClicked: true }, () =>
{ submitClicked: true }, valid ? submitNewUsername(formValue) : null
() => (valid ? submitNewUsername(formValue) : null)
); );
} }

View File

@ -81,7 +81,7 @@ class NavigationContextProvider extends Component {
toggleDisplaySideNav: noop, toggleDisplaySideNav: noop,
toggleExpandedState: this.toggleExpandedState toggleExpandedState: this.toggleExpandedState
}} }}
> >
{children} {children}
</Provider> </Provider>
); );

View File

@ -101,13 +101,13 @@ class AcceptPrivacyTerms extends Component {
id='terms-of-service' id='terms-of-service'
inline={true} inline={true}
onChange={this.createHandleChange('termsOfService')} onChange={this.createHandleChange('termsOfService')}
> >
I accept the{' '} I accept the{' '}
<a <a
href='https://www.freecodecamp/terms' href='https://www.freecodecamp/terms'
rel='noopener noreferrer' rel='noopener noreferrer'
target='_blank' target='_blank'
> >
terms of service terms of service
</a>{' '} </a>{' '}
(required) (required)
@ -123,13 +123,13 @@ class AcceptPrivacyTerms extends Component {
id='privacy-policy' id='privacy-policy'
inline={true} inline={true}
onChange={this.createHandleChange('privacyPolicy')} onChange={this.createHandleChange('privacyPolicy')}
> >
I accept the{' '} I accept the{' '}
<a <a
href='https://www.freecodecamp/privacy' href='https://www.freecodecamp/privacy'
rel='noopener noreferrer' rel='noopener noreferrer'
target='_blank' target='_blank'
> >
privacy policy privacy policy
</a>{' '} </a>{' '}
(required) (required)
@ -145,7 +145,7 @@ class AcceptPrivacyTerms extends Component {
id='quincy-email' id='quincy-email'
inline={true} inline={true}
onChange={this.createHandleChange('quincyEmail')} onChange={this.createHandleChange('quincyEmail')}
> >
I want weekly emails from Quincy, freeCodeCamp.org's I want weekly emails from Quincy, freeCodeCamp.org's
founder. founder.
</Checkbox> </Checkbox>
@ -157,7 +157,7 @@ class AcceptPrivacyTerms extends Component {
className='big-cta-btn' className='big-cta-btn'
disabled={!privacyPolicy || !termsOfService} disabled={!privacyPolicy || !termsOfService}
type='submit' type='submit'
> >
Continue to freeCodeCamp Continue to freeCodeCamp
</Button> </Button>
</form> </form>

View File

@ -68,7 +68,7 @@ class DonateOtherPage extends Component {
}) })
} }
target='_blank' target='_blank'
> >
<input defaultValue='_s-xclick' name='cmd' type='hidden' />{' '} <input defaultValue='_s-xclick' name='cmd' type='hidden' />{' '}
<input <input
defaultValue={item.defaultValueHash} defaultValue={item.defaultValueHash}

View File

@ -35,7 +35,7 @@ function Index() {
href='https://freecodecamp.org' href='https://freecodecamp.org'
rel='noopener noreferrer' rel='noopener noreferrer'
target='_blank' target='_blank'
> >
freeCodeCamp.org freeCodeCamp.org
</a> </a>
{'. It has a curriculum that starts from zero and helps you learn' + {'. It has a curriculum that starts from zero and helps you learn' +
@ -48,7 +48,7 @@ function Index() {
href='https://github.com/freeCodeCamp/freeCodeCamp' href='https://github.com/freeCodeCamp/freeCodeCamp'
rel='noopener noreferrer' rel='noopener noreferrer'
target='_blank' target='_blank'
> >
open source open source
</a> </a>
{'. Your help in making it better is greatly appreciated!'} {'. Your help in making it better is greatly appreciated!'}

View File

@ -232,7 +232,7 @@ const IndexPage = () => (
href='https://donate.freecodecamp.org/' href='https://donate.freecodecamp.org/'
rel='noopener noreferrer' rel='noopener noreferrer'
target='_blank' target='_blank'
> >
make a tax-deductible donation here make a tax-deductible donation here
</a> </a>
</p> </p>

View File

@ -53,7 +53,7 @@ const IndexPage = ({
href='https://donate.freecodecamp.org' href='https://donate.freecodecamp.org'
rel='noopener noreferrer' rel='noopener noreferrer'
target='_blank' target='_blank'
> >
donate donate
</a>{' '} </a>{' '}
to our nonprofit. to our nonprofit.

View File

@ -30,7 +30,7 @@ function SoftwareResourcesForNonProfits() {
href='http://givecamp.org/' href='http://givecamp.org/'
rel='noopener noreferrer' rel='noopener noreferrer'
target='_blank' target='_blank'
> >
Give Camp Give Camp
</a> </a>
</li> </li>
@ -39,7 +39,7 @@ function SoftwareResourcesForNonProfits() {
href='http://www.volunteermatch.com' href='http://www.volunteermatch.com'
rel='noopener noreferrer' rel='noopener noreferrer'
target='_blank' target='_blank'
> >
Volunteer Match.com Volunteer Match.com
</a> </a>
</li> </li>
@ -48,7 +48,7 @@ function SoftwareResourcesForNonProfits() {
href='http://www.catchafire.org' href='http://www.catchafire.org'
rel='noopener noreferrer' rel='noopener noreferrer'
target='_blank' target='_blank'
> >
Catchafire Catchafire
</a> </a>
</li> </li>
@ -57,7 +57,7 @@ function SoftwareResourcesForNonProfits() {
href='http://anyonecanhaveawebsite.com' href='http://anyonecanhaveawebsite.com'
rel='noopener noreferrer' rel='noopener noreferrer'
target='_blank' target='_blank'
> >
Anyone Can Have A Website Anyone Can Have A Website
</a> </a>
</li> </li>
@ -69,7 +69,7 @@ function SoftwareResourcesForNonProfits() {
href='https://www.youtube.com/watch?v=4AXDKWuY9QM' href='https://www.youtube.com/watch?v=4AXDKWuY9QM'
rel='noopener noreferrer' rel='noopener noreferrer'
target='_blank' target='_blank'
> >
How to build and deploy a website without writing any code for How to build and deploy a website without writing any code for
free free
</a> </a>
@ -79,7 +79,7 @@ function SoftwareResourcesForNonProfits() {
href='http://www.wix.com/' href='http://www.wix.com/'
rel='noopener noreferrer' rel='noopener noreferrer'
target='_blank' target='_blank'
> >
Wix Wix
</a> </a>
</li> </li>
@ -88,7 +88,7 @@ function SoftwareResourcesForNonProfits() {
href='https://www.squarespace.com/' href='https://www.squarespace.com/'
rel='noopener noreferrer' rel='noopener noreferrer'
target='_blank' target='_blank'
> >
Square Space Square Space
</a> </a>
</li> </li>
@ -97,7 +97,7 @@ function SoftwareResourcesForNonProfits() {
href='https://wordpress.com/' href='https://wordpress.com/'
rel='noopener noreferrer' rel='noopener noreferrer'
target='_blank' target='_blank'
> >
WordPress WordPress
</a> </a>
</li> </li>
@ -106,7 +106,7 @@ function SoftwareResourcesForNonProfits() {
href='https://xprs.imcreator.com' href='https://xprs.imcreator.com'
rel='noopener noreferrer' rel='noopener noreferrer'
target='_blank' target='_blank'
> >
Imcreator.com Imcreator.com
</a> </a>
</li> </li>
@ -118,7 +118,7 @@ function SoftwareResourcesForNonProfits() {
href='http://causesignal.com' href='http://causesignal.com'
rel='noopener noreferrer' rel='noopener noreferrer'
target='_blank' target='_blank'
> >
Cause Signal Cause Signal
</a> </a>
</li> </li>
@ -127,7 +127,7 @@ function SoftwareResourcesForNonProfits() {
href='https://www.thedatabank.com/' href='https://www.thedatabank.com/'
rel='noopener noreferrer' rel='noopener noreferrer'
target='_blank' target='_blank'
> >
The Data Bank The Data Bank
</a> </a>
</li> </li>
@ -136,7 +136,7 @@ function SoftwareResourcesForNonProfits() {
href='http://www.donorsnap.com/' href='http://www.donorsnap.com/'
rel='noopener noreferrer' rel='noopener noreferrer'
target='_blank' target='_blank'
> >
Donor Snap Donor Snap
</a> </a>
</li> </li>
@ -145,7 +145,7 @@ function SoftwareResourcesForNonProfits() {
href='http://www.donorperfect.com/' href='http://www.donorperfect.com/'
rel='noopener noreferrer' rel='noopener noreferrer'
target='_blank' target='_blank'
> >
Donor Perfect Donor Perfect
</a> </a>
</li> </li>
@ -157,7 +157,7 @@ function SoftwareResourcesForNonProfits() {
} }
rel='noopener noreferrer' rel='noopener noreferrer'
target='_blank' target='_blank'
> >
E Tapestry E Tapestry
</a> </a>
</li> </li>
@ -166,7 +166,7 @@ function SoftwareResourcesForNonProfits() {
href='http://www.z2systems.com' href='http://www.z2systems.com'
rel='noopener noreferrer' rel='noopener noreferrer'
target='_blank' target='_blank'
> >
Z2 Systems Z2 Systems
</a> </a>
</li> </li>
@ -175,7 +175,7 @@ function SoftwareResourcesForNonProfits() {
href='http://www.regpacks.com/volunteer-management' href='http://www.regpacks.com/volunteer-management'
rel='noopener noreferrer' rel='noopener noreferrer'
target='_blank' target='_blank'
> >
Reg Packs Reg Packs
</a> </a>
</li> </li>
@ -184,7 +184,7 @@ function SoftwareResourcesForNonProfits() {
href='http://sumac.com' href='http://sumac.com'
rel='noopener noreferrer' rel='noopener noreferrer'
target='_blank' target='_blank'
> >
Sumac Sumac
</a> </a>
</li> </li>
@ -193,7 +193,7 @@ function SoftwareResourcesForNonProfits() {
href='http://www.volgistics.com' href='http://www.volgistics.com'
rel='noopener noreferrer' rel='noopener noreferrer'
target='_blank' target='_blank'
> >
Volgistics Volgistics
</a> </a>
</li> </li>
@ -205,7 +205,7 @@ function SoftwareResourcesForNonProfits() {
href='https://www.ordoro.com' href='https://www.ordoro.com'
rel='noopener noreferrer' rel='noopener noreferrer'
target='_blank' target='_blank'
> >
Ordoro Ordoro
</a> </a>
</li> </li>
@ -214,7 +214,7 @@ function SoftwareResourcesForNonProfits() {
href='http://www.unleashedsoftware.com' href='http://www.unleashedsoftware.com'
rel='noopener noreferrer' rel='noopener noreferrer'
target='_blank' target='_blank'
> >
Unleashed Software Unleashed Software
</a> </a>
</li> </li>
@ -223,7 +223,7 @@ function SoftwareResourcesForNonProfits() {
href='https://www.ezofficeinventory.com/industries/non-profits' href='https://www.ezofficeinventory.com/industries/non-profits'
rel='noopener noreferrer' rel='noopener noreferrer'
target='_blank' target='_blank'
> >
EZ Office Inventory EZ Office Inventory
</a> </a>
</li> </li>
@ -235,7 +235,7 @@ function SoftwareResourcesForNonProfits() {
href='http://www.dokeos.com' href='http://www.dokeos.com'
rel='noopener noreferrer' rel='noopener noreferrer'
target='_blank' target='_blank'
> >
Dokeos Dokeos
</a> </a>
</li> </li>
@ -244,7 +244,7 @@ function SoftwareResourcesForNonProfits() {
href='http://www.efrontlearning.net/' href='http://www.efrontlearning.net/'
rel='noopener noreferrer' rel='noopener noreferrer'
target='_blank' target='_blank'
> >
E Front Learning E Front Learning
</a> </a>
</li> </li>
@ -253,7 +253,7 @@ function SoftwareResourcesForNonProfits() {
href='https://moodle.org/' href='https://moodle.org/'
rel='noopener noreferrer' rel='noopener noreferrer'
target='_blank' target='_blank'
> >
Moodle Moodle
</a> </a>
</li> </li>
@ -262,7 +262,7 @@ function SoftwareResourcesForNonProfits() {
href='https://sakaiproject.org/' href='https://sakaiproject.org/'
rel='noopener noreferrer' rel='noopener noreferrer'
target='_blank' target='_blank'
> >
Sakai Project Sakai Project
</a> </a>
</li> </li>
@ -274,7 +274,7 @@ function SoftwareResourcesForNonProfits() {
href='https://civicrm.org/' href='https://civicrm.org/'
rel='noopener noreferrer' rel='noopener noreferrer'
target='_blank' target='_blank'
> >
CiviCRM CiviCRM
</a> </a>
</li> </li>
@ -283,7 +283,7 @@ function SoftwareResourcesForNonProfits() {
href='http://tcmgr.com/' href='http://tcmgr.com/'
rel='noopener noreferrer' rel='noopener noreferrer'
target='_blank' target='_blank'
> >
Total Community Manager Total Community Manager
</a> </a>
</li> </li>
@ -295,7 +295,7 @@ function SoftwareResourcesForNonProfits() {
href='http://www.google.com/forms' href='http://www.google.com/forms'
rel='noopener noreferrer' rel='noopener noreferrer'
target='_blank' target='_blank'
> >
Google Forms Google Forms
</a> </a>
</li> </li>
@ -304,7 +304,7 @@ function SoftwareResourcesForNonProfits() {
href='http://www.typeform.com' href='http://www.typeform.com'
rel='noopener noreferrer' rel='noopener noreferrer'
target='_blank' target='_blank'
> >
Typeform Typeform
</a> </a>
</li> </li>

View File

@ -92,12 +92,12 @@ class UpdateEmail extends Component {
<FormGroup <FormGroup
controlId='emailInput' controlId='emailInput'
validationState={this.getEmailValidationState()} validationState={this.getEmailValidationState()}
> >
<Col <Col
className='email-label' className='email-label'
componentClass={ControlLabel} componentClass={ControlLabel}
sm={2} sm={2}
> >
Email Email
</Col> </Col>
<Col sm={10}> <Col sm={10}>
@ -115,7 +115,7 @@ class UpdateEmail extends Component {
bsStyle='primary' bsStyle='primary'
disabled={this.getEmailValidationState() !== 'success'} disabled={this.getEmailValidationState() !== 'success'}
type='submit' type='submit'
> >
{isNewEmail ? 'Update my Email' : 'Verify Email'} {isNewEmail ? 'Update my Email' : 'Verify Email'}
</Button> </Button>
</Form> </Form>

View File

@ -43,7 +43,7 @@ class DesktopLayout extends Component {
renderOnResize={true} renderOnResize={true}
renderOnResizeRate={20} renderOnResizeRate={20}
{...resizeProps} {...resizeProps}
> >
{editor} {editor}
</ReflexElement> </ReflexElement>
<ReflexSplitter propagate={true} {...resizeProps} /> <ReflexSplitter propagate={true} {...resizeProps} />
@ -53,7 +53,7 @@ class DesktopLayout extends Component {
renderOnResize={true} renderOnResize={true}
renderOnResizeRate={20} renderOnResizeRate={20}
{...resizeProps} {...resizeProps}
> >
{testOutput} {testOutput}
</ReflexElement> </ReflexElement>
</ReflexContainer> </ReflexContainer>

View File

@ -58,7 +58,7 @@ class MobileLayout extends Component {
defaultActiveKey={1} defaultActiveKey={1}
id='challenge-page-tabs' id='challenge-page-tabs'
onSelect={moveToTab} onSelect={moveToTab}
> >
<TabPane eventKey={1} title='Instructions'> <TabPane eventKey={1} title='Instructions'>
{instructions} {instructions}
</TabPane> </TabPane>

View File

@ -10,7 +10,7 @@ const propTypes = {
}; };
function emptyInstruction(instructions) { function emptyInstruction(instructions) {
return (/^<section\s+id\s*=\s*("|')instructions\1\s*>\s*<\/section>$/).test( return /^<section\s+id\s*=\s*("|')instructions\1\s*>\s*<\/section>$/.test(
instructions instructions
); );
} }

View File

@ -120,11 +120,11 @@ export class CompletionModal extends Component {
onHide={close} onHide={close}
onKeyDown={isOpen ? handleKeypress : noop} onKeyDown={isOpen ? handleKeypress : noop}
show={isOpen} show={isOpen}
> >
<Modal.Header <Modal.Header
className='challenge-list-header fcc-modal' className='challenge-list-header fcc-modal'
closeButton={true} closeButton={true}
> >
<Modal.Title className='text-center'>{message}</Modal.Title> <Modal.Title className='text-center'>{message}</Modal.Title>
</Modal.Header> </Modal.Header>
<Modal.Body className='completion-modal-body'> <Modal.Body className='completion-modal-body'>
@ -138,7 +138,7 @@ export class CompletionModal extends Component {
bsSize='large' bsSize='large'
bsStyle='primary' bsStyle='primary'
onClick={submitChallenge} onClick={submitChallenge}
> >
Submit and go to next challenge{' '} Submit and go to next challenge{' '}
<span className='hidden-xs'>(Ctrl + Enter)</span> <span className='hidden-xs'>(Ctrl + Enter)</span>
</Button> </Button>
@ -150,7 +150,7 @@ export class CompletionModal extends Component {
className='btn-invert' className='btn-invert'
download={`${dashedName}.json`} download={`${dashedName}.json`}
href={this.state.downloadURL} href={this.state.downloadURL}
> >
Download my solution Download my solution
</Button> </Button>
) : null} ) : null}

View File

@ -37,7 +37,7 @@ export class HelpModal extends Component {
<Modal.Header <Modal.Header
className='help-modal-header fcc-modal' className='help-modal-header fcc-modal'
closeButton={true} closeButton={true}
> >
<Modal.Title className='text-center'>Ask for help?</Modal.Title> <Modal.Title className='text-center'>Ask for help?</Modal.Title>
</Modal.Header> </Modal.Header>
<Modal.Body className='help-modal-body text-center'> <Modal.Body className='help-modal-body text-center'>
@ -48,7 +48,7 @@ export class HelpModal extends Component {
rel='noopener noreferrer' rel='noopener noreferrer'
target='_blank' target='_blank'
title='Read, search, ask' title='Read, search, ask'
> >
Read-Search-Ask Read-Search-Ask
</a> </a>
&nbsp; method, then you can ask for help on the freeCodeCamp forum. &nbsp; method, then you can ask for help on the freeCodeCamp forum.
@ -58,7 +58,7 @@ export class HelpModal extends Component {
bsSize='lg' bsSize='lg'
bsStyle='primary' bsStyle='primary'
onClick={createQuestion} onClick={createQuestion}
> >
Create a help post on the forum Create a help post on the forum
</Button> </Button>
<Button <Button
@ -66,7 +66,7 @@ export class HelpModal extends Component {
bsSize='lg' bsSize='lg'
bsStyle='primary' bsStyle='primary'
onClick={closeHelpModal} onClick={closeHelpModal}
> >
Cancel Cancel
</Button> </Button>
</Modal.Body> </Modal.Body>

View File

@ -16,9 +16,12 @@ const propTypes = {
reset: PropTypes.func.isRequired reset: PropTypes.func.isRequired
}; };
const mapStateToProps = createSelector(isResetModalOpenSelector, isOpen => ({ const mapStateToProps = createSelector(
isOpen isResetModalOpenSelector,
})); isOpen => ({
isOpen
})
);
const mapDispatchToProps = dispatch => const mapDispatchToProps = dispatch =>
bindActionCreators( bindActionCreators(
@ -41,7 +44,7 @@ function ResetModal({ reset, close, isOpen }) {
keyboard={true} keyboard={true}
onHide={close} onHide={close}
show={isOpen} show={isOpen}
> >
<Modal.Header className='reset-modal-header' closeButton={true}> <Modal.Header className='reset-modal-header' closeButton={true}>
<Modal.Title className='text-center'>Reset this lesson?</Modal.Title> <Modal.Title className='text-center'>Reset this lesson?</Modal.Title>
</Modal.Header> </Modal.Header>
@ -62,7 +65,7 @@ function ResetModal({ reset, close, isOpen }) {
bsSize='large' bsSize='large'
bsStyle='danger' bsStyle='danger'
onClick={withActions(reset, close)} onClick={withActions(reset, close)}
> >
Reset this Lesson Reset this Lesson
</Button> </Button>
</Modal.Footer> </Modal.Footer>

View File

@ -13,9 +13,12 @@ import { initConsole, challengeTestsSelector } from '../redux';
import { createSelector } from 'reselect'; import { createSelector } from 'reselect';
import './side-panel.css'; import './side-panel.css';
const mapStateToProps = createSelector(challengeTestsSelector, tests => ({ const mapStateToProps = createSelector(
tests challengeTestsSelector,
})); tests => ({
tests
})
);
const mapDispatchToProps = dispatch => const mapDispatchToProps = dispatch =>
bindActionCreators( bindActionCreators(

View File

@ -38,7 +38,7 @@ function TestSuite({ tests }) {
className='test-result' className='test-result'
key={text.slice(-6) + index} key={text.slice(-6) + index}
tabIndex='0' tabIndex='0'
> >
<div className='test-status-icon'> <div className='test-status-icon'>
{isInitial ? <Initial /> : statusIcon} {isInitial ? <Initial /> : statusIcon}
</div> </div>

View File

@ -45,7 +45,7 @@ function ToolPanel({
className={`tool-panel-group ${ className={`tool-panel-group ${
isMobile ? 'tool-panel-group-mobile' : '' isMobile ? 'tool-panel-group-mobile' : ''
}`} }`}
> >
<Button block={true} bsStyle='primary' onClick={executeChallenge}> <Button block={true} bsStyle='primary' onClick={executeChallenge}>
{isMobile ? 'Run' : 'Run the Tests'} {isMobile ? 'Run' : 'Run the Tests'}
</Button> </Button>
@ -54,7 +54,7 @@ function ToolPanel({
bsStyle='primary' bsStyle='primary'
className='btn-invert' className='btn-invert'
onClick={openResetModal} onClick={openResetModal}
> >
{isMobile ? 'Reset' : 'Reset All Code'} {isMobile ? 'Reset' : 'Reset All Code'}
</Button> </Button>
{guideUrl ? ( {guideUrl ? (
@ -64,7 +64,7 @@ function ToolPanel({
className='btn-invert' className='btn-invert'
href={guideUrl} href={guideUrl}
target='_blank' target='_blank'
> >
{isMobile ? 'Hint' : 'Get a hint'} {isMobile ? 'Hint' : 'Get a hint'}
</Button> </Button>
) : null} ) : null}
@ -74,7 +74,7 @@ function ToolPanel({
bsStyle='primary' bsStyle='primary'
className='btn-invert' className='btn-invert'
onClick={openVideoModal} onClick={openVideoModal}
> >
{isMobile ? 'Video' : 'Watch a video'} {isMobile ? 'Video' : 'Watch a video'}
</Button> </Button>
) : null} ) : null}
@ -83,7 +83,7 @@ function ToolPanel({
bsStyle='primary' bsStyle='primary'
className='btn-invert' className='btn-invert'
onClick={openHelpModal} onClick={openHelpModal}
> >
{isMobile ? 'Help' : 'Ask for help'} {isMobile ? 'Help' : 'Ask for help'}
</Button> </Button>
</div> </div>

View File

@ -30,11 +30,11 @@ export class VideoModal extends Component {
dialogClassName='video-modal' dialogClassName='video-modal'
onHide={closeVideoModal} onHide={closeVideoModal}
show={isOpen} show={isOpen}
> >
<Modal.Header <Modal.Header
className='video-modal-header fcc-modal' className='video-modal-header fcc-modal'
closeButton={true} closeButton={true}
> >
<Modal.Title className='text-center'>Watch A Video</Modal.Title> <Modal.Title className='text-center'>Watch A Video</Modal.Title>
</Modal.Header> </Modal.Header>
<Modal.Body className='video-modal-body'> <Modal.Body className='video-modal-body'>

View File

@ -7,7 +7,7 @@ function RedFail() {
viewBox='0 0 200 200' viewBox='0 0 200 200'
width='50' width='50'
xmlns='http://www.w3.org/2000/svg' xmlns='http://www.w3.org/2000/svg'
> >
<g> <g>
<title>Test failed</title> <title>Test failed</title>
<circle <circle

View File

@ -12,7 +12,7 @@ function GreenNotCompleted(props) {
width='50' width='50'
xmlns='http://www.w3.org/2000/svg' xmlns='http://www.w3.org/2000/svg'
{...props} {...props}
> >
<g> <g>
<title>Not Passed</title> <title>Not Passed</title>
<circle <circle

View File

@ -10,7 +10,7 @@ function GreenPass(props) {
width='50' width='50'
xmlns='http://www.w3.org/2000/svg' xmlns='http://www.w3.org/2000/svg'
{...props} {...props}
> >
<g> <g>
<title>Passed</title> <title>Passed</title>
<circle <circle

View File

@ -8,7 +8,7 @@ function Initial(props) {
width='50' width='50'
xmlns='http://www.w3.org/2000/svg' xmlns='http://www.w3.org/2000/svg'
{...props} {...props}
> >
<g> <g>
<title>Initial</title> <title>Initial</title>
<circle <circle
@ -26,7 +26,7 @@ function Initial(props) {
viewBox='-13 -12 50 50' viewBox='-13 -12 50 50'
width='200' width='200'
xmlns='http://www.w3.org/2000/svg' xmlns='http://www.w3.org/2000/svg'
> >
<path <path
d={ d={
'M8 1c0-.552.448-1 1-1h6c.553 0 1 .448 1 1s-.447 1-1 1h-6c-' + 'M8 1c0-.552.448-1 1-1h6c.553 0 1 .448 1 1s-.447 1-1 1h-6c-' +

View File

@ -35,7 +35,7 @@ export class ToolPanel extends Component {
className='btn-invert' className='btn-invert'
href={guideUrl} href={guideUrl}
target='_blank' target='_blank'
> >
Get a hint Get a hint
</Button> </Button>
)} )}
@ -44,7 +44,7 @@ export class ToolPanel extends Component {
bsStyle='primary' bsStyle='primary'
className='btn-invert' className='btn-invert'
onClick={openHelpModal} onClick={openHelpModal}
> >
Ask for help Ask for help
</Button> </Button>
</div> </div>
@ -59,4 +59,3 @@ export default connect(
mapStateToProps, mapStateToProps,
mapDispatchToProps mapDispatchToProps
)(ToolPanel); )(ToolPanel);

View File

@ -105,18 +105,20 @@ function loadCodeEpic(action$, state$) {
const codeFound = getCode(id); const codeFound = getCode(id);
if (codeFound && isFilesAllPoly(codeFound)) { if (codeFound && isFilesAllPoly(codeFound)) {
finalFiles = { finalFiles = {
...fileKeys.map(key => files[key]).reduce( ...fileKeys
(files, file) => ({ .map(key => files[key])
...files, .reduce(
[file.key]: { (files, file) => ({
...file, ...files,
contents: codeFound[file.key] [file.key]: {
? codeFound[file.key].contents ...file,
: file.contents contents: codeFound[file.key]
} ? codeFound[file.key].contents
}), : file.contents
{} }
) }),
{}
)
}; };
} else { } else {
const legacyCode = getLegacyCode(legacyKey); const legacyCode = getLegacyCode(legacyKey);

View File

@ -92,7 +92,7 @@ function getJSTestRunner({ build, sources }, proxyLogger) {
const testWorker = createWorker('test-evaluator'); const testWorker = createWorker('test-evaluator');
return async(testString, testTimeout) => { return async (testString, testTimeout) => {
try { try {
testWorker.on('LOG', proxyLogger); testWorker.on('LOG', proxyLogger);
return await testWorker.execute( return await testWorker.execute(

View File

@ -98,7 +98,7 @@ const initTestFrame = frameReady => ctx => {
resolve(); resolve();
} }
}); });
contentLoaded.then(async() => { contentLoaded.then(async () => {
const { sources, loadEnzyme } = ctx; const { sources, loadEnzyme } = ctx;
// default for classic challenges // default for classic challenges
// should not be used for modern // should not be used for modern

View File

@ -23,11 +23,13 @@ const propTypes = {
}; };
function renderMenuItems({ edges = [] }) { function renderMenuItems({ edges = [] }) {
return edges.map(({ node }) => node).map(({ title, fields: { slug } }) => ( return edges
<Link key={'intro-' + slug} to={slug}> .map(({ node }) => node)
<ListGroupItem>{title}</ListGroupItem> .map(({ title, fields: { slug } }) => (
</Link> <Link key={'intro-' + slug} to={slug}>
)); <ListGroupItem>{title}</ListGroupItem>
</Link>
));
} }
function IntroductionPage({ data: { markdownRemark, allChallengeNode } }) { function IntroductionPage({ data: { markdownRemark, allChallengeNode } }) {
@ -55,7 +57,7 @@ function IntroductionPage({ data: { markdownRemark, allChallengeNode } }) {
<Link <Link
className='btn btn-lg btn-primary btn-block' className='btn btn-lg btn-primary btn-block'
to={firstLessonPath} to={firstLessonPath}
> >
Go to the first lesson Go to the first lesson
</Link> </Link>
<ButtonSpacer /> <ButtonSpacer />

View File

@ -43,7 +43,7 @@ async function translateChallenge(file) {
translateText(instructions), translateText(instructions),
...tests.map( ...tests.map(
test => test =>
new Promise(async(resolve, reject) => { new Promise(async (resolve, reject) => {
const { testString, text } = test; const { testString, text } = test;
const translatedText = await translateText(text).catch(reject); const translatedText = await translateText(text).catch(reject);
return resolve({ return resolve({
@ -58,11 +58,11 @@ async function translateChallenge(file) {
const { files = {}, solutions = [], ...challengeMeta } = challenge; const { files = {}, solutions = [], ...challengeMeta } = challenge;
const md = `--- const md = `---
${YAML.dump( ${YAML.dump(
Object.assign(challengeMeta, { Object.assign(challengeMeta, {
localeTitle: title ? title.join(' ').trim() : '' localeTitle: title ? title.join(' ').trim() : ''
}), }),
{ lineWidth: 10000 } { lineWidth: 10000 }
)}--- )}---
## Description ## Description
${description} ${description}
@ -88,20 +88,20 @@ ${generateChallengeSeed(files)}
<section id='solution'> <section id='solution'>
${ ${
solutions.length === 0 solutions.length === 0
? `\`\`\`js ? `\`\`\`js
// solution required // solution required
\`\`\`` \`\`\``
: solutions : solutions
.map( .map(
solution => ` solution => `
\`\`\`js \`\`\`js
${solution} ${solution}
\`\`\` \`\`\`
` `
) )
.join('\n') .join('\n')
} }
</section> </section>
`; `;
@ -126,8 +126,8 @@ ${contents}
</div> </div>
${ ${
head.length head.length
? ` ? `
### Before Test ### Before Test
<div id='${ext}-setup'> <div id='${ext}-setup'>
@ -136,11 +136,11 @@ ${head}
\`\`\` \`\`\`
</div>` </div>`
: '' : ''
} }
${ ${
tail.length tail.length
? ` ? `
### After Test ### After Test
<div id='${ext}-teardown'> <div id='${ext}-teardown'>
@ -149,8 +149,8 @@ console.info('after the test');
\`\`\` \`\`\`
</div>` </div>`
: '' : ''
} }
`; `;
}); });
} }

View File

@ -289,7 +289,7 @@ async function createTestRunnerForDOMChallenge(
await context.reload(); await context.reload();
await context.setContent(build); await context.setContent(build);
await context.evaluate( await context.evaluate(
async(sources, loadEnzyme) => { async (sources, loadEnzyme) => {
const code = sources && 'index' in sources ? sources['index'] : ''; const code = sources && 'index' in sources ? sources['index'] : '';
const getUserInput = fileName => sources[fileName]; const getUserInput = fileName => sources[fileName];
await document.__initTestFrame({ code, getUserInput, loadEnzyme }); await document.__initTestFrame({ code, getUserInput, loadEnzyme });
@ -298,7 +298,7 @@ async function createTestRunnerForDOMChallenge(
loadEnzyme loadEnzyme
); );
return async({ text, testString }) => { return async ({ text, testString }) => {
try { try {
const { pass, err } = await Promise.race([ const { pass, err } = await Promise.race([
new Promise((_, reject) => setTimeout(() => reject('timeout'), 5000)), new Promise((_, reject) => setTimeout(() => reject('timeout'), 5000)),
@ -327,7 +327,7 @@ async function createTestRunnerForJSChallenge({ files }, solution) {
const code = sources && 'index' in sources ? sources['index'] : ''; const code = sources && 'index' in sources ? sources['index'] : '';
const testWorker = createWorker('test-evaluator'); const testWorker = createWorker('test-evaluator');
return async({ text, testString }) => { return async ({ text, testString }) => {
try { try {
const { pass, err } = await testWorker.execute( const { pass, err } = await testWorker.execute(
{ testString, build, code, sources }, { testString, build, code, sources },

View File

@ -45,7 +45,7 @@ function textToData(sectionIds) {
const lines = child.value.split('\n'); const lines = child.value.split('\n');
if (lines.filter(Boolean).length > 0) { if (lines.filter(Boolean).length > 0) {
lines.forEach((line, index) => { lines.forEach((line, index) => {
if ((/^\s*$/).test(line)) { if (/^\s*$/.test(line)) {
currentParagraph = null; currentParagraph = null;
} else { } else {
if (!currentParagraph || index > 0) { if (!currentParagraph || index > 0) {

View File

@ -70,7 +70,7 @@ const challengeFrontmatterValidator = file => frontmatter => {
function isChallengeParseable(file) { function isChallengeParseable(file) {
const { stat, fullPath } = file; const { stat, fullPath } = file;
if (!stat.isFile() || (/_meta/).test(fullPath)) { if (!stat.isFile() || /_meta/.test(fullPath)) {
return Promise.resolve(true); return Promise.resolve(true);
} }
return parseMarkdown(fullPath); return parseMarkdown(fullPath);