Feature(react): Move settings to React
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import { modernChallenges, map, challenges } from './challenges';
|
||||
import NotFound from '../components/NotFound/index.jsx';
|
||||
import { addLang } from '../utils/lang';
|
||||
import settings from './settings';
|
||||
|
||||
export default {
|
||||
path: '/:lang',
|
||||
@@ -15,6 +16,7 @@ export default {
|
||||
challenges,
|
||||
modernChallenges,
|
||||
map,
|
||||
settings,
|
||||
{
|
||||
path: '*',
|
||||
component: NotFound
|
||||
|
61
common/app/routes/settings/components/Delete-Modal.jsx
Normal file
61
common/app/routes/settings/components/Delete-Modal.jsx
Normal file
@@ -0,0 +1,61 @@
|
||||
import React, { PropTypes } from 'react';
|
||||
import { Modal, Button } from 'react-bootstrap';
|
||||
|
||||
export default function DeleteModal({ isOpen }) {
|
||||
return (
|
||||
<div>
|
||||
<Button
|
||||
block={ true }
|
||||
bsSize='lg'
|
||||
bsStyle='danger'
|
||||
className='btn-link-social'
|
||||
>
|
||||
Delete my Free Code Camp account
|
||||
</Button>
|
||||
<Modal
|
||||
backdrop={ true }
|
||||
show={ isOpen }
|
||||
>
|
||||
<Modal.Header>
|
||||
<h3>You don't really want to delete your account, do you?</h3>
|
||||
</Modal.Header>
|
||||
<Modal.Body>
|
||||
<p>
|
||||
This will really delete all your data, including
|
||||
all your progress and brownie points.
|
||||
</p>
|
||||
<p>
|
||||
We won't be able to recover any of it for you later,
|
||||
even if you change your mind.
|
||||
</p>
|
||||
<p>
|
||||
If there's something we could do better, send
|
||||
us an email instead and we'll do our best:  
|
||||
<a href='mailto:team@freecodecamp.com'>
|
||||
team@freecodecamp.com
|
||||
</a>.
|
||||
</p>
|
||||
</Modal.Body>
|
||||
<Modal.Footer>
|
||||
<Button
|
||||
block={ true }
|
||||
bsStyle='success'
|
||||
>
|
||||
Nevermind, I don't want to delete all of my progress
|
||||
</Button>
|
||||
<div className='spacer' />
|
||||
<Button
|
||||
block={ true }
|
||||
bsStyle='danger'
|
||||
>
|
||||
I am 100% sure I want to delete my account and all of my progress
|
||||
</Button>
|
||||
</Modal.Footer>
|
||||
</Modal>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
DeleteModal.propTypes = {
|
||||
isOpen: PropTypes.bool
|
||||
};
|
122
common/app/routes/settings/components/Email-Setting.jsx
Normal file
122
common/app/routes/settings/components/Email-Setting.jsx
Normal file
@@ -0,0 +1,122 @@
|
||||
import React, { PropTypes } from 'react';
|
||||
import { Button, Row, Col } from 'react-bootstrap';
|
||||
import FA from 'react-fontawesome';
|
||||
import classnames from 'classnames';
|
||||
|
||||
export function UpdateEmailButton() {
|
||||
return (
|
||||
<Button
|
||||
block={ true }
|
||||
bsSize='lg'
|
||||
bsStyle='primary'
|
||||
className='btn-link-social'
|
||||
>
|
||||
<FA name='envelope' />
|
||||
Update my Email
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
|
||||
export default function EmailSettings({
|
||||
email,
|
||||
sendMonthlyEmail,
|
||||
sendNotificationEmail,
|
||||
sendQuincyEmail
|
||||
}) {
|
||||
if (!email) {
|
||||
return (
|
||||
<div>
|
||||
<Row>
|
||||
<p className='large-p text-center'>
|
||||
You don't have an email id associated to this account.
|
||||
</p>
|
||||
</Row>
|
||||
<Row>
|
||||
<UpdateEmailButton />
|
||||
</Row>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<div>
|
||||
<Row>
|
||||
<p className='large-p text-center'>
|
||||
<em>{ email }</em>
|
||||
</p>
|
||||
</Row>
|
||||
<Row>
|
||||
<UpdateEmailButton />
|
||||
</Row>
|
||||
<Row>
|
||||
<Col xs={ 9 }>
|
||||
<p className='large-p'>
|
||||
Send me announcement emails
|
||||
<br />
|
||||
(we'll send you these every Thursday)
|
||||
</p>
|
||||
</Col>
|
||||
<Col xs={ 3 }>
|
||||
<Button
|
||||
block={ true }
|
||||
bsSize='lg'
|
||||
bsStyle='primary'
|
||||
className={
|
||||
classnames('positive-20', { active: sendMonthlyEmail })
|
||||
}
|
||||
>
|
||||
{ sendMonthlyEmail ? 'On' : 'Off' }
|
||||
</Button>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row>
|
||||
<Col xs={ 9 }>
|
||||
<p className='large-p'>
|
||||
Send me notification emails
|
||||
<br />
|
||||
(these will pertain to your account)
|
||||
</p>
|
||||
</Col>
|
||||
<Col xs={ 3 }>
|
||||
<Button
|
||||
block={ true }
|
||||
bsSize='lg'
|
||||
bsStyle='primary'
|
||||
className={
|
||||
classnames('positive-20', { active: sendNotificationEmail })
|
||||
}
|
||||
>
|
||||
{ sendNotificationEmail ? 'On' : 'Off' }
|
||||
</Button>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row>
|
||||
<Col xs={ 9 }>
|
||||
<p className='large-p'>
|
||||
Send me Quincy's weekly email
|
||||
<br />
|
||||
(with new articles every Tuesday)
|
||||
</p>
|
||||
</Col>
|
||||
<Col xs={ 3 }>
|
||||
<Button
|
||||
block={ true }
|
||||
bsSize='lg'
|
||||
bsStyle='primary'
|
||||
className={
|
||||
classnames('positive-20', { active: sendQuincyEmail })
|
||||
}
|
||||
>
|
||||
{ sendQuincyEmail ? 'On' : 'Off' }
|
||||
</Button>
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
EmailSettings.propTypes = {
|
||||
email: PropTypes.string,
|
||||
sendMonthlyEmail: PropTypes.bool,
|
||||
sendNotificationEmail: PropTypes.bool,
|
||||
sendQuincyEmail: PropTypes.bool
|
||||
};
|
49
common/app/routes/settings/components/Language-Settings.jsx
Normal file
49
common/app/routes/settings/components/Language-Settings.jsx
Normal file
@@ -0,0 +1,49 @@
|
||||
import React, { PropTypes } from 'react';
|
||||
import { FormControl } from 'react-bootstrap';
|
||||
import langs from '../../../../utils/supported-languages';
|
||||
|
||||
const langOptions = [
|
||||
...Object.keys(langs).map(tag => {
|
||||
return (
|
||||
<option
|
||||
key={ tag }
|
||||
value={ tag }
|
||||
>
|
||||
{ langs[tag] }
|
||||
</option>
|
||||
);
|
||||
}), (
|
||||
<option
|
||||
disabled={ true }
|
||||
key='more'
|
||||
>
|
||||
More to come...
|
||||
</option>
|
||||
)
|
||||
];
|
||||
|
||||
export default function LangaugeSettings({ userLang }) {
|
||||
const options = [(
|
||||
<option
|
||||
disabled={ true }
|
||||
key='default'
|
||||
selected={ userLang ? false : true }
|
||||
>
|
||||
Prefered Langauge
|
||||
</option>
|
||||
),
|
||||
...langOptions
|
||||
];
|
||||
return (
|
||||
<FormControl
|
||||
className='btn btn-block btn-primary btn-link-social'
|
||||
componentClass='select'
|
||||
>
|
||||
{ options }
|
||||
</FormControl>
|
||||
);
|
||||
}
|
||||
|
||||
LangaugeSettings.propTypes = {
|
||||
userLang: PropTypes.string
|
||||
};
|
35
common/app/routes/settings/components/Locked-Settings.jsx
Normal file
35
common/app/routes/settings/components/Locked-Settings.jsx
Normal file
@@ -0,0 +1,35 @@
|
||||
import React, { PropTypes } from 'react';
|
||||
import { Button, Row, Col } from 'react-bootstrap';
|
||||
import classnames from 'classnames';
|
||||
|
||||
export default function LockSettings({ isLocked }) {
|
||||
const className = classnames({
|
||||
'positive-20': true,
|
||||
active: isLocked
|
||||
});
|
||||
return (
|
||||
<Row>
|
||||
<Col xs={ 9 }>
|
||||
<p className='large-p'>
|
||||
Make all of my solutions private
|
||||
<br />
|
||||
(this disables your certificates)
|
||||
</p>
|
||||
</Col>
|
||||
<Col xs={ 3 }>
|
||||
<Button
|
||||
block={ true }
|
||||
bsSize='lg'
|
||||
bsStyle='primary'
|
||||
className={ className }
|
||||
>
|
||||
{ isLocked ? 'On' : 'Off' }
|
||||
</Button>
|
||||
</Col>
|
||||
</Row>
|
||||
);
|
||||
}
|
||||
|
||||
LockSettings.propTypes = {
|
||||
isLocked: PropTypes.bool
|
||||
};
|
135
common/app/routes/settings/components/Settings.jsx
Normal file
135
common/app/routes/settings/components/Settings.jsx
Normal file
@@ -0,0 +1,135 @@
|
||||
import React, { PropTypes } from 'react';
|
||||
import { Button, Row, Col } from 'react-bootstrap';
|
||||
|
||||
import LockedSettings from './Locked-Settings.jsx';
|
||||
import SocialSettings from './Social-Settings.jsx';
|
||||
import EmailSettings from './Email-Setting.jsx';
|
||||
import LangaugeSettings from './Language-Settings.jsx';
|
||||
import DeleteModal from './Delete-Modal.jsx';
|
||||
|
||||
export default class Settings extends React.Component {
|
||||
static displayName = 'Settings';
|
||||
static propTypes = {
|
||||
isLocked: PropTypes.bool,
|
||||
isGithubCool: PropTypes.bool,
|
||||
isTwitter: PropTypes.bool,
|
||||
isLinkedIn: PropTypes.bool,
|
||||
email: PropTypes.string,
|
||||
sendMonthlyEmail: PropTypes.bool,
|
||||
sendNotificationEmail: PropTypes.bool,
|
||||
sendQuincyEmail: PropTypes.bool
|
||||
};
|
||||
|
||||
render() {
|
||||
const {
|
||||
isLocked,
|
||||
isGithubCool,
|
||||
isTwitter,
|
||||
isLinkedIn,
|
||||
email,
|
||||
sendMonthlyEmail,
|
||||
sendNotificationEmail,
|
||||
sendQuincyEmail
|
||||
} = this.props;
|
||||
return (
|
||||
<div>
|
||||
<h1 className='text-center'>Settings for your Account</h1>
|
||||
<h2 className='text-center'>Actions</h2>
|
||||
<Row>
|
||||
<Col xs={ 12 }>
|
||||
<Button
|
||||
block={ true }
|
||||
bsSize='lg'
|
||||
bsStyle='primary'
|
||||
className='btn-link-social'
|
||||
>
|
||||
NightMode
|
||||
</Button>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row>
|
||||
<Col xs={ 12 }>
|
||||
<SocialSettings
|
||||
isGithubCool={ isGithubCool }
|
||||
isLinkedIn={ isLinkedIn }
|
||||
isTwitter={ isTwitter }
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
<div className='spacer' />
|
||||
<h2 className='text-center'>Account Settings</h2>
|
||||
<Row>
|
||||
<Col xs={ 12 }>
|
||||
<Button
|
||||
block={ true }
|
||||
bsSize='lg'
|
||||
bsStyle='primary'
|
||||
className='btn-link-social'
|
||||
href='/commit'
|
||||
>
|
||||
Edit my pledge
|
||||
</Button>
|
||||
</Col>
|
||||
</Row>
|
||||
<div className='spacer' />
|
||||
<h2 className='text-center'>Privacy Settings</h2>
|
||||
<Row>
|
||||
<Col
|
||||
md={ 6 }
|
||||
mdOffset={ 3 }
|
||||
sm={ 8 }
|
||||
smOffset={ 2 }
|
||||
xs={ 12 }
|
||||
>
|
||||
<LockedSettings isLocked={ isLocked } />
|
||||
</Col>
|
||||
</Row>
|
||||
<div className='spacer' />
|
||||
<h2 className='text-center'>Email Settings</h2>
|
||||
<Row>
|
||||
<Col
|
||||
md={ 6 }
|
||||
mdOffset={ 3 }
|
||||
sm={ 8 }
|
||||
smOffset={ 2 }
|
||||
xs={ 12 }
|
||||
>
|
||||
<EmailSettings
|
||||
email={ email }
|
||||
sendMonthlyEmail={ sendMonthlyEmail }
|
||||
sendNotificationEmail={ sendNotificationEmail }
|
||||
sendQuincyEmail={ sendQuincyEmail }
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
<div className='spacer' />
|
||||
<h2 className='text-center'>Language Settigns</h2>
|
||||
<Row>
|
||||
<Col
|
||||
md={ 6 }
|
||||
mdOffset={ 3 }
|
||||
sm={ 8 }
|
||||
smOffset={ 2 }
|
||||
xs={ 12 }
|
||||
>
|
||||
<LangaugeSettings />
|
||||
</Col>
|
||||
</Row>
|
||||
<div className='spacer' />
|
||||
<h2 className='text-center'>Danger Zone</h2>
|
||||
<Row>
|
||||
<Col
|
||||
md={ 6 }
|
||||
mdOffset={ 3 }
|
||||
sm={ 8 }
|
||||
smOffset={ 2 }
|
||||
xs={ 12 }
|
||||
>
|
||||
<DeleteModal />
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
60
common/app/routes/settings/components/Social-Settings.jsx
Normal file
60
common/app/routes/settings/components/Social-Settings.jsx
Normal file
@@ -0,0 +1,60 @@
|
||||
import React, { PropTypes } from 'react';
|
||||
import { Button } from 'react-bootstrap';
|
||||
import FA from 'react-fontawesome';
|
||||
|
||||
export default function SocialSettings({
|
||||
isGithubCool,
|
||||
isTwitter,
|
||||
isLinkedIn
|
||||
}) {
|
||||
const githubCopy = isGithubCool ?
|
||||
'Update my portfolio from GitHub' :
|
||||
'Link my GitHub to unlock my portfolio';
|
||||
const buttons = [
|
||||
<Button
|
||||
block={ true }
|
||||
bsSize='lg'
|
||||
className='btn-link-social btn-github'
|
||||
href='/link/github'
|
||||
key='github'
|
||||
>
|
||||
<FA name='github' />
|
||||
{ githubCopy }
|
||||
</Button>
|
||||
];
|
||||
if (isGithubCool && !isTwitter) {
|
||||
buttons.push((
|
||||
<Button
|
||||
block={ true }
|
||||
bsSize='lg'
|
||||
className='btn-link-social btn-twitter'
|
||||
href='/link/twitter'
|
||||
key='twitter'
|
||||
>
|
||||
<FA name='twitter' />
|
||||
Add my LinkedIn to my portfolio
|
||||
</Button>
|
||||
));
|
||||
}
|
||||
if (isGithubCool && !isLinkedIn) {
|
||||
buttons.push((
|
||||
<Button
|
||||
block={ true }
|
||||
bsSize='lg'
|
||||
className='btn-link-social btn-linkedin'
|
||||
href='/link/linkedin'
|
||||
key='linkedin'
|
||||
>
|
||||
<FA name='linked' />
|
||||
Add my LinkedIn to my portfolio
|
||||
</Button>
|
||||
));
|
||||
}
|
||||
return (<div>{ buttons }</div>);
|
||||
}
|
||||
|
||||
SocialSettings.propTypes = {
|
||||
isGithubCool: PropTypes.bool,
|
||||
isTwitter: PropTypes.bool,
|
||||
isLinkedIn: PropTypes.bool
|
||||
};
|
6
common/app/routes/settings/index.js
Normal file
6
common/app/routes/settings/index.js
Normal file
@@ -0,0 +1,6 @@
|
||||
import Settings from './components/Settings.jsx';
|
||||
|
||||
export default {
|
||||
path: 'settings',
|
||||
component: Settings
|
||||
};
|
Reference in New Issue
Block a user