Skip to content
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
26 changes: 25 additions & 1 deletion src/actions/attendeesAction.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,15 @@ import {
REGISTER_PARTICIPANT_INITIATED,
REGISTER_PARTICIPANT_SUCCESS,
REGISTER_PARTICIPANT_FAIL,
CANCEL_PARTICIPATION_INITIATED,
CANCEL_PARTICIPATION_SUCCESS,
CANCEL_PARTICIPATION_FAIL,
ADD_TEAM_MEMBER_SUCCESS,
ADD_TEAM_MEMBER_FAIL,
INVITATION_ACCEPT_REJECT_INITIATED,
INVITATION_ACCEPT_REJECT_SUCCESS,
INVITATION_ACCEPT_REJECT_FAIL
} from '../utils/constants';
} from "../utils/constants";

export function fetchAttendeesInitiated(eventID) {
return {
Expand Down Expand Up @@ -168,3 +171,24 @@ export function invitationAcceptRejectFail(payload) {
payload
};
}

export function cancelParticipationInitiated(payload) {
return {
type: CANCEL_PARTICIPATION_INITIATED,
payload
};
}

export function cancelParticipationSuccess(payload) {
return {
type: CANCEL_PARTICIPATION_SUCCESS,
payload
};
}

export function cancelParticipationFail(payload) {
return {
type: CANCEL_PARTICIPATION_FAIL,
payload
};
}
36 changes: 36 additions & 0 deletions src/components/EventDetails/ConfirmPopup.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import React from "react";
import { Button, Popconfirm } from "antd";

const ConfirmPopup = ({
handleConfirm,
btnText,
disabled,
loading,
icon,
btnClass,
type,
parentClass
}) => {
return (
<div className={parentClass}>
<Popconfirm
title="Are you sure?"
okText="Yes"
cancelText="No"
onConfirm={handleConfirm}
>
<Button
className={disabled ? `${btnClass} disabled-b` : btnClass}
type={type}
icon={icon}
block
loading={loading}
>
{btnText}
</Button>
</Popconfirm>
</div>
);
};

export default ConfirmPopup;
12 changes: 11 additions & 1 deletion src/components/EventDetails/EventDetails.scss
Original file line number Diff line number Diff line change
Expand Up @@ -204,4 +204,14 @@
padding-left: 5px;
}
}
}
}
}

.btn-dangerous {
border-color: #f02520 !important;
color: #f02520 !important;
}

.cancel-mt {
margin-top: 10px;
}
13 changes: 12 additions & 1 deletion src/components/EventDetails/EventDetailsContainer.js
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,14 @@ class EventDetailsContainer extends Component {
this.props.registerIndividualParticipation(payLoad);
};

handleRSVPCancel = () => {
const payload = {
eventId: this.props.event.id
};

this.props.cancelIndividualParticipation(payload);
};

