Created
April 8, 2016 17:59
-
-
Save victorpavlenko/eb946583197787f9179bd434d969c292 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, {Component} from 'react'; | |
import {reduxForm, addArrayValue} from 'redux-form'; | |
import Switch from './switch'; | |
import Scroll from './../atoms/scroll'; | |
import PureInput from '../atoms/pure-input'; | |
import PureDeepInput from '../atoms/pure-deep-input'; | |
import PureSelect from '../atoms/pure-select'; | |
import Location from '../atoms/location'; | |
import validate from './validate-deep'; | |
import {dispatchSaveOrgContact} from '../../lib/edit-org'; | |
export const fields = [ | |
'name', | |
'social[].name', | |
'social[].value', | |
'contact[].name', | |
'contact[].value', | |
'link[].name', | |
'link[].value', | |
'website', | |
'fullAddress', | |
'other', | |
'phone', | |
'email', | |
'type' | |
]; | |
class EditOrganizationContact extends Component { | |
constructor(props) { | |
super(props); | |
this.clickAddNew = this.clickAddNew.bind(this); | |
this.handleNewInfoChange = this.handleNewInfoChange.bind(this); | |
this.submitForm = this.submitForm.bind(this); | |
this.addField = this.addField.bind(this); | |
this.state = { | |
newContact: false, | |
newSocial: false, | |
newLink: false | |
} | |
} | |
componentDidMount(){ | |
let data = this.props.profile.profile; | |
console.log(data.email); | |
let values = { | |
email: data.email || '', | |
phone: data.phone || '', | |
website: data.website || '', | |
fullAddress: data.fullAddress ? data.fullAddress.placeDescription : '' | |
}; | |
this.props.initializeForm(values); | |
let social = this.props.fields.social; | |
let link = this.props.fields.link; | |
let contact = this.props.fields.contact; | |
if(data.socialList.length > 0){ | |
data.socialList.map(function(value, key){ | |
social.addField({name: value.name, value: value.value}); | |
}); | |
} | |
if(data.linksList.length > 0){ | |
data.linksList.map(function(value, key){ | |
link.addField({name: value.name, value: value.value}); | |
}); | |
} | |
if(data.contactList.length > 0){ | |
data.contactList.map(function(value, key){ | |
contact.addField({name: value.name, value: value.value}); | |
}); | |
} | |
this.setState({ | |
id: data.uuid | |
}) | |
} | |
clickAddNew(type){ | |
let state = 'new' + type.charAt(0).toUpperCase() + type.slice(1); | |
this.setState({ | |
[state]: true | |
}); | |
} | |
addField(type, data){ | |
this.props.fields[type].addField(data) | |
} | |
handleNewInfoChange(type, typeInput){ | |
let state = 'new' + type.charAt(0).toUpperCase() + type.slice(1); | |
if (typeInput.id == 'other') { | |
let data = { | |
name: '', value: '' | |
}; | |
this.addField(type, data); | |
this.setState({ | |
[state]: [typeInput], | |
[state]: false | |
}); | |
} else { | |
let data = { | |
name: typeInput.name, value: '' | |
}; | |
this.addField(type, data); | |
this.setState({ | |
[state]: [typeInput], | |
[state]: false | |
}); | |
} | |
} | |
submitForm(data) { | |
data.id = this.state.id; | |
dispatchSaveOrgContact(this.props.dispatch, data) | |
} | |
render() { | |
const {fields: {name, website,type, other, phone, fullAddress, email, social, contact, link}, handleSubmit, addValue} = this.props; | |
let SocialListItem = [ | |
{ id: 'twitter', name: 'twitter'}, | |
{ id: 'facebook', name: 'facebook'}, | |
{ id: 'pintrest', name: 'pintrest'}, | |
{ id: 'other', name: 'other'} | |
]; | |
let LinkListItem = [ | |
{ id: 'blog', name: 'blog'}, | |
{ id: 'other', name: 'other'} | |
]; | |
let ContactListItem = [ | |
{ id: 'twitter', name: 'twitter'}, | |
{ id: 'facebook', name: 'facebook'}, | |
{ id: 'pintrest', name: 'pintrest'}, | |
{ id: 'other', name: 'other'} | |
]; | |
return ( | |
<div className='profile profile edit contact'> | |
<div className='profile-header'>Edit {name.value}</div> | |
<Scroll> | |
<Switch type={this.props.type} setType={this.props.setType}/> | |
<form name='contact' autoComplete='off'> | |
<div className='profile-body'> | |
<div className="contact-block"> | |
<div className="contact-tag"><span className="contact-tag-social">Social Media</span></div> | |
<div className="input-field"> | |
<label htmlFor="">linkedin</label> | |
<span>http://linkedin.com/{name.value}</span> | |
</div> | |
{(social.length > 0) ? social.map((v, i) => | |
<PureDeepInput field={v} label={v.name.value} key={i} /> | |
) : ''} | |
{this.state.newSocial ? ( | |
<PureSelect field={type} list={SocialListItem} label="type" onChange={this.handleNewInfoChange.bind(null, 'social')}/> | |
) : ''} | |
<div className="contact-add-new" onClick={this.clickAddNew.bind(null, 'social')}> + Add new social media</div> | |
</div> | |
<hr/> | |
<div className="contact-block"> | |
<div className="contact-tag"><span className="contact-tag-link">Links</span></div> | |
<PureInput field={website} label="website" icon="globe"/> | |
{(social.length > 0) ? link.map((v, i) => | |
<PureDeepInput field={v} label={v.name.value} key={i} /> | |
): ''} | |
{this.state.newLink ? ( | |
<PureSelect field={type} list={LinkListItem} label="type" onChange={this.handleNewInfoChange.bind(null, 'link')}/> | |
): ''} | |
<div className="contact-add-new" onClick={this.clickAddNew.bind(null, 'link')}>+ Add new link</div> | |
</div> | |
<hr/> | |
<div className="contact-block"> | |
<div className="contact-tag"><span className="contact-tag-contact">Contact Info</span></div> | |
<Location field={fullAddress} label="location" placeholder={'Country/State/City'}/> | |
<PureInput field={phone} label="phone" icon="phone"/> | |
<PureInput field={email} label="email" icon="envelope"/> | |
{(contact.length > 0) ? contact.map((v, i) => | |
<PureDeepInput field={v} label={v.name.value} key={i} /> | |
): ''} | |
{this.state.newContact ? ( | |
<PureSelect field={type} list={ContactListItem} label="type" onChange={this.handleNewInfoChange.bind(null, 'contact')}/> | |
) : ''} | |
<div className="contact-add-new" onClick={this.clickAddNew.bind(null, 'contact')}>+ Add new Contact Info</div> | |
</div> | |
</div> | |
</form> | |
</Scroll> | |
<div className="profile-footer"> | |
<button className="button not">Cancel</button> | |
<button className="button" onClick={handleSubmit(this.submitForm)}>Save Changes</button> | |
</div> | |
</div> | |
); | |
} | |
} | |
EditOrganizationContact.propTypes = { | |
fields: React.PropTypes.object.isRequired, | |
addValue: React.PropTypes.func.isRequired, | |
handleSubmit: React.PropTypes.func.isRequired | |
}; | |
export default reduxForm({ | |
form: 'contact', | |
fields, | |
validate | |
}, state => ({ // mapStateToProps | |
initialValues: { | |
social: [{ | |
label: 'lifograph', | |
value: 'http://lifograph.com/deawilson1' | |
},{ | |
label: 'facebook', | |
value: 'pavlenko' | |
},{ | |
label: 'vk', | |
value: '' | |
}] | |
} | |
}), { | |
addValue: addArrayValue | |
})(EditOrganizationContact); | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, {Component} from 'react'; | |
import Modal from '../atoms/modal'; | |
import EditOrganizationDetails from './profile'; | |
import EditOrganizationContact from './contact'; | |
import editOrgAction from '../../actions/profile/edit-org'; | |
import {connect} from 'react-redux'; | |
import {dispatchLoadOrg, getOrgData} from '../../lib/edit-org' | |
class EditProfile extends Component { | |
constructor(props) { | |
super(props); | |
this.setType = this.setType.bind(this); | |
this.closeModal = this.closeModal.bind(this); | |
this.state = { | |
modalIsOpen: true, | |
type: 'profile' | |
} | |
} | |
componentDidMount() { | |
dispatchLoadOrg(this.props.dispatch, this.props.id) | |
} | |
closeModal(){ | |
this.setState({ | |
modalIsOpen: !this.state.modalIsOpen | |
}) | |
} | |
setType(type){ | |
this.setState({ | |
type: type | |
}) | |
} | |
render() { | |
let {editOrgCache, editOrgState, id} = this.props; | |
let _getProfile = getOrgData.bind(null, editOrgCache, editOrgState); | |
let profile = _getProfile(id); | |
return ( | |
<div> | |
{(profile) ? | |
(<Modal modalIsOpen={this.state.modalIsOpen} closeModal={this.closeModal} > | |
{(this.state.type === 'profile') ? | |
<EditOrganizationDetails | |
setType={this.setType} | |
type="profile" | |
profile={profile} | |
/> : | |
<EditOrganizationContact | |
setType={this.setType} | |
type="contact" | |
profile={profile} | |
/> | |
} | |
</Modal>) : '' } | |
</div> | |
); | |
} | |
} | |
export default connect( | |
function(state, props){ | |
return { | |
editOrgState: state.editOrgState, | |
editOrgCache: state.editOrgCache, | |
id: props.params.profileId | |
} | |
}, editOrgAction)(EditProfile); | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, {Component} from 'react'; | |
import {reduxForm} from 'redux-form'; | |
import AvatarView from './../atoms/avatar-view'; | |
import Switch from './switch'; | |
import PureInput from '../atoms/pure-input'; | |
import PureSelect from '../atoms/pure-select'; | |
import PureTextarea from '../atoms/pure-textarea'; | |
import Scroll from './../atoms/scroll'; | |
import {validate} from './validate'; | |
import {dispatchSaveOrg} from '../../lib/edit-org' | |
class EditOrganizationDetails extends Component { | |
constructor(props) { | |
super(props); | |
this.handleFileChange = this.handleFileChange.bind(this); | |
this.handleSaveAvatar = this.handleSaveAvatar.bind(this); | |
this.handleInputChangeAvatar = this.handleInputChangeAvatar.bind(this); | |
this.handleSelectChange = this.handleSelectChange.bind(this); | |
this.closeImageUploadModal = this.closeImageUploadModal.bind(this); | |
this.submitForm = this.submitForm.bind(this); | |
this.deletePhoto = this.deletePhoto.bind(this); | |
this.state = { | |
image: '', | |
preview: null, | |
imageUploadIsOpen: false | |
} | |
} | |
componentDidMount(){ | |
let data = this.props.profile.profile; | |
let values = { | |
name: data.name || '', | |
industry: data.industry || '', | |
orgType: data.orgType || '', | |
orgTypeExchangeSymbol: data.orgTypeExchangeSymbol || '', | |
orgTypeOther: data.orgTypeOther || '', | |
summary: data.summary || '', | |
headline: data.headline || '' | |
}; | |
this.props.initializeForm(values); | |
let that = this; | |
data.imageList.map(function(value) { | |
return that.handleSaveAvatar(value) | |
}); | |
this.setState({ | |
id: data.uuid | |
}) | |
} | |
handleSelectChange(type, value) { | |
if(value.id == 'newOrg'){ | |
window.open('/#/addprofile','_blank'); | |
} | |
if(type){ | |
this.props.fields[type].onChange(value); | |
let inputName = 'input' + type.toUpperCase(); | |
this.setState({ | |
[inputName]: value | |
}); | |
} | |
} | |
closeImageUploadModal() { | |
this.setState({ | |
imageUploadIsOpen: false | |
}); | |
} | |
handleFileChange(data) { | |
this.setState({ | |
image: data, | |
imageUploadIsOpen: true | |
}) | |
} | |
handleInputChangeAvatar(data) { | |
if(this.props.fields.avatar.length == 3){ | |
document.querySelector('.image-upload-item.new').className = 'image-upload-item new disabled'; | |
document.querySelector('input[type=file]').disabled = 'disabled'; | |
}else{ | |
document.querySelector('.image-upload-item.new').className = 'image-upload-item new '; | |
document.querySelector('input[type=file]').disabled = ''; | |
this.props.fields.avatar.addField({ | |
url: data.url, | |
uuid: data.uuid, | |
fileName: data.fileName | |
}); | |
} | |
} | |
handleSaveAvatar(data){ | |
let image = { | |
url: data.url || data, | |
fileName: 'name', | |
type: 'type', | |
uuid: data.uuid || "new-" + data.substring(Math.floor(Math.random( ) * 20) + Math.floor(Math.random( ) * 20), Math.floor(Math.random( ) * 20) + Math.floor(Math.random( ) * 20)) | |
}; | |
this.handleInputChangeAvatar(image); | |
this.setState({ | |
preview: image, | |
imageUploadIsOpen: false | |
}); | |
} | |
submitForm(data) { | |
data.id = this.state.id; | |
data.summary = data.summary.replace(/[^a-zA-Z0-9_:,.'-]/g, ' ').trim(); | |
dispatchSaveOrg(this.props.dispatch, data) | |
} | |
deletePhoto(avatar, id){ | |
if(avatar.uuid.value.indexOf('new') + 1) { | |
this.props.fields.avatar.removeField(id); | |
}else{ | |
this.props.fields.avatar.removeField(id); | |
this.props.fields.avatar.addField({ | |
deleteImage: true, | |
uuid: avatar.uuid.value, | |
fileName: avatar.fileName.value, | |
url: avatar.url.value | |
}, id); | |
} | |
} | |
shouldComponentUpdate(nextProps, nextState) { | |
return this.props.fields !== nextProps.fields || nextState != this.state; | |
} | |
render() { | |
const {fields: {orgType, summary, avatar, industry, orgTypeExchangeSymbol, orgTypeOther, newIndustry, headline, name}, handleSubmit} = this.props; | |
let industryList = [ | |
{ id: 'it', name: 'IT'}, | |
{ id: 'bank', name: 'Bank'}, | |
{ id: 'new', name: 'Add New' } | |
]; | |
var organizationTypeList = [ | |
{ id: 'publiclyTraded', name: 'Publicly Traded'}, | |
{ id: 'private', name: 'Private'}, | |
{ id: 'nonProfit', name: 'Non Profit' }, | |
{ id: 'governmental', name: 'Governmental' }, | |
{ id: 'other', name: 'Other' } | |
]; | |
if(orgType.value && industry.value){ | |
console.log(orgType.value && orgType.value.id == 'other'); | |
} | |
return ( | |
<div className="profile profile"> | |
<div className="profile-header"> | |
Edit {name.value} | |
</div> | |
<Scroll> | |
<Switch type={this.props.type} setType={this.props.setType} /> | |
<form name="profile" autoComplete='off'> | |
<div className="profile-body "> | |
<PureSelect field={orgType} list={organizationTypeList} label="organization type" onChange={this.handleSelectChange.bind(null, 'orgType')} /> | |
{(orgType.value && orgType.value.id == 'publiclyTraded') ? (<PureInput field={orgTypeExchangeSymbol} label="Stock Exchange Ticker"/>) : ''} | |
{(orgType.value && orgType.value.id == 'other') ? (<PureInput field={orgTypeOther} label="Other"/>) : ''} | |
<PureSelect field={industry} list={industryList} value={industry.value} label="Industry" onChange={this.handleSelectChange.bind(null, 'industry')} /> | |
{(industry.value && industry.value.id == 'new') ? (<PureInput field={newIndustry} label="Add New Industry"/>) : ''} | |
<PureInput field={headline} label="headline"/> | |
<PureTextarea field={summary} label="description"/> | |
<hr/> | |
<AvatarView | |
label="PROFILE PICTURES" | |
preview={avatar} | |
image={this.state.image} | |
handleFileChange={this.handleFileChange} | |
imageUploadIsOpen={this.state.imageUploadIsOpen} | |
closeImageUploadModal={this.closeImageUploadModal} | |
handleSaveAvatar={this.handleSaveAvatar} | |
deletePhoto={this.deletePhoto} | |
/> | |
{avatar.map((c, index) => | |
<div key={index}> | |
<input type="hidden" {...c} value={c.value} onChange={(e) => c.onChange(e.target.value)} /> | |
</div> | |
)} | |
</div> | |
</form> | |
</Scroll> | |
<div className="profile-footer"> | |
<button className="button not">Cancel</button> | |
<button className="button" onClick={handleSubmit(this.submitForm)}>Save Changes</button> | |
</div> | |
</div> | |
); | |
} | |
} | |
EditOrganizationDetails.propTypes = { | |
fields: React.PropTypes.object.isRequired, | |
handleSubmit: React.PropTypes.func.isRequired | |
}; | |
export default reduxForm({ | |
form: 'profile', | |
fields: [ | |
'orgType', 'industry', 'headline', 'summary', 'name', | |
'avatar[]', | |
'avatar[].url', | |
'avatar[].uuid', | |
'avatar[].deleteImage', | |
'avatar[].fileName', | |
'newIndustry', 'orgTypeExchangeSymbol', 'orgTypeOther'], | |
destroyOnUnmount: false, | |
validate | |
})(EditOrganizationDetails); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, {Component} from 'react'; | |
import classNames from 'classnames'; | |
class Switch extends Component { | |
constructor(props) { | |
super(props); | |
this.changeProfileType = this.changeProfileType.bind(this); | |
} | |
changeProfileType(type){ | |
this.props.setType(type); | |
} | |
render() { | |
return ( | |
<div className="profile-change"> | |
<span className={classNames({'active': (this.props.type == 'profile')})} onClick={this.changeProfileType.bind(null, 'profile')}>Organization Details</span> | |
<span className={classNames({'active': (this.props.type == 'contact')})} onClick={this.changeProfileType.bind(null, 'contact')}>Contact Details</span> | |
</div> | |
); | |
} | |
} | |
Switch.propTypes = { | |
type: React.PropTypes.node.isRequired, | |
setType: React.PropTypes.func.isRequired | |
}; | |
export default Switch; | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export function validate(values){ | |
const errors = {}; | |
Object.keys(values).map(function (v, i) { | |
if (!values[v]) { | |
errors[v] = true | |
} | |
}); | |
delete errors.newPosition; | |
delete errors.newIndustry; | |
delete errors.orgTypeExchangeSymbol; | |
delete errors.orgTypeOther; | |
return errors; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment