Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Event form implementation #224

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8,902 changes: 4,451 additions & 4,451 deletions client/package-lock.json

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "client",
"version": "0.1.1",
"private": true,
"proxy": "http://localhost:8000/",
"proxy": "https://karachi-communities.herokuapp.com",
"dependencies": {
"bootstrap": "^4.1.1",
"font-awesome": "^4.7.0",
Expand All @@ -22,6 +22,7 @@
"react-scripts": "1.1.4",
"react-select": "^1.2.1",
"react-share": "^2.2.0",
"react-spinners": "^0.4.7",
"react-toastify": "^4.1.0",
"reactstrap": "^6.1.0",
"redux": "^4.0.0",
Expand Down
65 changes: 65 additions & 0 deletions client/src/actions/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import OrganisationsService from '../services/organisation';
import SponsorsService from '../services/sponsors';
import LocationService from '../services/locations';
import TagsService from '../services/tags';
import EventFormService from '../services/eventform';

import UserService from '../services/user';
import * as humps from 'humps';
Expand Down Expand Up @@ -41,6 +42,14 @@ export const POST_COMMENT = 'POST_COMMENT';
// organisation
export const FETCH_ORGANISATION_DETAIL = 'FETCH_ORGANISATION_DETAIL';

//EVENT SIGNUP FORM
export const TOGGLE_EVENT_SIGNUP_MODAL = 'TOGGLE_EVENT_SIGNUP_MODAL';

export const FETCH_EVENT_SIGNUP_FORM = 'FETCH_EVENT_SIGNUP_FORM';
export const EVENT_FORM_RESPONSE = 'EVENT_FORM_RESPONSE';
export const POST_EVENT_SIGNUP_DETAILS = 'POST_EVENT_SIGNUP_DETAILS';
export const EVENT_SIGNUP_SUCCESS_RESPONSE = 'EVENT_SIGNUP_SUCCESS_RESPONSE';

//misc
export const FETCH_LOCATIONS = 'FETCH_LOCATIONS';
export const FETCH_ORGANISATIONS = 'FETCH_ORGANISATIONS';
Expand Down Expand Up @@ -362,3 +371,59 @@ export const fetchTags = query => async (dispatch, getState) => {
return e;
}
};

//event form action

export const toggleModal = state => ({
type: TOGGLE_EVENT_SIGNUP_MODAL,
showSignupModal: state,
});

export const eventForm = form => ({
type: EVENT_FORM_RESPONSE,
form,
});

export const postEventSignup = userDetails => ({
type: POST_EVENT_SIGNUP_DETAILS,
userDetails,
});

export const eventSignupSuccess = payload => ({
type: EVENT_SIGNUP_SUCCESS_RESPONSE,
payload,
});

export const fetchForm = () => ({
type: FETCH_EVENT_SIGNUP_FORM,
});

export const fetchEventFormById = id => async dispatch => {
dispatch(toggleModal(true));
dispatch(fetchForm());
dispatch(triggerRequest(FETCH_EVENT_SIGNUP_FORM));
try {
const response = await EventFormService.getFormById(id);

dispatch(eventForm(response));
} catch (e) {
dispatch(triggerFailure(FETCH_EVENT_SIGNUP_FORM, e.message));
return e;
}
};

export const postEventSignupDetails = (
userDetails,
formId
) => async dispatch => {
dispatch(triggerRequest(POST_EVENT_SIGNUP_DETAILS));
try {
const response = await EventFormService.signupForEvent(userDetails, formId);

dispatch(eventSignupSuccess(response));
dispatch(toggleModal(false));
} catch (e) {
dispatch(triggerFailure(POST_EVENT_SIGNUP_DETAILS, e.message));
return e;
}
};
71 changes: 71 additions & 0 deletions client/src/components/EventSignup/EventSignupModal.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import React, { Component } from 'react';
import { Modal, ModalHeader, ModalBody } from 'reactstrap';
import SignUpForm from '../EventSignupForm/EventSignupForm';
import { postEventSignupDetails } from '../../actions';
import { connect } from 'react-redux';
import withLoader from '../Loader/withLoader';
import {
ModalBodyTypes,
EventSignupModalTypes,
} from '../../types/event-form-types';

const ModalBody_ = props => (
<div>
<ModalHeader>{props.eventForm.title}</ModalHeader>
<ModalBody>
<SignUpForm
fields={props.eventForm.fields}
onSubmit={props.onSubmit}
registered={props.registered}
toggle={props.toggle}
/>
</ModalBody>
</div>
);

ModalBody_.propTypes = ModalBodyTypes;

