Skip to content
This repository has been archived by the owner on May 28, 2018. It is now read-only.

Commit

Permalink
Add copy application on renew
Browse files Browse the repository at this point in the history
  • Loading branch information
nbrohee committed May 23, 2017
1 parent fcfc03b commit 78fd27c
Show file tree
Hide file tree
Showing 10 changed files with 222 additions and 15 deletions.
53 changes: 53 additions & 0 deletions client/npm-debug.log.2126673800
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
0 info it worked if it ends with ok
1 verbose cli [ '/usr/local/Cellar/node/6.2.0/bin/node',
1 verbose cli '/usr/local/bin/npm',
1 verbose cli 'run',
1 verbose cli 'start' ]
2 info using npm@3.10.6
3 info using node@v6.2.0
4 verbose run-script [ 'prestart', 'start', 'poststart' ]
5 info lifecycle etudiant-entrepreneur@0.0.1~prestart: etudiant-entrepreneur@0.0.1
6 verbose lifecycle etudiant-entrepreneur@0.0.1~prestart: unsafe-perm in lifecycle true
7 verbose lifecycle etudiant-entrepreneur@0.0.1~prestart: PATH: /usr/local/lib/node_modules/npm/bin/node-gyp-bin:/Users/nbr/projects/sgmap/etudiant-entrepreneur/client/node_modules/.bin:/usr/local/lib/node_modules/npm/bin/node-gyp-bin:/Users/nbr/projects/sgmap/etudiant-entrepreneur/node_modules/.bin:/usr/local/lib/node_modules/npm/bin/node-gyp-bin:/Users/nbr/projects/sgmap/etudiant-entrepreneur/node_modules/.bin:/usr/local/Cellar/node/6.2.0/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin
8 verbose lifecycle etudiant-entrepreneur@0.0.1~prestart: CWD: /Users/nbr/projects/sgmap/etudiant-entrepreneur/client
9 silly lifecycle etudiant-entrepreneur@0.0.1~prestart: Args: [ '-c', 'babel-node tools/startMessage.js' ]
10 silly lifecycle etudiant-entrepreneur@0.0.1~prestart: Returned: code: 0 signal: null
11 info lifecycle etudiant-entrepreneur@0.0.1~start: etudiant-entrepreneur@0.0.1
12 verbose lifecycle etudiant-entrepreneur@0.0.1~start: unsafe-perm in lifecycle true
13 verbose lifecycle etudiant-entrepreneur@0.0.1~start: PATH: /usr/local/lib/node_modules/npm/bin/node-gyp-bin:/Users/nbr/projects/sgmap/etudiant-entrepreneur/client/node_modules/.bin:/usr/local/lib/node_modules/npm/bin/node-gyp-bin:/Users/nbr/projects/sgmap/etudiant-entrepreneur/node_modules/.bin:/usr/local/lib/node_modules/npm/bin/node-gyp-bin:/Users/nbr/projects/sgmap/etudiant-entrepreneur/node_modules/.bin:/usr/local/Cellar/node/6.2.0/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin
14 verbose lifecycle etudiant-entrepreneur@0.0.1~start: CWD: /Users/nbr/projects/sgmap/etudiant-entrepreneur/client
15 silly lifecycle etudiant-entrepreneur@0.0.1~start: Args: [ '-c',
15 silly lifecycle 'npm-run-all --parallel test:watch open:src lint:watch' ]
16 silly lifecycle etudiant-entrepreneur@0.0.1~start: Returned: code: 1 signal: null
17 info lifecycle etudiant-entrepreneur@0.0.1~start: Failed to exec start script
18 verbose stack Error: etudiant-entrepreneur@0.0.1 start: `npm-run-all --parallel test:watch open:src lint:watch`
18 verbose stack Exit status 1
18 verbose stack at EventEmitter.<anonymous> (/usr/local/lib/node_modules/npm/lib/utils/lifecycle.js:255:16)
18 verbose stack at emitTwo (events.js:106:13)
18 verbose stack at EventEmitter.emit (events.js:191:7)
18 verbose stack at ChildProcess.<anonymous> (/usr/local/lib/node_modules/npm/lib/utils/spawn.js:40:14)
18 verbose stack at emitTwo (events.js:106:13)
18 verbose stack at ChildProcess.emit (events.js:191:7)
18 verbose stack at maybeClose (internal/child_process.js:850:16)
18 verbose stack at Process.ChildProcess._handle.onexit (internal/child_process.js:215:5)
19 verbose pkgid etudiant-entrepreneur@0.0.1
20 verbose cwd /Users/nbr/projects/sgmap/etudiant-entrepreneur/client
21 error Darwin 15.6.0
22 error argv "/usr/local/Cellar/node/6.2.0/bin/node" "/usr/local/bin/npm" "run" "start"
23 error node v6.2.0
24 error npm v3.10.6
25 error code ELIFECYCLE
26 error etudiant-entrepreneur@0.0.1 start: `npm-run-all --parallel test:watch open:src lint:watch`
26 error Exit status 1
27 error Failed at the etudiant-entrepreneur@0.0.1 start script 'npm-run-all --parallel test:watch open:src lint:watch'.
27 error Make sure you have the latest version of node.js and npm installed.
27 error If you do, this is most likely a problem with the etudiant-entrepreneur package,
27 error not with npm itself.
27 error Tell the author that this fails on your system:
27 error npm-run-all --parallel test:watch open:src lint:watch
27 error You can get information on how to open an issue for this project with:
27 error npm bugs etudiant-entrepreneur
27 error Or if that isn't available, you can get their info via:
27 error npm owner ls etudiant-entrepreneur
27 error There is likely additional logging output above.
28 verbose exit [ 1, true ]
4 changes: 3 additions & 1 deletion client/src/actions/actionTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export const LOAD_PROJECT_SUCCESS = "LOAD_PROJECT_SUCCESS"
export const UPDATE_PROJECT = "UPDATE_PROJECT"

