diff --git a/.idea/codeStyleSettings.xml b/.idea/codeStyleSettings.xml new file mode 100644 index 0000000..ba8dafd --- /dev/null +++ b/.idea/codeStyleSettings.xml @@ -0,0 +1,30 @@ + + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..c6cc8c8 --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..28a804d --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/HackMerced/2017F/src/app/src/actions/actions.js b/HackMerced/2017F/src/app/src/actions/actions.js index e774c21..3f52cfc 100644 --- a/HackMerced/2017F/src/app/src/actions/actions.js +++ b/HackMerced/2017F/src/app/src/actions/actions.js @@ -24,11 +24,12 @@ */ -import { SET_AUTH, UPDATE_LOGIN_FORM, UPDATE_USER_DATA, UPDATE_SIGNUP_FORM, UPDATE_SIGNUP_ERRORS, UPDATE_LOGIN_ERRORS, SET_AUTH_AS_FALSE, SET_USER_NAME_AS_FALSE, SET_USER_NAME, SET_USER_ID_AS_FALSE, SET_USER_ID, UPDATE_APPLY_STEP_ONE, UPDATE_APPLY_STEP_TWO, UPDATE_APPLY_STEP_THREE, UPDATE_APPLY_STEP_FOUR, SET_CURRENT_APPLY_STEP, UPDATE_USER_UPDATING_STATUS, UPDATE_APPLY_ERRORS, UPDATE_MOBILE_MENU_STATUS, UPDATE_SUBMITTED_VIEW,UPDATE_FORGOT_PASSWORD_FORM,UPDATE_VOLUNTEER_FORM } from '../constants'; +import { SET_AUTH, UPDATE_LOGIN_FORM, UPDATE_USER_DATA, UPDATE_SIGNUP_FORM, UPDATE_SIGNUP_ERRORS, UPDATE_LOGIN_ERRORS, UPDATE_VOLUNTEER_ERRORS, SET_AUTH_AS_FALSE, SET_USER_NAME_AS_FALSE, SET_USER_NAME, SET_USER_ID_AS_FALSE, SET_USER_ID, UPDATE_APPLY_STEP_ONE, UPDATE_APPLY_STEP_TWO, UPDATE_APPLY_STEP_THREE, UPDATE_APPLY_STEP_FOUR, SET_CURRENT_APPLY_STEP, UPDATE_USER_UPDATING_STATUS, UPDATE_APPLY_ERRORS, UPDATE_MOBILE_MENU_STATUS, UPDATE_SUBMITTED_VIEW,UPDATE_FORGOT_PASSWORD_FORM,UPDATE_VOLUNTEER_FORM } from '../constants'; import { auth } from '../util'; import { browserHistory } from 'react-router'; import { notMercedOptions } from '../constants' +import { parseError } from '../util' function mapUserDetailsToApplication(dispatch, details){ let stepOne = { @@ -186,6 +187,41 @@ export function logout() { } } +/** + * + * @param user + * @returns {function(*)} + */ +export function signUpVolunteer (user) { + return (dispatch) => { + auth.submitVolunteerApplication(user) + .then(() => { + dispatch(updateVolunteerForm({ + name: '', + email: '', + age: '', + friday_availability: '', + saturday_availability: '', + sunday_availability: '', + dietary_restrictions: '', + shirt_size: '', + })) + + forwardTo('/') + }) + .catch(({ validation }) => { + let errorSet = {} + if(validation.errors) { + validation.errors.forEach((error) => { + errorSet[error.key] = parseError(error.key, error.message); + }) + } + + dispatch(updateVolunteerErrors(errorSet)); + }); + } +} + export function signup(user) { return (dispatch) => { @@ -216,6 +252,8 @@ export function signup(user) { } } + + export function updateApplyStep(index, data){ const applyStepMap = [ updateApplyStepOne(data), @@ -268,6 +306,11 @@ export function updateSignupErrors(newState) { return { type: UPDATE_SIGNUP_ERRORS, newState }; } + +export function updateVolunteerErrors(newState) { + return { type: UPDATE_VOLUNTEER_ERRORS, newState }; +} + export function updateApplyErrors(newState) { return { type: UPDATE_APPLY_ERRORS, newState }; } diff --git a/HackMerced/2017F/src/app/src/components/application/layout.js b/HackMerced/2017F/src/app/src/components/application/layout.js index f2a4800..dae343d 100644 --- a/HackMerced/2017F/src/app/src/components/application/layout.js +++ b/HackMerced/2017F/src/app/src/components/application/layout.js @@ -1,5 +1,4 @@ import React, { Component } from 'react'; -import { TextInputBlock } from '../partials'; import { updateApplyStep, update, updateApplyErrors } from '../../actions'; import { StepOne, StepTwo, StepThree, StepFour } from './'; import { notMercedOptions } from '../../constants'; @@ -9,7 +8,6 @@ let timeChecker; export class ApplicationLayout extends Component { - render() { return (
@@ -85,7 +83,7 @@ export class ApplicationLayout extends Component { const { data } = this.props; const { name, value } = event.target; let newState = {}; - let newErrorState = {} + let newErrorState = {}; newErrorState = assign(data.applyErrors, { [ name ]: undefined diff --git a/HackMerced/2017F/src/app/src/components/application/step-three.js b/HackMerced/2017F/src/app/src/components/application/step-three.js index 4d5c4af..d195696 100644 --- a/HackMerced/2017F/src/app/src/components/application/step-three.js +++ b/HackMerced/2017F/src/app/src/components/application/step-three.js @@ -7,7 +7,7 @@ export class StepThree extends Component { render() { - const { resume, question, experience, dietary_restrictions, allergies, github, linkedin, devpost } = this.props.data; + const { resume, experience, dietary_restrictions, allergies, github, linkedin, devpost } = this.props.data; return (
diff --git a/HackMerced/2017F/src/app/src/components/forms/index.js b/HackMerced/2017F/src/app/src/components/forms/index.js index 532a3ab..66e84b1 100644 --- a/HackMerced/2017F/src/app/src/components/forms/index.js +++ b/HackMerced/2017F/src/app/src/components/forms/index.js @@ -1,4 +1,5 @@ export * from './signup'; export * from './login'; -export *from'./forget'; -export *from'./volunteer'; \ No newline at end of file +export * from './forget'; +export * from './volunteer'; + diff --git a/HackMerced/2017F/src/app/src/components/forms/volunteer.js b/HackMerced/2017F/src/app/src/components/forms/volunteer.js index f616b25..b1ee995 100644 --- a/HackMerced/2017F/src/app/src/components/forms/volunteer.js +++ b/HackMerced/2017F/src/app/src/components/forms/volunteer.js @@ -13,53 +13,47 @@ import { signUpVolunteer, updateVolunteerForm } from '../../actions'; const assign = Object.assign || require('object.assign'); export class VolunteerForm extends Component { - + render() { + const { errors, data } = this.props; + return (
-

Volunteer for HackMerced

+

Interested in helping out HackMerced?

+

Become a volunteer!

- - + + + + - + + + ); } - _onChange(event){ + _onChange(event) { let newState = this._mergeWithCurrentState({ [event.target.name]: event.target.value }); @@ -103,26 +146,30 @@ export class VolunteerForm extends Component { } // Merges the current state with a change - _mergeWithCurrentState(change) { - return assign(this.props.data, change); + _mergeWithCurrentState (change) { + const { data } = this.props; + return assign(data, change); } // Emits a change of the form state to the application state - _emitChange(newState) { + _emitChange (newState) { this.props.dispatch(updateVolunteerForm(newState)); } - _onSubmit(event){ - event.preventDefault(); - - this.props.dispatch(signUpVolunteer({ - name: this.props.data.name, - age: this.props.data.age, - availibility: this.props.data.availibility, - dietary_restrictions: this.props.data.dietary_restrictions, - shirt_size: this.props.data.shirt_size - })) + _onSubmit (event) { + const { dispatch, data } = this.props + event.preventDefault() + dispatch(signUpVolunteer({ + name: data.name, + email: data.email, + age: data.age, + friday_availability: data.friday_availability, + saturday_availability: data.saturday_availability, + sunday_availability: data.sunday_availability, + dietary_restrictions: data.dietary_restrictions, + shirt_size: data.shirt_size, + })) } } diff --git a/HackMerced/2017F/src/app/src/components/volunteer.js b/HackMerced/2017F/src/app/src/components/volunteer.js index 8883c02..4e40b2b 100644 --- a/HackMerced/2017F/src/app/src/components/volunteer.js +++ b/HackMerced/2017F/src/app/src/components/volunteer.js @@ -1,22 +1,22 @@ - import React, { Component} from 'react'; import { connect } from 'react-redux'; import { browserHistory } from 'react-router' import { VolunteerForm } from './forms'; -import { LogoWithCopy } from './partials' +import { LogoWithCopy } from './partials'; +import '../styles/apply.scss'; export class VolunteerComponent extends Component { render() { const dispatch = this.props.dispatch; - const { volunteerPersonForm, loginErrors } = this.props.data; + const { volunteerPersonForm, volunteerErrors } = this.props.data; return ( -
- - +
+ +
) } diff --git a/HackMerced/2017F/src/app/src/constants/constants.js b/HackMerced/2017F/src/app/src/constants/constants.js index 4bd90c1..fe55e23 100644 --- a/HackMerced/2017F/src/app/src/constants/constants.js +++ b/HackMerced/2017F/src/app/src/constants/constants.js @@ -31,3 +31,4 @@ export const UPDATE_MOBILE_MENU_STATUS ='UPDATE_MOBILE_MENU_STATUS'; export const UPDATE_SUBMITTED_VIEW = 'UPDATE_SUBMITTED_VIEW'; export const UPDATE_FORGOT_PASSWORD_FORM = 'UPDATE_FORGOT_PASSWORD_FORM'; export const UPDATE_VOLUNTEER_FORM = 'UPDATE_VOLUNTEER_FORM'; +export const UPDATE_VOLUNTEER_ERRORS = 'UPDATE_VOLUNTEER_ERRORS'; diff --git a/HackMerced/2017F/src/app/src/reducers/index.js b/HackMerced/2017F/src/app/src/reducers/index.js index 455ce49..3edfeed 100644 --- a/HackMerced/2017F/src/app/src/reducers/index.js +++ b/HackMerced/2017F/src/app/src/reducers/index.js @@ -10,7 +10,7 @@ * }); */ -import { UPDATE_SIGNUP_FORM, UPDATE_LOGIN_FORM, UPDATE_USER_DATA, UPDATE_SUBMITTED_VIEW, UPDATE_SIGNUP_ERRORS, UPDATE_LOGIN_ERRORS, SET_AUTH, SENDING_REQUEST, SET_ERROR_MESSAGE, SET_AUTH_AS_FALSE, SET_USER_NAME_AS_FALSE, SET_USER_NAME, SET_USER_ID_AS_FALSE, SET_USER_ID, UPDATE_APPLY_STEP_ONE, UPDATE_APPLY_STEP_TWO, UPDATE_APPLY_STEP_THREE, UPDATE_APPLY_STEP_FOUR, SET_CURRENT_APPLY_STEP, UPDATE_USER_UPDATING_STATUS, UPDATE_APPLY_ERRORS, UPDATE_MOBILE_MENU_STATUS,UPDATE_FORGOT_PASSWORD_FORM, UPDATE_VOLUNTEER_FORM} from '../constants'; +import { UPDATE_SIGNUP_FORM, UPDATE_LOGIN_FORM, UPDATE_USER_DATA, UPDATE_SUBMITTED_VIEW, UPDATE_SIGNUP_ERRORS, UPDATE_LOGIN_ERRORS, SET_AUTH, SENDING_REQUEST, SET_ERROR_MESSAGE, SET_AUTH_AS_FALSE, SET_USER_NAME_AS_FALSE, SET_USER_NAME, SET_USER_ID_AS_FALSE, SET_USER_ID, UPDATE_APPLY_STEP_ONE, UPDATE_APPLY_STEP_TWO, UPDATE_APPLY_STEP_THREE, UPDATE_APPLY_STEP_FOUR, SET_CURRENT_APPLY_STEP, UPDATE_USER_UPDATING_STATUS, UPDATE_APPLY_ERRORS, UPDATE_MOBILE_MENU_STATUS,UPDATE_FORGOT_PASSWORD_FORM, UPDATE_VOLUNTEER_FORM, UPDATE_VOLUNTEER_ERRORS } from '../constants'; // Object.assign is not yet fully supported in all browsers, so we fallback to // a polyfill const assign = Object.assign || require('object.assign'); @@ -27,25 +27,22 @@ const initialState = { forgotPasswordForm: { email: '' }, - - - - -volunteerPersonForm: { - name: '', - age: '', - availibility: '', - dietary_restrictions: '', - shirt_size: '', + volunteerPersonForm: { + name: '', + age: '', + email: '', + friday_availability: '', + saturday_availability: '', + sunday_availability: '', + dietary_restrictions: '', + shirt_size: '', }, - - - signupErrors:{}, loginForm: { email: '', password: '', }, + volunteerErrors: {}, loginErrors:{}, user:{}, currentlySending: false, @@ -141,9 +138,14 @@ export function homeReducer(state = initialState, action) { signupErrors: action.newState }); break; + case UPDATE_VOLUNTEER_ERRORS: + return assign({}, state, { + volunteerErrors: action.newState + }); + break; case UPDATE_LOGIN_FORM: return assign({}, state, { - loginFom: action.newState + loginForm: action.newState }); break; case UPDATE_LOGIN_ERRORS: @@ -156,18 +158,11 @@ export function homeReducer(state = initialState, action) { forgotPasswordForm: action.newState }); break; - - - - - - case UPDATE_VOLUNTEER_FORM: + case UPDATE_VOLUNTEER_FORM: return assign({}, state, { volunteerPersonForm: action.newState }); break; - - case SET_AUTH_AS_FALSE: return assign({}, state, { loggedIn: false @@ -186,8 +181,6 @@ export function homeReducer(state = initialState, action) { return assign({}, state, { applyErrors: action.newState }); - - case SET_AUTH: return assign({}, state, { loggedIn: action.newState diff --git a/HackMerced/2017F/src/app/src/styles/home.scss b/HackMerced/2017F/src/app/src/styles/home.scss index 92c4ecf..23cd579 100644 --- a/HackMerced/2017F/src/app/src/styles/home.scss +++ b/HackMerced/2017F/src/app/src/styles/home.scss @@ -82,7 +82,7 @@ width: 100%; height: 100%; top: 40px; - opacity: 0; + opacity: 0; @include animation('fadein 1500ms forwards 4.5s'); } diff --git a/HackMerced/2017F/src/app/src/styles/main.scss b/HackMerced/2017F/src/app/src/styles/main.scss index fd496f0..5a805da 100644 --- a/HackMerced/2017F/src/app/src/styles/main.scss +++ b/HackMerced/2017F/src/app/src/styles/main.scss @@ -28,4 +28,4 @@ body { @import 'authorization-form'; @import 'home'; -@import 'logo'; +@import 'logo'; \ No newline at end of file diff --git a/HackMerced/2017F/src/app/src/util/auth.js b/HackMerced/2017F/src/app/src/util/auth.js index 674f31a..7626751 100644 --- a/HackMerced/2017F/src/app/src/util/auth.js +++ b/HackMerced/2017F/src/app/src/util/auth.js @@ -1,11 +1,10 @@ import axios from 'axios'; -const BASE_URI = (process.env.NODE_ENV === 'development') ? 'http://localhost:1954' : ''; +const BASE_URI = (process.env.NODE_ENV === 'development') ? 'http://localhost:' + (process.env.PORT || 1954) : ''; export const auth = { saveUser(response, resolve) { const user = response.data.results; - localStorage.token = response.data.meta.token; localStorage.userName = user.name; localStorage.userId = user.id; @@ -75,6 +74,25 @@ export const auth = { }); }) }, + submitVolunteerApplication(details) { + return new Promise((resolve, reject) => { + axios({ + method: 'post', + url: BASE_URI + '/volunteer', + headers: { + 'Authorization': 'Bearer ' + localStorage.token + }, + data: details, + }) + .then(response => { + const user = response.data.results; + resolve(user); + }) + .catch(error => { + reject(error.response.data); + }); + }) + }, submitApplication(details) { return new Promise((resolve, reject) => { axios({ @@ -94,6 +112,27 @@ export const auth = { }); }) }, + submitVolunteerApplication(details) { + return new Promise((resolve, reject) => { + console.log(BASE_URI + '/volunteer') + axios({ + method: 'post', + url: BASE_URI + '/volunteer', + headers: { + 'Authorization': 'Bearer ' + localStorage.token + }, + data: details + }) + .then((response) => { + const user = response.data.results; + resolve(user); + }) + .catch((error) => { + console.log(error) + reject(error.response.data); + }) + }) + }, logout(callback) { return new Promise((resolve, reject) => { @@ -125,7 +164,6 @@ export const auth = { let headers = new Headers(); headers.append('Content-Type', 'application/json'); headers.append('Accept', 'application/json'); - axios.post(BASE_URI + '/signup', user) .then((response) => { auth.saveUser(response, resolve); diff --git a/HackMerced/2017F/src/server/src/handlers/volunteer.js b/HackMerced/2017F/src/server/src/handlers/volunteer.js index d617b78..4b7f6ba 100644 --- a/HackMerced/2017F/src/server/src/handlers/volunteer.js +++ b/HackMerced/2017F/src/server/src/handlers/volunteer.js @@ -1,41 +1,21 @@ -import Boom from 'boom'; import axios from 'axios'; -import jwt from 'jsonwebtoken'; -import parseError from '../handlers' +import { parseError } from '../handlers' const TOMOE_URI = process.env.TOMOE_URI; export const volunteerHandlers = { postVolunteer: (req, reply) => { - axios - .post(TOMOE_URI + '/volunteers/', req.payload) - .then((response) => { - reply(user); - }).catch((err) => { - reply(parseError(err.response.data)); - }); - }, - - getMe: (req, reply) => { - axios - .get(TOMOE_URI + '/volunteers/' + req.auth.credentials.id) - .then((response) => { - const user = response.data; - reply(user); - }).catch((err) => { - reply(err); - }); - }, - - postSubmit: (req, reply) => { - axios - .post(TOMOE_URI + '/volunteers/' + req.auth.credentials.id, { - status: 'submitted', - details: req.payload - }) - .then((response) => { - reply(user); - }).catch((err) => { - reply(parseError(err.response.data)); - }); + const email = req.payload.email ? req.payload.email.toLowerCase() : 'bad'; + const name = req.payload.name ? req.payload.name : ''; + axios.post(TOMOE_URI + '/volunteers', { + name, + email, + status: 'applied', + details: req.payload + }) + .then(({ data }) => { + reply(data); + }).catch((err) => { + reply(parseError(err.response.data)); + }); } } diff --git a/HackMerced/2017F/src/server/src/routes/hacker.js b/HackMerced/2017F/src/server/src/routes/hacker.js index 7d1bfc4..edef1ba 100644 --- a/HackMerced/2017F/src/server/src/routes/hacker.js +++ b/HackMerced/2017F/src/server/src/routes/hacker.js @@ -1,10 +1,6 @@ /* */ - - -import Joi from 'joi'; -import Boom from 'boom'; import { hackerHandlers } from '../handlers' import { hackerValidators } from '../validators' diff --git a/HackMerced/2017F/src/server/src/routes/volunteer.js b/HackMerced/2017F/src/server/src/routes/volunteer.js index a657af3..de0ebbd 100644 --- a/HackMerced/2017F/src/server/src/routes/volunteer.js +++ b/HackMerced/2017F/src/server/src/routes/volunteer.js @@ -1,47 +1,17 @@ -import Joi from 'joi'; -import Boom from 'boom'; import { volunteerHandlers } from '../handlers' import { volunteerValidators } from '../validators' -// [POST] /login export const postVolunteer = { - path: '/volunteer/signup', + path: '/volunteer', method: 'POST', config: { handler: volunteerHandlers.postVolunteer, + validate: volunteerValidators.postVolunteer, } }; -// [GET] /me -export const getMe = { - path: '/volunteer/me', - method: 'GET', - config: { - handler: volunteerHandlers.getMe, - auth: { - strategy: 'token', - } - } -}; - -// [POST] /submit -export const postSubmit = { - path: '/volunteer/submit', - method: 'POST', - config: { - handler: volunteerHandlers.postSubmit, - validate: volunteerValidators.postSubmit, - auth: { - strategy: 'token', - } - } -}; - const volunteerRoutes = [ postVolunteer, - getMe, - postSubmit ] export default volunteerRoutes; - diff --git a/HackMerced/2017F/src/server/src/validators/volunteer.js b/HackMerced/2017F/src/server/src/validators/volunteer.js index 588fc49..5d63b69 100644 --- a/HackMerced/2017F/src/server/src/validators/volunteer.js +++ b/HackMerced/2017F/src/server/src/validators/volunteer.js @@ -1,31 +1,16 @@ import Joi from 'joi'; -import fs from 'fs'; -import path from 'path'; - -import { notMercedOptions } from '../../../app/src/constants' export const volunteerValidators = { postVolunteer:{ - //tomoe - }, - - getMe:{ - payload:{ - id: Joi.string().required() - } - }, - - postSubmit:{ payload:{ name: Joi.string().required(), - age: Joi.number().integer().min(14).max(121).required().options({ language: { any: { allowOnly: 'Sorry we only allow people older than age 14 and younger than 121!' } } }), - email: Joi.string().required(), - availability: Joi.string().required(), + age: Joi.number().integer().min(18).max(121).required().options({ language: { any: { allowOnly: 'Sorry we only allow people older than age 18 and younger than 121!' } } }), + email: Joi.string().required().email(), + friday_availability: Joi.string().required(), + saturday_availability: Joi.string().required(), + sunday_availability: Joi.string().required(), dietary_restrictions: Joi.string().required(), shirt_size: Joi.string().required() } } } - - - \ No newline at end of file