summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlowercasename <raphaelkabo@gmail.com>2019-08-03 14:31:37 +0100
committerlowercasename <raphaelkabo@gmail.com>2019-08-03 14:31:37 +0100
commitc7469119b76fe63154a39131317d38644f6830ac (patch)
treeb1234458f349620c48c9f23d9247f6967ff06376
parente4269caf3412a85d1f6b8578f8b708942826b387 (diff)
Users can remove themselves, admins can remove all users from events
-rwxr-xr-xpublic/css/style.css10
-rwxr-xr-xroutes.js78
-rwxr-xr-xviews/event.handlebars83
3 files changed, 159 insertions, 12 deletions
diff --git a/public/css/style.css b/public/css/style.css
index ebbc375..ec43118 100755
--- a/public/css/style.css
+++ b/public/css/style.css
@@ -251,3 +251,13 @@ body, html {
height: 2.25rem !important;
}
+#removeAttendee {
+ position: absolute;
+ top: 110px;
+ left: 53px;
+ color: #fff;
+}
+
+#removeAttendee:hover {
+ color: #c82333;
+}
diff --git a/routes.js b/routes.js
index ab41656..ff218a1 100755
--- a/routes.js
+++ b/routes.js
@@ -146,10 +146,10 @@ router.get('/:eventID', (req, res) => {
else {
displayDate = moment.tz(event.start, event.timezone).format('dddd D MMMM YYYY [<span class="text-muted">at</span>] h:mm a') + moment.tz(event.end, event.timezone).format(' [<span class="text-muted">–</span>] dddd D MMMM YYYY [<span class="text-muted">at</span>] h:mm a [<span class="text-muted">](z)[</span>]');
}
- eventStartISO = moment.tz(event.start, event.timezone).toISOString();
- eventEndISO = moment.tz(event.end, event.timezone).toISOString();
+ eventStartISO = moment.tz(event.start, "Etc/UTC").toISOString();
+ eventEndISO = moment.tz(event.end, "Etc/UTC").toISOString();
parsedStart = moment.tz(event.start, event.timezone).format('YYYYMMDD[T]HHmmss');
- parsedEnd = moment.tz(event.start, event.timezone).format('YYYYMMDD[T]HHmmss');
+ parsedEnd = moment.tz(event.end, event.timezone).format('YYYYMMDD[T]HHmmss');
let eventHasConcluded = false;
if (moment.tz(event.end, event.timezone).isBefore(moment.tz(event.timezone))){
eventHasConcluded = true;
@@ -588,6 +588,76 @@ router.post('/attendevent/:eventID', (req, res) => {
});
});
+router.post('/unattendevent/:eventID', (req, res) => {
+ Event.update(
+ { id: req.params.eventID },
+ { $pull: { attendees: { email: req.body.attendeeEmail } } }
+ )
+ .then(response => {
+ console.log(response)
+ addToLog("removeEventAttendee", "success", "Attendee removed from event " + req.params.eventID);
+ if (sendEmails) {
+ if (req.body.attendeeEmail){
+ const msg = {
+ to: req.body.attendeeEmail,
+ from: {
+ name: 'Gathio',
+ email: 'notifications@gath.io',
+ },
+ templateId: 'd-56c97755d6394c23be212fef934b0f1f',
+ dynamic_template_data: {
+ subject: 'gathio: You have been removed from an event',
+ eventID: req.params.eventID
+ },
+ };
+ sgMail.send(msg);
+ }
+ }
+ res.writeHead(302, {
+ 'Location': '/' + req.params.eventID
+ });
+ res.end();
+ })
+ .catch((err) => {
+ res.send('Database error, please try again :('); addToLog("removeEventAttendee", "error", "Attempt to remove attendee from event " + req.params.eventID + " failed with error: " + err);
+ });
+});
+
+router.post('/removeattendee/:eventID/:attendeeID', (req, res) => {
+ Event.update(
+ { id: req.params.eventID },
+ { $pull: { attendees: { _id: req.params.attendeeID } } }
+ )
+ .then(response => {
+ console.log(response)
+ addToLog("removeEventAttendee", "success", "Attendee removed by admin from event " + req.params.eventID);
+ if (sendEmails) {
+ if (req.body.attendeeEmail){
+ const msg = {
+ to: req.body.attendeeEmail,
+ from: {
+ name: 'Gathio',
+ email: 'notifications@gath.io',
+ },
+ templateId: 'd-56c97755d6394c23be212fef934b0f1f',
+ dynamic_template_data: {
+ subject: 'gathio: You have been removed from an event',
+ eventID: req.params.eventID
+ },
+ };
+ sgMail.send(msg);
+ }
+ }
+ res.writeHead(302, {
+ 'Location': '/' + req.params.eventID
+ });
+ res.end();
+ })
+ .catch((err) => {
+ res.send('Database error, please try again :('); addToLog("removeEventAttendee", "error", "Attempt to remove attendee by admin from event " + req.params.eventID + " failed with error: " + err);
+ });
+});
+
router.post('/post/comment/:eventID', (req, res) => {
let commentID = shortid.generate();
const newComment = {
@@ -655,7 +725,7 @@ router.post('/post/reply/:eventID/:commentID', (req, res) => {
event.save()
.then(() => {
addToLog("addEventReply", "success", "Reply added to comment " + commentID + " in event " + req.params.eventID);
- if (sendEmails) {
+ if (sendEmails) {
Event.findOne({id: req.params.eventID}).distinct('attendees.email', function(error, ids) {
attendeeEmails = ids;
if (!error){
diff --git a/views/event.handlebars b/views/event.handlebars
index daacfc5..8d2559b 100755
--- a/views/event.handlebars
+++ b/views/event.handlebars
@@ -95,12 +95,17 @@
{{#if eventData.usersCanAttend}}
<div class="card mb-4" id="eventAttendees">
- <h5 class="card-header" style="width:100%;display:flex;justify-content:space-between;align-items:center">Attendees {{#if eventData.attendees}}({{eventData.attendees.length}}){{/if}}<button type="button" id="attendEvent" class="btn btn-primary" data-toggle="modal" data-target="#attendModal"><i class="fas fa-user-plus"></i> I'm going!</button></h5>
+ <h5 class="card-header" style="width:100%;display:flex;justify-content:space-between;align-items:center">Attendees {{#if eventData.attendees}}({{eventData.attendees.length}}){{/if}}
+ <div class="btn-group" role="group" aria-label="Attendance controls">
+ <button type="button" id="attendEvent" class="btn btn-success" data-toggle="modal" data-target="#attendModal"><i class="fas fa-user-plus"></i> Add me</button>
+ <button type="button" id="unattendEvent" class="btn btn-secondary" data-toggle="modal" data-target="#unattendModal"><i class="fas fa-user-times"></i> Remove me</button>
+ </div>
+ </h5>
<div class="card-body">
{{#if eventData.attendees}}
<ul class="attendeesList">
{{#each eventData.attendees}}
- <li>{{this.name}}</li>
+ <li{{#if ../editingEnabled}} data-attendee-name="{{this.name}}" data-attendee-id="{{this._id}}"{{/if}}>{{this.name}}{{#if ../editingEnabled}}<a href="#" id="removeAttendee" data-toggle="modal" data-target="#removeAttendeeModal"><i class="fas fa-user-times"></i></a>{{/if}}</li>
{{/each}}
</ul>
{{else}}
@@ -129,8 +134,8 @@
<div class="form-group row">
<label for="attendeeEmail" class="col-sm-2 col-form-label">Your email</label>
<div class="form-group col-sm-10">
- <input type="email" class="form-control" id="attendeeEmail" name="attendeeEmail" placeholder="We won't spam you <3" data-validation="email" data-validation-optional="true">
- <small class="form-text">Optional - we'll use it to send you any updates to the event.</small>
+ <input type="email" class="form-control" id="attendeeEmail" name="attendeeEmail" placeholder="We won't spam you <3" data-validation="email">
+ <small class="form-text">We'll only use it to send you updates to the event.</small>
</div>
</div>
</div>
@@ -142,8 +147,61 @@
</div>
</div>
</div>
+
+<div class="modal fade" id="unattendModal" tabindex="-1" role="dialog" aria-labelledby="unattendModalLabel" aria-hidden="true">
+ <div class="modal-dialog" role="document">
+ <div class="modal-content">
+ <div class="modal-header">
+ <h5 class="modal-title" id="unattendModalLabel">Remove yourself from '{{eventData.name}}'</h5>
+ <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+ <span aria-hidden="true">&times;</span>
+ </button>
+ </div>
+ <form id="unattendEventForm" action="/unattendevent/{{eventData.id}}" method="post">
+ <div class="modal-body">
+ <div class="form-group row">
+ <label for="attendeeEmail" class="col-sm-2 col-form-label">Your email</label>
+ <div class="form-group col-sm-10">
+ <input type="email" class="form-control" id="attendeeEmail" name="attendeeEmail" placeholder="name@domain.com" data-validation="email" data-validation-optional="true">
+ <small class="form-text">Enter the email you used when signing up for this event.</small>
+ </div>
+ </div>
+ </div>
+ <div class="modal-footer">
+ <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
+ <button type="submit" class="btn btn-primary">Remove myself</button>
+ </div>
+ </form>
+ </div>
+ </div>
+</div>
+
+ {{#if editingEnabled}}
+ <div class="modal fade" id="removeAttendeeModal" tabindex="-1" role="dialog" aria-labelledby="removeAttendeeModalLabel" aria-hidden="true">
+ <div class="modal-dialog" role="document">
+ <div class="modal-content">
+ <div class="modal-header">
+ <h5 class="modal-title" id="removeAttendeeModalLabel">Remove attendee from '{{eventData.name}}'</h5>
+ <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+ <span aria-hidden="true">&times;</span>
+ </button>
+ </div>
+ <form id="removeAttendeeForm" action="/removeattendee/{{eventData.id}}/" method="post">
+ <div class="modal-body">
+ <p>Are you sure you want to remove this attendee from the event? This action cannot be undone.</p>
+ </div>
+ <div class="modal-footer">
+ <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
+ <button type="submit" class="btn btn-danger">Remove attendee</button>
+ </div>
+ </form>
+ </div>
+ </div>
+ </div>
+ {{/if}}
{{/if}}
+
{{#if eventData.usersCanComment}}
<div class="card mb-4" id="eventComments">
<h5 class="card-header">Discussion</h5>
@@ -220,7 +278,6 @@
{{#if editingEnabled}}
{{#unless eventHasConcluded}}
-<script type="text/javascript" src="/js/generate-timezones.js"></script>
{{> editeventmodal }}
{{/unless}}
@@ -248,9 +305,10 @@
{{/if}}
-
+{{#unless eventHasConcluded}}
+<script type="text/javascript" src="/js/generate-timezones.js"></script>
+{{/unless}}
<script>
-
$.validate({
lang: 'en',
errorElementClass: "is-invalid",
@@ -258,6 +316,15 @@
successElementClass: "is-valid"
});
{{#if editingEnabled}}
+
+ $('#removeAttendeeModal').on('show.bs.modal', function (event) {
+ var listItem = $(event.relatedTarget).closest('li'); // List element enclosing button
+ var attendeeName = listItem.data('attendee-name');
+ var attendeeID = listItem.data('attendee-id');
+ var modal = $(this);
+ modal.find('.modal-title').text('Remove ' + attendeeName + ' from {{eventData.name}}')
+ modal.find('#removeAttendeeForm').attr('action', '/removeattendee/{{eventData.id}}/' + attendeeID);
+ })
{{#unless eventHasConcluded}}
$('#eventStart').datepicker({
language: 'en',
@@ -287,7 +354,7 @@
$(this).closest(".comment").find(".replyContainer").slideToggle();
})
$(document).ready(function() {
-
+
$.uploadPreview({
input_field: "#image-upload",
preview_box: "#image-preview",