export const LOAD_CONTACT_SUCCESS = "LOAD_CONTACT_SUCCESS"
export const COPY_CONTACT_SUCCESS = "COPY_CONTACT_SUCCESS"
export const UPDATE_CONTACT = "UPDATE_CONTACT"

export const LOAD_PEPITE_SUCCESS = "UPDATE_PEPITE_SUCCESS"
Expand All @@ -23,7 +24,8 @@ export const DELETE_COMMITTEE_SUCCESS = "DELETE_COMMITTEE_SUCCESS"

export const LOAD_NEXT_COMMITTEE_SUCCESS = "LOAD_NEXT_COMMITTEE_SUCCESS"

export const LOAD_PROFILE_SUCCESS = "UPDATE_PROFILE_SUCCESS"
export const LOAD_PROFILE_SUCCESS = "LOAD_PROFILE_SUCCESS"
export const COPY_PROFILE_SUCCESS = "COPY_PROFILE_SUCCESS"
export const UPDATE_PROFILE = "UPDATE_PROFILE"

export const UPDATE_ERRORS = "UPDATE_ERRORS"
Expand Down
29 changes: 27 additions & 2 deletions client/src/actions/applicationActions.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import applicationApi from '../api/applicationApi'
import { loadContactSuccess, } from './contactActions'
import { loadContactSuccess, copyContactSuccess } from './contactActions'
import { loadProjectSuccess } from './projectActions'
import { loadPepiteSuccess } from './pepiteActions'
import { loadProfileSuccess } from './profileActions'
import { loadProfileSuccess, copyProfileSuccess } from './profileActions'
import { loadCareerSuccess } from './careerActions'
import { loadCommitteeAnswerSuccess, applicationToCommitteeAnswer } from './committeeAnswerActions'
import * as types from './actionTypes'
Expand Down Expand Up @@ -45,6 +45,31 @@ export function loadApplication(id) {
if (application.career) {
dispatch(loadCareerSuccess(application.career))
}
return application
}).catch(error => {
throw (error)
})
}
}

