Skip to content

Instantly share code, notes, and snippets.

@victorpavlenko
Created April 8, 2016 17:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save victorpavlenko/eb946583197787f9179bd434d969c292 to your computer and use it in GitHub Desktop.
Save victorpavlenko/eb946583197787f9179bd434d969c292 to your computer and use it in GitHub Desktop.
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);
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);
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);
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;
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