Break up map components

Add static super blocks
pull/7430/head
Berkeley Martinez 2016-03-22 22:13:05 -07:00
parent c909cd032e
commit 9353c4df9f
6 changed files with 259 additions and 71 deletions

View File

@ -0,0 +1,82 @@
import React, { PropTypes } from 'react';
import FA from 'react-fontawesome';
import PureComponent from 'react-pure-render/component';
import { Panel } from 'react-bootstrap';
import classnames from 'classnames';
export default class Block extends PureComponent {
static displayName = 'Block';
static propTypes = {
title: PropTypes.string,
time: PropTypes.string,
challenges: PropTypes.array
};
renderChallenges(challenges) {
if (!Array.isArray(challenges) || !challenges.length) {
return <div>No Challenges Found</div>;
}
return challenges.map(challenge => {
const { title, dashedName, isLocked, isRequired } = challenge;
const challengeClassName = classnames({
'text-primary': true,
'padded-ionic-icon': true,
'negative-15': true,
'challenge-title': true,
'ion-checkmark-circled': !isLocked,
'ion-locked': isLocked,
'disabled': isLocked
});
if (isLocked) {
return (
<p
className={ challengeClassName }
key={ title }>
{ title }
{
isRequired ?
<span className='text-primary'><strong>*</strong></span> :
''
}
</p>
);
}
return (
<p
className={ challengeClassName }
key={ title }>
<a href={ `/challenges/${dashedName}` }>
{ title }
<span className='sr-only'>complete</span>
{
isRequired ?
<span className='text-primary'><strong>*</strong></span> :
''
}
</a>
</p>
);
});
}
render() {
const { title, time, challenges } = this.props;
return (
<Panel
bsClass='map-accordion-panel-nested'
collapsible={ true }
expanded={ true }
header={
<div>
<h3><FA name='caret-right' />{ title }</h3>
<span className='challenge-block-time'>({ time })</span>
</div>
}
id={ title }
key={ title }>
{ this.renderChallenges(challenges) }
</Panel>
);
}
}

View File

@ -0,0 +1,61 @@
import React from 'react';
import PureComponent from 'react-pure-render/component';
import dedent from 'dedent';
import SuperBlock from './Super-Block.jsx';
const lockMessage = dedent`
To qualify for these nonprofit projects,
you must first earn all three foundational certifications:
Front End, Data Visualization, and Back End
`.replace(/[\n]/g, ' ');
const codingPrep = [{
title: 'Coding Interview Training',
time: '70 Hours',
challenges: [
{
title: 'Soft Skill Training',
isLocked: true
},
{
title: 'Critical Thinking Training',
isLocked: true
},
{
title: 'Whiteboard Coding Training',
isLocked: true
}
]
}, {
title: 'Mock Interviews',
time: '10 Hours',
challenges: [
{
title: 'Mock Interview #1',
isLocked: true
},
{
title: 'Mock Interview #2',
isLocked: true
},
{
title: 'Mock Interview #3',
isLocked: true
}
]
}];
export default class CodingPrep extends PureComponent {
static displayName = 'CodingPrep;'
render() {
return (
<div>
<SuperBlock
blocks={ codingPrep }
message={ lockMessage }
title='Coding Interview Prep ' />
</div>
);
}
}

View File

@ -0,0 +1,54 @@
import React from 'react';
import PureComponent from 'react-pure-render/component';
import dedent from 'dedent';
import SuperBlock from './Super-Block.jsx';
const lockMessage = dedent`
To qualify for these nonprofit projects,
you must first earn all three foundational certifications:
Front End, Data Visualization, and Back End
`.replace(/[\n]/g, ' ');
const nonprofitProjects = {
title: 'Nonprofit Projects',
time: '800 Hours',
challenges: [
{
title: 'Greenfield Nonprofit Project #1',
isLocked: true,
isRequired: true
},
{
title: 'Greenfield Nonprofit Project #2',
isLocked: true,
isRequired: true
},
{
title: 'Legacy Code Nonprofit Project #1',
isLocked: true,
isRequired: true
},
{
title: 'Legacy Code Nonprofit Project #2',
isLocked: true,
isRequired: true
},
{
title: 'Claim your Full Stack Development Certification',
isLocked: true
}
]
};
export default class FullStack extends PureComponent {
static displayName = 'FullStack';
render() {
const title = 'Full Stack Development Certification';
return (
<SuperBlock
blocks={ [ nonprofitProjects ] }
message={ lockMessage }
title={ title } />
);
}
}