const ModalContent = withLoader(ModalBody_);
class EventSignupModal extends Component {
constructor(props) {
super(props);
}

onSubmit = e => {
e.preventDefault();
const { dispatch, eventForm } = this.props;
const { name, email, phone } = e.target.elements;

const payload = {
name: name.value,
email: email.value,
phone: phone.value,
};

dispatch(postEventSignupDetails(payload, eventForm.id));
};
render() {
const { props } = this;
const { eventForm } = this.props;
return (
<Modal
isOpen={props.showModal}
toggle={value => {
props.toggle(value);
}}
>
<ModalContent
showModal={props.showModal}
eventForm={eventForm}
isFetching={props.isFetching}
onSubmit={this.onSubmit}
toggle={props.toggle}
registered={props.registered}
/>
</Modal>
);
}
}

EventSignupModal.propTypes = EventSignupModalTypes;
export default connect(null)(EventSignupModal);
36 changes: 36 additions & 0 deletions client/src/components/EventSignup/EventSignupView.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import React, { Component } from 'react';
import { Label, Button } from 'reactstrap';

export default class EventSignupView extends Component {
render() {
const { props } = this;
return (
<div
style={{
display: 'flex',

justifyContent: 'center',
alignItems: 'center',
}}
>
<div
style={{
width: '50%',
alignItems: 'center',
display: 'flex',
flexDirection: 'column',
}}
>
<h3>
<Label>Sign Up For This Event</Label>
</h3>
{props.isRegistered ? (
<span style={{ color: 'green' }}> Signed up! </span>
) : (
<Button onClick={props.onSignUpPress}>Sign Up</Button>
)}
</div>
</div>
);
}
}
11 changes: 11 additions & 0 deletions client/src/components/EventSignupForm/EventSignUpFormValidator.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
const validate = values => {
const errors = {},
{ name, email } = values;

if (!name) errors.name = '*Name Required';
if (!email) errors.email = '*Email Required';

return errors;
};

export default validate;
Empty file.
65 changes: 65 additions & 0 deletions client/src/components/EventSignupForm/EventSignupForm.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import React from 'react';
import { Button } from 'reactstrap';
import './EventSignupForm.css';
import { Field, reduxForm } from 'redux-form';
import renderField from '../RenderField';
import validate from './EventSignUpFormValidator';
import { EventSignupFormTypes } from '../../types/event-form-types';

const placeHolder = {
name: 'Name',
email: 'Email',
phone: 'Phone',
};

const EventSignupForm = props => {
const { valid } = props;

return (
<form id="login-form" onSubmit={props.onSubmit}>
{props.fields.map((field, i) => (
<Field
type="text"
key={i}
placeholder={placeHolder[field.label]}
className="form-control"
name={field.label}
component={renderField}
/>
))}

<div
style={{
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
}}
>
{props.registered ? (
<Button
className="btn btn-primary"
value="Signup_success"
onClick={() => props.toggle(false)}
>
Signed up!
</Button>
) : (
<Button
type="submit"
className="btn btn-primary"
value="Signup"
disabled={!valid}
>
Submit
</Button>
)}
</div>
</form>
);
};

EventSignupForm.propTypes = EventSignupFormTypes;
export default reduxForm({
form: 'eventSignupform',
validate,
})(EventSignupForm);
36 changes: 36 additions & 0 deletions client/src/components/Loader/withLoader.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import React from 'react';
import { ClipLoader } from 'react-spinners';
import { LoaderTypes } from '../../types/event-form-types';

const withLoader = Component => {
return function wrappedWithLoader({ isFetching, ...props }) {
return (
<div>
{isFetching ? (
<div
className="sweet-loading"
style={{
display: 'flex',
height: 80,
justifyContent: 'center',
alignItems: 'center',
}}
>
<ClipLoader
className={'MoonLoader'}
sizeUnit={'px'}
size={30}
color={'green'}
loading={isFetching}
/>
</div>
) : (
<Component {...props} />
)}
</div>
);
};
};

withLoader.propTypes = LoaderTypes;
export default withLoader;
11 changes: 9 additions & 2 deletions client/src/containers/App/routes/private.routes.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
import React, { Fragment } from 'react';
import { Route, Redirect } from 'react-router-dom';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';

//components
import EditUserProfile from '../../EditProfile/EditUserProfile';

const LoginRedirection = () => <Redirect to="/login" />;
const LoginRedirection = props => (
<Redirect to={{ pathname: '/login', state: { from: props.location } }} />
);

LoginRedirection.propTypes = {
location: PropTypes.object,
};

const PrivateRoutes = props => (
<Fragment>
Expand All @@ -16,7 +23,7 @@ const PrivateRoutes = props => (
{props.userState.token ? (
<EditUserProfile {...routesProps} />
) : (
<LoginRedirection />
<LoginRedirection {...routesProps} />
)}
</div>
)}
Expand Down
1 change: 1 addition & 0 deletions client/src/containers/App/routes/public.routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { Route, Redirect, Switch } from 'react-router-dom';
import Signup from '../../Signup/Signup';
import Login from '../../Login/Login';
import Events from '../../Events/Events';

import ForgotPassword from '../../ForgotPassword/ForgotPassword';

const BaseRedirection = () => <Redirect to="/events" />;
Expand Down
Loading