feat(settings): Internet Settings

This commit is contained in:
Bouncey
2018-09-20 12:29:31 +01:00
committed by Stuart Taylor
parent 6208237d0b
commit 9f4430eced
3 changed files with 200 additions and 8 deletions

View File

@ -16,11 +16,14 @@ import FullWidthRow from '../components/helpers/FullWidthRow';
import About from '../components/settings/About'; import About from '../components/settings/About';
import Privacy from '../components/settings/Privacy'; import Privacy from '../components/settings/Privacy';
import Email from '../components/settings/Email'; import Email from '../components/settings/Email';
import Internet from '../components/settings/Internet';
const propTypes = { const propTypes = {
about: PropTypes.string, about: PropTypes.string,
email: PropTypes.string, email: PropTypes.string,
githubProfile: PropTypes.string,
isEmailVerified: PropTypes.bool, isEmailVerified: PropTypes.bool,
linkedin: PropTypes.string,
location: PropTypes.string, location: PropTypes.string,
name: PropTypes.string, name: PropTypes.string,
picture: PropTypes.string, picture: PropTypes.string,
@ -30,8 +33,11 @@ const propTypes = {
submitNewAbout: PropTypes.func.isRequired, submitNewAbout: PropTypes.func.isRequired,
theme: PropTypes.string, theme: PropTypes.string,
toggleNightMode: PropTypes.func.isRequired, toggleNightMode: PropTypes.func.isRequired,
twitter: PropTypes.string,
updateInternetSettings: PropTypes.func.isRequired,
updateQuincyEmail: PropTypes.func.isRequired, updateQuincyEmail: PropTypes.func.isRequired,
username: PropTypes.string username: PropTypes.string,
website: PropTypes.string
}; };
const mapStateToProps = createSelector( const mapStateToProps = createSelector(
@ -49,7 +55,11 @@ const mapStateToProps = createSelector(
points, points,
name, name,
location, location,
theme theme,
githubProfile,
linkedin,
twitter,
website
} }
) => ({ ) => ({
email, email,
@ -62,7 +72,11 @@ const mapStateToProps = createSelector(
points, points,
name, name,
theme, theme,
location location,
githubProfile,
linkedin,
twitter,
website
}) })
); );
@ -71,6 +85,7 @@ const mapDispatchToProps = dispatch =>
{ {
submitNewAbout, submitNewAbout,
toggleNightMode: theme => updateUserFlag({ theme }), toggleNightMode: theme => updateUserFlag({ theme }),
updateInternetSettings: updateUserFlag,
updateQuincyEmail: sendQuincyEmail => updateUserFlag({ sendQuincyEmail }) updateQuincyEmail: sendQuincyEmail => updateUserFlag({ sendQuincyEmail })
}, },
dispatch dispatch
@ -91,7 +106,12 @@ function ShowSettings(props) {
name, name,
submitNewAbout, submitNewAbout,
toggleNightMode, toggleNightMode,
updateQuincyEmail updateQuincyEmail,
githubProfile,
linkedin,
twitter,
website,
updateInternetSettings
} = props; } = props;
if (showLoading) { if (showLoading) {
@ -154,9 +174,15 @@ function ShowSettings(props) {
updateQuincyEmail={updateQuincyEmail} updateQuincyEmail={updateQuincyEmail}
/> />
<Spacer /> <Spacer />
{/* <InternetSettings /> <Internet
githubProfile={githubProfile}
linkedin={linkedin}
twitter={twitter}
updateInternetSettings={updateInternetSettings}
website={website}
/>
<Spacer /> <Spacer />
<PortfolioSettings /> {/* <PortfolioSettings />
<Spacer /> <Spacer />
<Honesty /> <Honesty />
<Spacer /> <Spacer />

View File

@ -0,0 +1,164 @@
import React, { Fragment, Component } from 'react';
import PropTypes from 'prop-types';
import {
FormControl,
FormGroup,
ControlLabel
} from '@freecodecamp/react-bootstrap';
import isURL from 'validator/lib/isURL';
import { maybeUrlRE } from '../../utils';
import SectionHeader from './SectionHeader';
import { FullWidthRow } from '../helpers';
import BlockSaveButton from '../helpers/form/BlockSaveButton';
const propTypes = {
githubProfile: PropTypes.string,
linkedin: PropTypes.string,
twitter: PropTypes.string,
updateInternetSettings: PropTypes.func.isRequired,
website: PropTypes.string
};
class InternetSettings extends Component {
constructor(props) {
super(props);
const {
githubProfile = '',
linkedin = '',
twitter = '',
website = ''
} = props;
this.state = {
formValues: { githubProfile, linkedin, twitter, website },
originalValues: { githubProfile, linkedin, twitter, website }
};
}
getValidationStateFor(maybeURl = '') {
if (!maybeURl || !maybeUrlRE.test(maybeURl)) {
return null;
}
if (isURL(maybeURl)) {
return 'success';
}
return 'error';
}
createHandleChange = key => e => {
const value = e.target.value.slice(0);
return this.setState(state => ({
formValues: {
...state.formValues,
[key]: value
}
}));
};
isFormPristine = () => {
const { formValues, originalValues } = this.state;
return Object.keys(originalValues)
.map(key => originalValues[key] === formValues[key])
.every(bool => bool);
};
isFormValid = () => {
const { formValues } = this.state;
return Object.keys(formValues).reduce((bool, key) => {
const maybeUrl = formValues[key];
return maybeUrl ? isURL(maybeUrl) : bool;
}, false);
};
handleSubmit = e => {
e.preventDefault();
if (!this.isFormPristine() && this.isFormValid()) {
// Only submit the form if is has changed, and if it is valid
const { formValues } = this.state;
const { updateInternetSettings } = this.props;
return updateInternetSettings(formValues);
}
return null;
};
render() {
const {
formValues: { githubProfile, linkedin, twitter, website }
} = this.state;
return (
<Fragment>
<SectionHeader>Your Internet Presence</SectionHeader>
<FullWidthRow>
<form id='internet-presence' onSubmit={this.handleSubmit}>
<FormGroup
controlId='internet-github'
validationState={this.getValidationStateFor(githubProfile)}
>
<ControlLabel>
<strong>GitHub</strong>
</ControlLabel>
<FormControl
onChange={this.createHandleChange('githubProfile')}
type='url'
value={githubProfile}
/>
</FormGroup>
<FormGroup
controlId='internet-linkedin'
validationState={this.getValidationStateFor(linkedin)}
>
<ControlLabel>
<strong>LinkedIn</strong>
</ControlLabel>
<FormControl
onChange={this.createHandleChange('linkedin')}
type='url'
value={linkedin}
/>
</FormGroup>
<FormGroup
controlId='internet-picture'
validationState={this.getValidationStateFor(twitter)}
>
<ControlLabel>
<strong>Twitter</strong>
</ControlLabel>
<FormControl
onChange={this.createHandleChange('twitter')}
type='url'
value={twitter}
/>
</FormGroup>
<FormGroup
controlId='internet-website'
validationState={this.getValidationStateFor(website)}
>
<ControlLabel>
<strong>Personal Website</strong>
</ControlLabel>
<FormControl
onChange={this.createHandleChange('website')}
type='url'
value={website}
/>
</FormGroup>
<BlockSaveButton
disabled={
this.isFormPristine() ||
(!this.isFormPristine() && !this.isFormValid())
}
/>
</form>
</FullWidthRow>
</Fragment>
);
}
}
InternetSettings.displayName = 'InternetSettings';
InternetSettings.propTypes = propTypes;
export default InternetSettings;

View File

@ -1,3 +1,5 @@
// This regex is not for validation, it is purely to see // These regex are not for validation, it is purely to see
// if we are looking at something like an email before we try to validate // if we are looking at something like what we want to validate
// before we try to validate
export const maybeEmailRE = /.*@.*\.\w\w/; export const maybeEmailRE = /.*@.*\.\w\w/;
export const maybeUrlRE = /https?:\/\/.*\..*/;