View File

@ -1,20 +1,10 @@
import React, { PropTypes } from 'react';
import FA from 'react-fontawesome';
import PureComponent from 'react-pure-render/component';
import {
Input,
Button,
Row,
Panel
} from 'react-bootstrap';
import { Input, Button, Row } from 'react-bootstrap';
const challengeClassName = `
text-primary
padded-ionic-icon
negative-15
challenge-title
ion-checkmark-circled
`.replace(/[\n]/g, '');
import SuperBlock from './Super-Block.jsx';
import FullStack from './Full-Stack.jsx';
import CodingPrep from './Coding-Prep.jsx';
export default class ShowMap extends PureComponent {
static displayName = 'Map';
@ -22,69 +12,15 @@ export default class ShowMap extends PureComponent {
superBlocks: PropTypes.array
};
renderChallenges(challenges) {
if (!Array.isArray(challenges) || !challenges.length) {
return <div>No Challenges Found</div>;
}
return challenges.map(challenge => {
const { title, dashedName } = challenge;
return (
<p
className={ challengeClassName }
key={ title }>
<a href={ `/challenges/${dashedName}` }>
{ title }
<span className='sr-only'>complete</span>
</a>
</p>
);
});
}
renderBlocks(blocks) {
if (!Array.isArray(blocks) || !blocks.length) {
return <div>No Blocks Found</div>;
}
return blocks.map(block => {
const { title, time, challenges } = block;
return (
<Panel
bsClass='map-accordion-panel-nested'
collapsible={ true }
expanded={ true }
header={
<div>
<h3><FA name='caret-right' />{ title }</h3>
<span className='challenge-block-time'>({ time })</span>
</div>
}
id={ title }
key={ title }>
{ this.renderChallenges(challenges) }
</Panel>
);
});
}
renderSuperBlocks(superBlocks) {
if (!Array.isArray(superBlocks) || !superBlocks.length) {
return <div>No Super Blocks</div>;
}
return superBlocks.map((superBlock) => {
const { title, blocks } = superBlock;
return (
<Panel
bsClass='map-accordion-panel'
collapsible={ true }
expanded={ true }
header={ <h2><FA name='caret-right' />{ title }</h2> }
id={ title }
key={ title }>
<div
className='map-accordion-block'>
{ this.renderBlocks(blocks) }
</div>
</Panel>
<SuperBlock
key={ superBlock.title }
{ ...superBlock }/>
);
});
}
@ -120,6 +56,8 @@ export default class ShowMap extends PureComponent {
<div
className='map-accordion'>
{ this.renderSuperBlocks(superBlocks) }
<FullStack />
<CodingPrep />
</div>
</div>
);

View File

@ -0,0 +1,53 @@
import React, { PropTypes } from 'react';
import PureComponent from 'react-pure-render/component';
import FA from 'react-fontawesome';
import { Panel } from 'react-bootstrap';
import Block from './Block.jsx';
export default class SuperBlock extends PureComponent {
static displayName = 'SuperBlock';
static propTypes = {
title: PropTypes.string,
message: PropTypes.string,
blocks: PropTypes.array
};
renderBlocks(blocks) {
if (!Array.isArray(blocks) || !blocks.length) {
return <div>No Blocks Found</div>;
}
return blocks.map(block => {
return (
<Block
key={ block.title }
{ ...block } />
);
});
}
render() {
const { title, blocks, message } = this.props;
return (
<Panel
bsClass='map-accordion-panel'
collapsible={ true }
expanded={ true }
header={ <h2><FA name='caret-right' />{ title }</h2> }
id={ title }
key={ title }>
{
message ?
<div className='challenge-block-description'>
{ message }
</div> :
''
}
<div
className='map-accordion-block'>
{ this.renderBlocks(blocks) }
</div>
</Panel>
);
}
}