handleAcceptReject = (value, teamId, memberId) => {
const payload = {
eventId: this.props.event.id,
Expand Down Expand Up @@ -314,6 +322,7 @@ class EventDetailsContainer extends Component {
<IndividualRegistration
attending={is_attending}
handleRSVPClick={this.handleRSVPClick}
handleRSVPCancel={this.handleRSVPCancel}
isPastEvent={isPastEvent}
loading={rsvpLoading}
// error={rsvpError}
Expand Down Expand Up @@ -480,7 +489,9 @@ function mapDispatchToProps(dispatch) {
registerIndividualParticipation: payload =>
dispatch(registerParticipantInitiated(payload)),
invitationAcceptRejectInitiated: payload =>
dispatch(invitationAcceptRejectInitiated(payload))
dispatch(invitationAcceptRejectInitiated(payload)),
cancelIndividualParticipation: payload =>
dispatch(cancelParticipationInitiated(payload))
};
}

Expand Down
70 changes: 46 additions & 24 deletions src/components/EventDetails/IndividualParticipation.js
Original file line number Diff line number Diff line change
@@ -1,29 +1,51 @@
import React from 'react';
import { Button, Popconfirm } from 'antd';
const individualParticipation = ({rsvp, handleRSVPClick, attending, isPastEvent, loading }) => {
if (attending || rsvp) {
return <div className={isPastEvent? "going-to-event disabled-b": "going-to-event"}>{isPastEvent? 'You have attended this event': 'You are going.'}</div>
}

return (
import React from "react";
import ConfirmPopup from "./ConfirmPopup";
const individualParticipation = ({
rsvp,
handleRSVPClick,
attending,
isPastEvent,
loading,
handleRSVPCancel
}) => {
if (attending || rsvp) {
if (isPastEvent)
return (
<div className="going-to-event disabled-b">
You have attended this event{" "}
</div>
);
else
return (
<div>
<div>
<div className='yes-no-buttons-wrapper'>
<Popconfirm title="Are you sure?" okText="Yes" cancelText="No" onConfirm={isPastEvent? ()=>{}: handleRSVPClick}>
<Button
className= {isPastEvent? "disabled-b button yesButton": 'button yesButton'}
type='ghost'
icon='check'
block
loading={loading}
>
RSVP
</Button>
</Popconfirm>
</div>
</div>
<div className="going-to-event">You are going!</div>
<ConfirmPopup
handleConfirm={handleRSVPCancel}
disabled={isPastEvent}
loading={loading}
btnText="Cancel RSVP"
btnClass="btn-dangerous button ant-btn-round cancel-mt"
/>
</div>
);
);
}

return (
<div>
<div>
<ConfirmPopup
handleConfirm={handleRSVPClick}
disabled={isPastEvent}
loading={loading}
btnText="RSVP"
icon="check"
btnClass="button yesButton ant-btn-round"
type="ghost"
parentClass="yes-no-buttons-wrapper "
/>
</div>
</div>
);
};

export default individualParticipation;
35 changes: 32 additions & 3 deletions src/reducers/attendeesReducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,12 @@ import {
REGISTER_PARTICIPANT_FAIL,
INVITATION_ACCEPT_REJECT_INITIATED,
INVITATION_ACCEPT_REJECT_SUCCESS,
INVITATION_ACCEPT_REJECT_FAIL
} from 'UTILS/constants';
import { getTeamMembers } from '../utils/util';
INVITATION_ACCEPT_REJECT_FAIL,
CANCEL_PARTICIPATION_FAIL,
CANCEL_PARTICIPATION_INITIATED,
CANCEL_PARTICIPATION_SUCCESS
} from "UTILS/constants";
import { getTeamMembers } from "../utils/util";

const initialState = {
isLoading: false,
Expand All @@ -43,6 +46,12 @@ function addNewAttendees({members}) {
return members || [];
}

function removeAttendee({ members }) {
const email = localStorage.getItem("email") || "";

return members.filter(m => m.invitee && m.invitee.email !== email);
}

export default function eventReducer(state = initialState, action) {
switch (action.type) {
case FETCH_ATTENDEES_INITIATED:
Expand Down Expand Up @@ -220,6 +229,26 @@ export default function eventReducer(state = initialState, action) {
error: action.payload
};

case CANCEL_PARTICIPATION_INITIATED:
return {
...state,
rsvpLoading: true
};
case CANCEL_PARTICIPATION_SUCCESS:
const newMembers = removeAttendee(state);
return {
...state,
members: newMembers,
rsvpLoading: false,
rsvp: false
};
case CANCEL_PARTICIPATION_FAIL:
return {
...state,
rsvpLoading: false,
rsvpError: action.payload
};

default:
return state;
}
Expand Down
32 changes: 26 additions & 6 deletions src/sagas/attendeesSaga.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { call, put, takeEvery } from 'redux-saga/effects';
import { call, put, takeEvery, takeLatest } from "redux-saga/effects";
import {
fetchAttendeesSuccess,
fetchAttendeesFailed,
Expand All @@ -13,19 +13,25 @@ import {
registerParticipantSuccess,
registerParticipantFail,
invitationAcceptRejectSuccess,
invitationAcceptRejectFail
} from 'ACTION/attendeesAction';
invitationAcceptRejectFail,
cancelParticipationSuccess,
cancelParticipationFail
} from "ACTION/attendeesAction";
import {
FETCH_ATTENDEES_INITIATED,
ADD_TEAM_MEMBER_INITIATED,
CREATE_TEAM_INITIATED,
UPDATE_TEAM_INITIATED,
DELETE_TEAM_INITIATED,
REGISTER_PARTICIPANT_INITIATED,
CANCEL_PARTICIPATION_INITIATED,
INVITATION_ACCEPT_REJECT_INITIATED
} from 'UTILS/constants';
import RequestHandler from '../HTTP';
import { showFailureNotification, showSuccessNotification } from '../components/shared/Notification';
} from "UTILS/constants";
import RequestHandler from "../HTTP";
import {
showFailureNotification,
showSuccessNotification
} from "../components/shared/Notification";

function* fetchAttendees(action) {
try {
Expand Down Expand Up @@ -144,6 +150,19 @@ function* inviteAcceptReject(action) {
}
}

function* cancelParticipation(action) {
try {
const response = yield call(() =>
RequestHandler.delete(`events/${action.payload.eventId}/rsvp`)
);
showSuccessNotification("Cancelled RSVP!");

yield put(cancelParticipationSuccess(response));
} catch (error) {
yield put(cancelParticipationFail(error));
}
}

export default function* attendeesSaga() {
yield takeEvery(FETCH_ATTENDEES_INITIATED, fetchAttendees);
yield takeEvery(ADD_TEAM_MEMBER_INITIATED, addTeamMember);
Expand All @@ -152,4 +171,5 @@ export default function* attendeesSaga() {
yield takeEvery(DELETE_TEAM_INITIATED, deleteTeam);
yield takeEvery(REGISTER_PARTICIPANT_INITIATED, registerParticipant);
yield takeEvery(INVITATION_ACCEPT_REJECT_INITIATED, inviteAcceptReject);
yield takeLatest(CANCEL_PARTICIPATION_INITIATED, cancelParticipation);
}
4 changes: 4 additions & 0 deletions src/utils/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@ export const MEMBER_INVITE_STATUS = {
PENDING: 'invited'
};

export const CANCEL_PARTICIPATION_INITIATED = "CANCEL_PARTICIPATION_INITIATED";
export const CANCEL_PARTICIPATION_SUCCESS = "CANCEL_PARTICIPATION_SUCCESS";
export const CANCEL_PARTICIPATION_FAIL = "CANCEL_PARTICIPATION_FAIL";

export const HTTP_STANDARD_ERRORS = {
400: 'Bad request',
401: 'Unauthorized',
Expand Down