export function copyApplication(id) {
return dispatch => {
return applicationApi.getApplication(id).then(application => {
dispatch(copyContactSuccess(application.contact))
dispatch(loadCommitteeAnswerSuccess(applicationToCommitteeAnswer(application)))
if (application.project) {
dispatch(loadProjectSuccess(application.project))
}
if (application.pepite) {
dispatch(loadPepiteSuccess(application.pepite))
}
if (application.profile) {
dispatch(copyProfileSuccess(application.profile))
}
if (application.career) {
dispatch(loadCareerSuccess(application.career))
}
return application
}).catch(error => {
throw (error)
})
Expand Down
6 changes: 6 additions & 0 deletions client/src/actions/contactActions.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ export function loadContactSuccess(contact) {
return { type: types.LOAD_CONTACT_SUCCESS, contact }
}

export function copyContactSuccess(contact) {
return { type: types.COPY_CONTACT_SUCCESS, contact }
}

export function updateContact(contact) {
return { type: types.UPDATE_CONTACT, contact }
}


4 changes: 4 additions & 0 deletions client/src/actions/profileActions.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ export function loadProfileSuccess(profile) {
return { type: types.LOAD_PROFILE_SUCCESS, profile }
}

export function copyProfileSuccess(profile) {
return { type: types.COPY_PROFILE_SUCCESS, profile }
}

export function updateProfile(profile) {
return { type: types.UPDATE_PROFILE, profile }
}
Expand Down
32 changes: 22 additions & 10 deletions client/src/components/application/Contact/ContactPage.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import React, {PropTypes} from 'react'
import React, { PropTypes } from 'react'
import ContactForm from './ContactForm'
import {connect} from 'react-redux'
import {bindActionCreators} from 'redux'
import { connect } from 'react-redux'
import { bindActionCreators } from 'redux'
import * as contactActions from '../../../actions/contactActions'
import * as applicationActions from '../../../actions/applicationActions'
import * as errorsActions from '../../../actions/errorsActions'
import {contactValidationConstraints} from './ContactValidationConstraints'
import { contactValidationConstraints } from './ContactValidationConstraints'
import Validation from '../../common/Validation'
import {isEmptyObject} from '../../common/validationHelper.js'
import { isEmptyObject } from '../../common/validationHelper.js'
import RenewContainer from './RenewContainer'

export class ContactPage extends React.Component {
constructor(props, context) {
Expand Down Expand Up @@ -48,18 +50,26 @@ export class ContactPage extends React.Component {
return this.setState({ errors })
}

isRenewIdDisplayed() {
return (this.props.contact.isRenew == 'true')
}

render() {
return (
<ContactForm
contact={this.state.contact}
onChange={this.updateContactState}
errors={this.state.errors}/>
<div>
<ContactForm
contact={this.state.contact}
onChange={this.updateContactState}
errors={this.state.errors} />
{this.isRenewIdDisplayed() && <RenewContainer
copyApplication={this.props.applicationActions.copyApplication}
isRenew={this.props.contact.isRenew} />}
</div>
)
}
}

function mapStateToProps(state, ownProps) {

return {
errors: state.errors.contact,
contact: state.contact
Expand All @@ -69,13 +79,15 @@ function mapStateToProps(state, ownProps) {
function mapDispatchToProps(dispatch) {
return {
actions: bindActionCreators(contactActions, dispatch),
applicationActions: bindActionCreators(applicationActions, dispatch),
errorsActions: bindActionCreators(errorsActions, dispatch)
}
}

ContactPage.propTypes = {
contact: PropTypes.object.isRequired,
actions: PropTypes.object.isRequired,
applicationActions: PropTypes.object.isRequired,
errorsActions: PropTypes.object.isRequired,
errors: PropTypes.object.isRequired
}
Expand Down
66 changes: 66 additions & 0 deletions client/src/components/application/Contact/RenewContainer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import React, { PropTypes } from 'react'
import { connect } from 'react-redux'
import { bindActionCreators } from 'redux'
import toastr from 'toastr'

import * as contactActions from '../../../actions/contactActions'
import RenewForm from './RenewForm'

export class RenewContainer extends React.Component {
constructor(props, context) {
super(props, context)
this.state = {
oldLink: '',
error: '',
renewId: ''
}
this.onOldLinkChange = this.onOldLinkChange.bind(this)
this.onCopyApplicationClick = this.onCopyApplicationClick.bind(this)
}

onOldLinkChange(event) {
const oldLink = event.target.value
this.setState({ oldLink })
this.validateOldLink(oldLink)
}

validateOldLink(oldLink) {
const regex = /^(.*\/application\/)?([a-f\d]{24})$/i
const match = regex.exec(oldLink)
if (match && match[2]) {
this.setState({ error: '', renewId: match[2] })
} else {
this.setState({ error: 'Ton lien n\'est pas valide', renewId: '' })
}
}

onCopyApplicationClick(event) {
event.preventDefault()
this.props.copyApplication(this.state.renewId).then(() => {
toastr.success('Candidature copiée')
})
.catch((err) => {
if (err.response && err.response.data && err.response.data.reason) {
toastr.error(err.response.data.reason)
} else {
toastr.error(err)
}
})
}

render() {
return (
<RenewForm
onOldLinkChange={this.onOldLinkChange}
onCopyApplicationClick={this.onCopyApplicationClick}
oldLink={this.state.oldLink}
error={this.state.error} />
)
}
}

RenewContainer.propTypes = {
copyApplication: PropTypes.func.isRequired
}

export default RenewContainer
32 changes: 32 additions & 0 deletions client/src/components/application/Contact/RenewForm.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import React, { PropTypes } from 'react'
import { FormGroup, ControlLabel, Panel, InputGroup, FormControl, HelpBlock } from 'react-bootstrap'
import ValidatedComponent from '../../common/ValidatedComponent'

const RenewForm = ({ oldLink, error, onOldLinkChange, onCopyApplicationClick }) => {
return (
<Panel bsStyle="primary" header="Repartir de ma candidature de l'année passée">
<form>
<FormGroup>
<ControlLabel>Lien de ta candidature</ControlLabel>
<ValidatedComponent error={error}>
<InputGroup>
<InputGroup.Addon>{`${window.location.protocol}//`}</InputGroup.Addon>
<FormControl name="oldLink" type="text" placeholder={`${window.location.host}/application/xxxxxxx`} onChange={onOldLinkChange} value={oldLink} />
</InputGroup>
</ValidatedComponent>
<HelpBlock>Tu trouveras ce lien dans le mail de ta candidature de l'année passée</HelpBlock>
</FormGroup>
<button type="button" className="btn btn-success" disabled={!oldLink && !!error} onClick={onCopyApplicationClick}>Copier</button>
</form>
</Panel>
)
}

RenewForm.propTypes = {
oldLink: PropTypes.string.isRequired,
onOldLinkChange: PropTypes.func.isRequired,
onCopyApplicationClick: PropTypes.func.isRequired,
error: PropTypes.string
}

export default RenewForm
6 changes: 5 additions & 1 deletion client/src/reducers/contactReducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@ export default function contactReducer(state = initialState.contact, action) {
switch (action.type) {
case types.UPDATE_CONTACT:
case types.LOAD_CONTACT_SUCCESS:
return Object.assign({}, state.contact, action.contact )
return Object.assign({}, state, action.contact)
case types.COPY_CONTACT_SUCCESS:
delete action.contact.schoolYear
delete action.contact.situation
return Object.assign({}, state, action.contact)
default:
return state
}
Expand Down
5 changes: 4 additions & 1 deletion client/src/reducers/profileReducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ export default function profileReducer(state = initialState.profile, action) {
switch (action.type) {
case types.UPDATE_PROFILE:
case types.LOAD_PROFILE_SUCCESS:
return Object.assign({}, state.profile, action.profile )
return Object.assign({}, state, action.profile )
case types.COPY_PROFILE_SUCCESS:
delete action.profile.situation
return Object.assign({}, state, action.profile )
default:
return state
}
Expand Down

0 comments on commit 78fd27c

Please sign in to comment.