fix(description): Adjust for new description format

This commit is contained in:
Bouncey
2018-10-05 10:17:34 +01:00
committed by Stuart Taylor
parent badc68089f
commit b38ee544a3
9 changed files with 50 additions and 78 deletions

View File

@ -26,13 +26,6 @@ export default function settingsController(app) {
createValidatorErrorHandler(alertTypes.danger), createValidatorErrorHandler(alertTypes.danger),
updateMyCurrentChallenge updateMyCurrentChallenge
); );
api.post(
'/update-my-current-challenge',
ifNoUser401,
updateMyCurrentChallengeValidators,
createValidatorErrorHandler(alertTypes.danger),
updateMyCurrentChallenge
);
api.post('/update-my-portfolio', ifNoUser401, updateMyPortfolio); api.post('/update-my-portfolio', ifNoUser401, updateMyPortfolio);
api.post('/update-my-projects', ifNoUser401, updateMyProjects); api.post('/update-my-projects', ifNoUser401, updateMyProjects);
api.post( api.post(

View File

@ -1,10 +1,11 @@
import helmet from 'helmet'; import helmet from 'helmet';
import { homeLocation } from '../../../config/env';
let trusted = [ let trusted = [
"'self'", "'self'",
'https://search.freecodecamp.org', 'https://search.freecodecamp.org',
'https://www.freecodecamp.rocks', homeLocation,
'https://api.freecodecamp.rocks',
'https://' + process.env.AUTH0_DOMAIN 'https://' + process.env.AUTH0_DOMAIN
]; ];
@ -12,9 +13,7 @@ const host = process.env.HOST || 'localhost';
const port = process.env.SYNC_PORT || '3000'; const port = process.env.SYNC_PORT || '3000';
if (process.env.NODE_ENV !== 'production') { if (process.env.NODE_ENV !== 'production') {
trusted = trusted.concat([ trusted = trusted.concat([`ws://${host}:${port}`, 'http://localhost:8000']);
`ws://${host}:${port}`
]);
} }
export default function csp() { export default function csp() {
@ -73,11 +72,9 @@ export default function csp() {
'*', '*',
'data:' 'data:'
], ],
mediaSrc: [ mediaSrc: ['*.bitly.com', '*.amazonaws.com', '*.twitter.com'].concat(
'*.bitly.com', trusted
'*.amazonaws.com', ),
'*.twitter.com'
].concat(trusted),
frameSrc: [ frameSrc: [
'*.gitter.im', '*.gitter.im',
'*.gitter.im https:', '*.gitter.im https:',

View File

@ -22,7 +22,7 @@ export const ChallengeNode = PropTypes.shape({
block: PropTypes.string, block: PropTypes.string,
challengeType: PropTypes.number, challengeType: PropTypes.number,
dashedName: PropTypes.string, dashedName: PropTypes.string,
description: PropTypes.arrayOf(PropTypes.string), description: PropTypes.string,
files: PropTypes.shape({ files: PropTypes.shape({
indexhtml: FileType, indexhtml: FileType,
indexjs: FileType indexjs: FileType
@ -34,6 +34,7 @@ export const ChallengeNode = PropTypes.shape({
guideUrl: PropTypes.string, guideUrl: PropTypes.string,
head: PropTypes.arrayOf(PropTypes.string), head: PropTypes.arrayOf(PropTypes.string),
challengeOrder: PropTypes.number, challengeOrder: PropTypes.number,
instructions: PropTypes.string,
isBeta: PropTypes.bool, isBeta: PropTypes.bool,
isComingSoon: PropTypes.bool, isComingSoon: PropTypes.bool,
isLocked: PropTypes.bool, isLocked: PropTypes.bool,

View File

@ -41,7 +41,7 @@ const reduxFormPropTypes = {
}; };
const propTypes = { const propTypes = {
description: PropTypes.arrayOf(PropTypes.string), description: PropTypes.string,
executeChallenge: PropTypes.func.isRequired, executeChallenge: PropTypes.func.isRequired,
id: PropTypes.string, id: PropTypes.string,
output: PropTypes.string, output: PropTypes.string,
@ -126,7 +126,8 @@ export class BackEnd extends Component {
challengeNode: { challengeNode: {
fields: { blockName, slug }, fields: { blockName, slug },
title, title,
description description,
instructions
} }
}, },
output, output,
@ -145,7 +146,10 @@ export class BackEnd extends Component {
<Spacer /> <Spacer />
<div> <div>
<ChallengeTitle>{blockNameTitle}</ChallengeTitle> <ChallengeTitle>{blockNameTitle}</ChallengeTitle>
<ChallengeDescription description={description} /> <ChallengeDescription
description={description}
instructions={instructions}
/>
</div> </div>
<div> <div>
<Form <Form
@ -200,6 +204,7 @@ export const query = graphql`
title title
guideUrl guideUrl
description description
instructions
challengeType challengeType
fields { fields {
blockName blockName

View File

@ -177,6 +177,7 @@ class ShowClassic extends Component {
fields: { blockName, slug }, fields: { blockName, slug },
title, title,
description, description,
instructions,
videoUrl videoUrl
} }
}, },
@ -227,6 +228,7 @@ class ShowClassic extends Component {
className='full-height' className='full-height'
description={description} description={description}
guideUrl={createGuideUrl(slug)} guideUrl={createGuideUrl(slug)}
instructions={instructions}
section={dasherize(blockName)} section={dasherize(blockName)}
title={blockNameTitle} title={blockNameTitle}
videoUrl={videoUrl} videoUrl={videoUrl}
@ -271,6 +273,7 @@ export const query = graphql`
challengeNode(fields: { slug: { eq: $slug } }) { challengeNode(fields: { slug: { eq: $slug } }) {
title title
description description
instructions
challengeType challengeType
videoUrl videoUrl
fields { fields {

View File

@ -1,44 +1,29 @@
import React from 'react'; import React, { Fragment } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { Col, Row } from '@freecodecamp/react-bootstrap'; import { Col, Row } from '@freecodecamp/react-bootstrap';
import { descriptionRegex } from '../../../../utils';
import './challenge-description.css'; import './challenge-description.css';
const propTypes = { const propTypes = {
description: PropTypes.arrayOf(PropTypes.string), description: PropTypes.string,
instructions: PropTypes.string,
section: PropTypes.string section: PropTypes.string
}; };
function renderDescription(description) { function ChallengeDescription({ description, instructions, section }) {
if (!Array.isArray(description)) {
return null;
}
return description.map((line, index) => {
if (descriptionRegex.test(line)) {
return (
<div
dangerouslySetInnerHTML={{ __html: line }}
key={line.slice(-6) + index}
/>
);
}
return (
<p
className='wrappable'
dangerouslySetInnerHTML={{ __html: line }}
key={line.slice(-6) + index}
/>
);
});
}
function ChallengeDescription({ description, section }) {
// TODO: Remove bootstrap
return ( return (
<Row> <Row>
<Col className={`challenge-instructions ${section}`} xs={12}> <Col className={`challenge-instructions ${section}`} xs={12}>
{renderDescription(description)} <div dangerouslySetInnerHTML={{ __html: description }} />
{instructions ? (
<Fragment>
<hr />
<div dangerouslySetInnerHTML={{ __html: instructions }} />
<hr />
</Fragment>
) : (
<hr />
)}
</Col> </Col>
</Row> </Row>
); );

View File

@ -1,4 +1,4 @@
import React, { PureComponent } from 'react'; import React, { Component } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import ReactDom from 'react-dom'; import ReactDom from 'react-dom';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
@ -29,16 +29,17 @@ const mapDispatchToProps = dispatch =>
const MathJax = global.MathJax; const MathJax = global.MathJax;
const propTypes = { const propTypes = {
description: PropTypes.arrayOf(PropTypes.string), description: PropTypes.string,
guideUrl: PropTypes.string, guideUrl: PropTypes.string,
initConsole: PropTypes.func.isRequired, initConsole: PropTypes.func.isRequired,
instructions: PropTypes.string,
section: PropTypes.string, section: PropTypes.string,
tests: PropTypes.arrayOf(PropTypes.object), tests: PropTypes.arrayOf(PropTypes.object),
title: PropTypes.string, title: PropTypes.string,
videoUrl: PropTypes.string videoUrl: PropTypes.string
}; };
export class SidePanel extends PureComponent { export class SidePanel extends Component {
constructor(props) { constructor(props) {
super(props); super(props);
this.bindTopDiv = this.bindTopDiv.bind(this); this.bindTopDiv = this.bindTopDiv.bind(this);
@ -84,6 +85,7 @@ export class SidePanel extends PureComponent {
const { const {
title, title,
description, description,
instructions,
guideUrl, guideUrl,
tests, tests,
section, section,
@ -95,7 +97,7 @@ export class SidePanel extends PureComponent {
<Spacer /> <Spacer />
<div> <div>
<ChallengeTitle>{title}</ChallengeTitle> <ChallengeTitle>{title}</ChallengeTitle>
<ChallengeDescription description={description} section={section} /> <ChallengeDescription description={description} instructions={instructions} section={section} />
</div> </div>
<ToolPanel guideUrl={guideUrl} videoUrl={videoUrl} /> <ToolPanel guideUrl={guideUrl} videoUrl={videoUrl} />
<TestSuite tests={tests} /> <TestSuite tests={tests} />

View File

@ -1,36 +1,23 @@
import React, { PureComponent } from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import ChallengeTitle from '../components/Challenge-Title'; import ChallengeTitle from '../components/Challenge-Title';
import Spacer from '../../../components/helpers/Spacer'; import Spacer from '../../../components/helpers/Spacer';
const propTypes = { const propTypes = {
description: PropTypes.arrayOf(PropTypes.string), description: PropTypes.string,
isCompleted: PropTypes.bool, isCompleted: PropTypes.bool,
isSignedIn: PropTypes.bool, isSignedIn: PropTypes.bool,
title: PropTypes.string title: PropTypes.string
}; };
export default class SidePanel extends PureComponent { export default function SidePanel({ title, description, isCompleted }) {
renderDescription(title = '', description = []) { return (
return description.map((line, index) => ( <div>
<li <Spacer />
className='step-text wrappable' <ChallengeTitle isCompleted={isCompleted}>{title}</ChallengeTitle>
dangerouslySetInnerHTML={{ __html: line }} <div dangerouslySetInnerHTML={{ __html: description }} />
key={title.slice(6) + index} </div>
/> );
));
}
render() {
const { title, description, isCompleted } = this.props;
return (
<div>
<Spacer />
<ChallengeTitle isCompleted={isCompleted}>{title}</ChallengeTitle>
<ul>{this.renderDescription(title, description)}</ul>
</div>
);
}
} }
SidePanel.displayName = 'ProjectSidePanel'; SidePanel.displayName = 'ProjectSidePanel';

View File

@ -39,7 +39,6 @@ class GuideArticle extends Component {
}, },
pageContext: { meta } pageContext: { meta }
} = this.props; } = this.props;
console.log(title);
return ( return (
<Layout> <Layout>
<Helmet> <Helmet>