diff options
Diffstat (limited to 'views')
-rwxr-xr-x | views/event.handlebars | 80 | ||||
-rwxr-xr-x | views/layouts/main.handlebars | 2 | ||||
-rwxr-xr-x | views/newevent.handlebars | 137 | ||||
-rw-r--r-- | views/partials/editeventmodal.handlebars | 264 | ||||
-rwxr-xr-x | views/partials/eventForm.handlebars | 141 | ||||
-rwxr-xr-x | views/partials/neweventform.handlebars | 179 |
6 files changed, 381 insertions, 422 deletions
diff --git a/views/event.handlebars b/views/event.handlebars index 1576647..41e3591 100755 --- a/views/event.handlebars +++ b/views/event.handlebars @@ -136,7 +136,7 @@ {{#unless noMoreSpots}} <button type="button" id="attendEvent" class="btn btn-success" data-event-id="{{eventData.id}}"><i class="fas fa-user-plus"></i> Add me</button> {{/unless}} - <button type="button" id="unattendEvent" class="btn btn-seco.split("?")[0];dary" data-toggle="modal" data-target="#unattendModal"><i class="fas fa-user-times"></i> Remove 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"> @@ -397,18 +397,7 @@ {{/if}} <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script> -{{#unless eventHasConcluded}} -{{#if editingEnabled}} -<script type="text/javascript" src="/js/generate-timezones.js"></script> -{{/if}} -{{/unless}} <script> - $.validate({ - lang: 'en', - errorElementClass: "is-invalid", - errorMessageClass: "text-danger", - successElementClass: "is-valid" - }); {{#if editingEnabled}} $('#removeAttendeeModal').on('show.bs.modal', function (event) { @@ -419,24 +408,6 @@ 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', - timepicker: true, - dateFormat: 'd MM yyyy', - dateTimeSeparator: ', ', - onSelect: function(formattedDate, rawDate){ - $('#eventEnd').datepicker().data('datepicker').update('minDate', rawDate).clear(); - } - }); - $('#eventEnd').datepicker({ - language: 'en', - timepicker: true, - dateFormat: 'd MM yyyy', - dateTimeSeparator: ', ' - }); - $("#timezone").val('{{eventData.timezone}}').trigger('change'); - {{/unless}} {{/if}} $(".commentTimestamp").html(function(){ parsedDate = moment($(this).html()).fromNow(); @@ -512,23 +483,7 @@ document.body.removeChild(a); } - $.uploadPreview({ - input_field: "#image-upload", - preview_box: "#image-preview", - label_field: "#image-label", - label_default: "Choose file", - label_selected: "Change file", - no_label: false - }); - $("#image-preview").css("background-image", "url('/events/{{eventData.image}}')"); - $("#image-preview").css("background-size", "cover"); - $("#image-preview").css("background-position", "center center"); - {{#if editingEnabled}} - $('#eventStart').datepicker().data('datepicker').selectDate(moment('{{parsedStart}}', 'YYYYMMDD[T]HHmmss').toDate()); - $('#eventEnd').datepicker().data('datepicker').selectDate(moment('{{parsedEnd}}', 'YYYYMMDD[T]HHmmss').toDate()); - {{/if}} new ClipboardJS('#copyEventLink'); - autosize($('textarea')); $("#exportICS").click(function(){ let eventID = $(this).attr('data-event-id'); $.get('/exportevent/' + eventID, function(response) { @@ -548,39 +503,6 @@ if ($("#joinCheckbox").is(':checked')){ $("#maxAttendeesCheckboxContainer").css("display","flex"); } - $("#maxAttendeesCheckbox").on("click", function() { - if ($(this).is(':checked')) { - $("#maxAttendeesContainer").slideDown('fast').css("display","flex"); - $("#maxAttendees").attr("data-validation-optional","false"); - } - else { - $("#maxAttendeesContainer").slideUp('fast'); - $("#maxAttendees").attr("data-validation-optional","true").val("").removeClass('is-valid is-invalid'); - } - }); - $("#joinCheckbox").on("click", function() { - if ($(this).is(':checked')) { - $("#maxAttendeesCheckboxContainer").slideDown('fast').css("display","flex"); - } - else { - $("#maxAttendeesCheckboxContainer").slideUp('fast'); - $("#maxAttendeesCheckbox").prop("checked",false); - $("#maxAttendeesContainer").slideUp('fast'); - $("#maxAttendees").attr("data-validation-optional","true").val("").removeClass('is-valid is-invalid'); - } - }); - $("#eventGroupCheckbox").on("click", function() { - if ($(this).is(':checked')) { - $("#eventGroupData").slideDown('fast'); - $("#eventGroupID").removeAttr("data-validation-optional").attr("data-validation","required"); - $("#eventGroupEditToken").removeAttr("data-validation-optional").attr("data-validation","required"); - } - else { - $("#eventGroupData").slideUp('fast'); - $("#eventGroupID").removeAttr("data-validation").attr("data-validation-optional","true").val(""); - $("#eventGroupEditToken").removeAttr("data-validation").attr("data-validation-optional","true").val(""); - } - }); $('#attendEvent').on('click', function(event) { const modal = $('#attendModal'); const eventID = $(this).attr('data-event-id'); diff --git a/views/layouts/main.handlebars b/views/layouts/main.handlebars index ee6817b..daa5a37 100755 --- a/views/layouts/main.handlebars +++ b/views/layouts/main.handlebars @@ -53,6 +53,8 @@ <script src="/js/moment-timezone.js"></script> <script src="/js/util.js"></script> + <script src="//unpkg.com/alpinejs" defer></script> + </head> <body> diff --git a/views/newevent.handlebars b/views/newevent.handlebars index 5e7752f..76b6a17 100755 --- a/views/newevent.handlebars +++ b/views/newevent.handlebars @@ -24,7 +24,20 @@ </div> <div id="newEventFormContainer"> - {{>neweventform}} + <h4 class="mb-2">Create an event</h4> + <form id="newEventForm" enctype="multipart/form-data" x-data="newEventForm()" x-init="init()" @submit.prevent="submitForm"> + {{>eventForm}} + <div class="form-group row"> + <div class="col-sm-12 pt-3 pb-3 text-center"> + <button + id="newEventFormSubmit" + type="submit" + class="btn btn-primary w-50" + x-bind:disabled="submitting" + >Create</button> + </div> + </div> + </form> </div> <div id="importEventFormContainer"> @@ -36,34 +49,11 @@ </div> <script> - $.validate({ - lang: 'en', - errorElementClass: "is-invalid", - errorMessageClass: "text-danger", - successElementClass: "is-valid" - }); $(document).ready(function(){ if ($('#icsImportControl')[0].files[0] != null){ var file = $('#icsImportControl')[0].files[0].name; $('#icsImportControl').next('label').html('<i class="far fa-file-alt"></i> ' + file); } - $('#eventStart').datepicker({ - language: 'en', - minDate: new Date(), - timepicker: true, - dateFormat: 'd MM yyyy', - dateTimeSeparator: ', ', - onSelect: function(formattedDate, rawDate){ - $('#eventEnd').datepicker().data('datepicker').update('minDate', rawDate).clear(); - } - }); - $('#eventEnd').datepicker({ - language: 'en', - minDate: new Date(), - timepicker: true, - dateFormat: 'd MM yyyy', - dateTimeSeparator: ', ' - }); $("#showNewEventFormButton").click(function(){ $("button").removeClass("active"); $("#showImportEventFormButton #showNewEventGroupFormButton").removeClass("active"); @@ -109,3 +99,102 @@ }); }) </script> + +<script type="text/javascript" src="/js/generate-timezones.js"></script> + +<script> + $(document).ready(function() { + $.uploadPreview({ + input_field: "#image-upload", + preview_box: "#image-preview", + label_field: "#image-label", + label_default: "Choose file", + label_selected: "Change file", + no_label: false + }); + autosize($('textarea')); + }); + + function newEventForm() { + return { + data: { + eventName: '', + eventLocation: '', + eventStart: '', + eventEnd: '', + timezone: '', + eventDescription: '', + eventURL: '', + hostName: '', + creatorEmail: '', + eventGroupID: '', + eventGroupEditToken: '', + interactionCheckbox: false, + joinCheckbox: false, + maxAttendeesCheckbox: false, + maxAttendees: '', + }, + errors: [], + submitting: false, + init() { + // Set up Select2 + this.select2 = $(this.$refs.timezone).select2(); + this.select2.on("select2:select", (event) => { + this.data.timezone = event.target.value; + }); + this.data.timezone = this.select2.val(); + // Reset checkboxes + this.data.eventGroupCheckbox = false; + this.data.interactionCheckbox = false; + this.data.joinCheckbox = false; + this.data.maxAttendeesCheckbox = false; + }, + async submitForm() { + this.submitting = true; + this.errors = []; + const formData = new FormData(); + for (const key in this.data) { + if (this.data.hasOwnProperty(key)) { + formData.append(key, this.data[key]); + } + } + formData.append("imageUpload", this.$refs.eventImageUpload.files[0]); + try { + const response = await fetch("/event", { + method: "POST", + body: formData, + }); + this.submitting = false; + if (!response.ok) { + if (response.status !== 400) { + this.errors = [ + { + message: "An unexpected error has occurred. Please try again later.", + } + ]; + return; + } + const json = await response.json(); + this.errors = json.errors; + // Set Bootstrap validation classes using 'field' property + $("input, textarea").removeClass("is-invalid"); + this.errors.forEach((error) => { + $(`#${error.field}`).addClass("is-invalid"); + }); + return; + } + const json = await response.json(); + window.location.assign(json.url); + } catch (error) { + console.log(error); + this.errors = [ + { + message: "An unexpected error has occurred. Please try again later.", + } + ]; + this.submitting = false; + } + }, + } + } +</script>
\ No newline at end of file diff --git a/views/partials/editeventmodal.handlebars b/views/partials/editeventmodal.handlebars index b4b0ea6..2572cbb 100644 --- a/views/partials/editeventmodal.handlebars +++ b/views/partials/editeventmodal.handlebars @@ -8,140 +8,21 @@ </button> </div> <div class="modal-body"> - <form id="editEventForm" action="/editevent/{{eventData.id}}/{{eventData.editToken}}" method="post" - enctype="multipart/form-data" autocomplete="off"> - <div class="form-group"> - <label for="eventName" class="col-form-label">Event name</label> - <input type="text" class="form-control" id="eventName" name="eventName" - placeholder="Make it snappy." value="{{eventData.name}}" data-validation="required length" - data-validation-length="3-120"> - </div> - <div class="form-group"> - <label for="eventLocation" class="col-form-label">Location</label> - <input type="text" class="form-control" id="eventLocation" name="eventLocation" - placeholder="Be specific." value="{{eventData.location}}" data-validation="required length" - data-validation-length="3-120"> - </div> - <div class="form-group"> - <label for="eventStart" class="col-form-label">Starts</label> - <input readonly type="text" class="form-control" id="eventStart" name="eventStart" value="" - data-validation="required"> - </div> - <div class="form-group"> - <label for="eventEnd" class="col-form-label">Ends</label> - <input readonly type="text" class="form-control" id="eventEnd" name="eventEnd" value="" - data-validation="required"> - </div> - <div class="form-group"> - <label for="timezone" class="col-form-label">Timezone</label> - <select class="select2" id="timezone" name="timezone"></select> - </div> - <div class="form-group"> - <label for="eventDescription" class="col-form-label">Description</label> - <textarea class="form-control" id="eventDescription" name="eventDescription" - data-validation="required">{{eventData.description}}</textarea> - <small class="form-text"><a href="https://commonmark.org/help/">Markdown</a> formatting - supported.</small> - </div> - <div class="form-group"> - <label for="eventURL" class="col-form-label">Link</label> - <input type="url" class="form-control" id="eventURL" name="eventURL" value="{{eventData.url}}" - placeholder="For tickets or another event page (optional)." data-validation="url" - data-validation-optional="true"> - </div> - <div class="form-group"> - <label for="hostName" class="col-form-label">Host name</label> - <input type="text" class="form-control" id="hostName" name="hostName" - placeholder="Will be shown on the event page (optional)." value="{{eventData.hostName}}" - data-validation="length" data-validation-length="3-120" data-validation-optional="true"> - </div> - <div class="form-group"> - <label for="eventImage" class="col-form-label">Cover image</label> - <div class="image-preview" id="image-preview"> - <label for="image-upload" id="image-label">Choose file</label> - <input type="file" name="imageUpload" id="image-upload" /> - </div> - <small class="form-text">Recommended dimensions (w x h): 920px by 300px.</small> - {{#if eventData.image}} - <button type="button" class="btn btn-danger" id="deleteImage">Delete image</button> - {{/if}} - </div> - <div class="form-group"> - <div class="mb-2">Options</div> - <div class="form-check"> - <input class="form-check-input" type="checkbox" id="eventGroupCheckbox" - name="eventGroupCheckbox" {{#if eventData.eventGroup}}checked{{/if}}> - <label class="form-check-label" for="eventGroupCheckbox"> - This event is part of an event group - </label> - </div> - <div class="card text-white bg-secondary my-2" id="eventGroupData" {{#if eventData.eventGroup}}style="display:flex" {{/if}}> - <div class="card-header"> - <strong>Link this event to an event group</strong> - </div> - <div class="card-body"> - <div class="form-group"> - <label for="eventGroupID" class="form-label">Event group ID</label> - <div class="form-group"> - <input type="text" class="form-control" id="eventGroupID" name="eventGroupID" - placeholder="" data-validation-optional="true" value="{{eventData.eventGroup.id}}"> - <small class="form-text">You can find this short string of characters in the - event group's link, in your confirmation email, or on the event group's - page.</small> - </div> - </div> - <div class="form-group"> - <label for="eventGroupEditToken" class="form-label">Event group secret - editing code</label> - <div class="form-group"> - <input type="text" class="form-control" id="eventGroupEditToken" - name="eventGroupEditToken" placeholder="" data-validation-optional="true" value="{{eventData.eventGroup.editToken}}"> - <small class="form-text">You can find this long string of characters in the - confirmation email you received when you created the event group.</small> - </div> - </div> - </div> - </div> - <div class="form-check"> - <input class="form-check-input" type="checkbox" id="interactionCheckbox" - name="interactionCheckbox" {{#if eventData.usersCanComment}}checked{{/if}}> - <label class="form-check-label" for="interactionCheckbox"> - Users can post comments on this event - </label> - </div> - <div class="form-check"> - <input class="form-check-input {{#unless eventData.usersCanAttend}}unchecked{{/unless}}" - type="checkbox" id="joinCheckbox" name="joinCheckbox" - {{#if eventData.usersCanAttend}}checked{{/if}}> - <label class="form-check-label" for="joinCheckbox"> - Users can mark themselves as attending this event - </label> - </div> - <div class="form-check" id="maxAttendeesCheckboxContainer" - {{#if eventData.maxAttendees}}style="display:flex" {{/if}}> - <input class="form-check-input" type="checkbox" id="maxAttendeesCheckbox" - name="maxAttendeesCheckbox" {{#if eventData.maxAttendees}}checked{{/if}}> - <label class="form-check-label" for="maxAttendeesCheckbox"> - Set a limit on the maximum number of attendees - </label> - </div> - </div> - <div class="form-group" id="maxAttendeesContainer" - {{#if eventData.maxAttendees}}style="display:flex" {{/if}}> - <label for="maxAttendees" class="col-form-label">Attendee limit</label> - <input type="number" class="form-control" id="maxAttendees" name="maxAttendees" - placeholder="Enter a number." data-validation="number" data-validation-optional="true" - value="{{eventData.maxAttendees}}"> - </div> + <form id="editEventForm" enctype="multipart/form-data" x-data="editEventForm()" x-init="init()" + @submit.prevent="submitForm"> - <div class="form-group"> - <div class="card border-danger mb-3"> - <div class="card-header text-danger">Delete this event</div> - <div class="card-body text-danger"> - <button type="button" id="deleteEvent" class="btn btn-danger" data-toggle="modal" data-target="#deleteModal" data-event-id="{{eventData.id}}"><i class="fas fa-trash"></i> Delete</button> + {{> eventForm }} + + <div class="form-group"> + <div class="card border-danger mb-3"> + <div class="card-header text-danger">Delete this event</div> + <div class="card-body text-danger"> + <button type="button" id="deleteEvent" class="btn btn-danger" data-toggle="modal" + data-target="#deleteModal" data-event-id="{{eventData.id}}"><i class="fas fa-trash"></i> + Delete</button> + </div> </div> </div> - </div> </div> <div class="modal-footer"> <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button> @@ -153,13 +34,116 @@ </div> <script> -$('#deleteImage').click(function() { - $.post('/deleteimage/{{eventData.id}}/{{eventData.editToken}}', function(response) { - if (response === "Success") { - location.reload(); - } else { - alert(response); - } - }); -}) + $('#deleteImage').click(function () { + $.post('/deleteimage/{{eventData.id}}/{{eventData.editToken}}', function (response) { + if (response === "Success") { + location.reload(); + } else { + alert(response); + } + }); + }) </script> + +<script type="text/javascript" src="/js/generate-timezones.js"></script> + +<script> + $(document).ready(function () { + $.uploadPreview({ + input_field: "#image-upload", + preview_box: "#image-preview", + label_field: "#image-label", + label_default: "Choose file", + label_selected: "Change file", + no_label: false + }); + autosize($('textarea')); + $("#image-preview").css("background-image", "url('/events/{{eventData.image}}')"); + $("#image-preview").css("background-size", "cover"); + $("#image-preview").css("background-position", "center center"); + $("#timezone").val('{{eventData.timezone}}').trigger('change'); + }); + + function editEventForm() { + return { + data: { + eventName: `{{{eventData.name}}}`, + eventLocation: `{{{ eventData.location }}}`, + eventStart: `{{{ parsedStartForDateInput }}}`, + eventEnd: `{{{ parsedEndForDateInput }}}`, + timezone: `{{{ eventData.timezone }}}`, + eventDescription: `{{{ eventData.description }}}`, + eventURL: `{{{ eventData.url }}}`, + hostName: `{{{ eventData.hostName }}}`, + creatorEmail: `{{{ eventData.creatorEmail }}}`, + eventGroupID: `{{{ eventData.eventGroupID }}}`, + eventGroupEditToken: `{{{ eventData.eventGroupEditToken }}}`, + interactionCheckbox: {{{ eventData.usersCanComment }}}, + joinCheckbox: {{{ eventData.usersCanAttend }}}, + maxAttendeesCheckbox: {{#if eventData.maxAttendees}}true{{else}}false{{/if}}, + maxAttendees: `{{{ eventData.maxAttendees }}}`, + }, + errors: [], + submitting: false, + init() { + // Set up Select2 + this.select2 = $(this.$refs.timezone).select2(); + this.select2.on("select2:select", (event) => { + this.data.timezone = event.target.value; + }); + this.data.timezone = this.select2.val(); + /* Set up checkboxes */ + this.data.eventGroupCheckbox = {{#if eventData.eventGroupID}}true{{else}}false{{/if}}; + this.data.interactionCheckbox = {{eventData.usersCanComment}}; + this.data.joinCheckbox = {{eventData.usersCanAttend}}; + this.data.maxAttendeesCheckbox = {{#if eventData.maxAttendees}}true{{else}}false{{/if}}; + }, + async submitForm() { + this.submitting = true; + this.errors = []; + const formData = new FormData(); + for (const key in this.data) { + if (this.data.hasOwnProperty(key)) { + formData.append(key, this.data[key]); + } + } + formData.append("imageUpload", this.$refs.eventImageUpload.files[0]); + formData.append("editToken", '{{eventData.editToken}}'); + try { + const response = await fetch("/event/{{eventData.id}}", { + method: "PUT", + body: formData, + }); + this.submitting = false; + if (!response.ok) { + if (response.status !== 400) { + this.errors = [ + { + message: "An unexpected error has occurred. Please try again later.", + } + ]; + return; + } + const json = await response.json(); + this.errors = json.errors; + // Set Bootstrap validation classes using 'field' property + $("input, textarea").removeClass("is-invalid"); + this.errors.forEach((error) => { + $(`#${error.field}`).addClass("is-invalid"); + }); + return; + } + window.location.reload(); + } catch (error) { + console.log(error); + this.errors = [ + { + message: "An unexpected error has occurred. Please try again later.", + } + ]; + this.submitting = false; + } + }, + } + } +</script>
\ No newline at end of file diff --git a/views/partials/eventForm.handlebars b/views/partials/eventForm.handlebars new file mode 100755 index 0000000..36da7b8 --- /dev/null +++ b/views/partials/eventForm.handlebars @@ -0,0 +1,141 @@ +<div class="form-group row"> + <label for="eventName" class="col-sm-2 col-form-label">Event name</label> + <div class="form-group col-sm-10"> + <input type="text" class="form-control" id="eventName" name="eventName" placeholder="Make it snappy." x-model="data.eventName" > + </div> +</div> +<div class="form-group row"> + <label for="eventLocation" class="col-sm-2 col-form-label">Location</label> + <div class="form-group col-sm-10"> + <input type="text" class="form-control" id="eventLocation" name="eventLocation" placeholder="Be specific." x-model="data.eventLocation"> + </div> +</div> +<div class="form-group row"> + <label for="eventStart" class="col-sm-2 col-form-label">Starts</label> + <div class="form-group col-sm-4"> + <input type="datetime-local" class="form-control" id="eventStart" name="eventStart" x-model="data.eventStart"> + </div> +</div> +<div class="form-group row"> + <label for="eventEnd" class="col-sm-2 col-form-label">Ends</label> + <div class="form-group col-sm-4"> + <input type="datetime-local" class="form-control" id="eventEnd" name="eventEnd" x-model="data.eventEnd"> + </div> +</div> +<div class="form-group row"> + <label for="timezone" class="col-sm-2 col-form-label">Timezone</label> + <div class="form-group col-sm-10"> + <select class="select2" id="timezone" name="timezone" x-ref="timezone"></select> + </div> +</div> +<div class="form-group row"> + <label for="eventDescription" class="col-sm-2 col-form-label">Description</label> + <div class="form-group col-sm-10"> + <textarea class="form-control expand" id="eventDescription" name="eventDescription" placeholder="You can always edit it later." x-model="data.eventDescription" ></textarea> + <small class="form-text"><a href="https://commonmark.org/help/">Markdown</a> formatting supported.</small> + </div> +</div> +<div class="form-group row"> + <label for="eventURL" class="col-sm-2 col-form-label">Link</label> + <div class="form-group col-sm-10"> + <input type="url" class="form-control" id="eventURL" name="eventURL" placeholder="For tickets or another event page (optional)." x-model="data.eventURL" > + </div> +</div> +<div class="form-group row"> + <label for="eventImage" class="col-sm-2 col-form-label">Cover image</label> + <div class="form-group col-sm-10"> + <div class="image-preview" id="image-preview"> + <label for="image-upload" id="image-label">Choose file</label> + <input type="file" name="imageUpload" id="image-upload" accept="image/jpeg,image/gif,image/png" x-ref="eventImageUpload" /> + </div> + <small class="form-text">Recommended dimensions (w x h): 920px by 300px.</small> + {{#if eventData.image}} + <button type="button" class="btn btn-danger" id="deleteImage">Delete image</button> + {{/if}} + </div> +</div> +<div class="form-group row"> + <label for="hostName" class="col-sm-2 col-form-label">Host name</label> + <div class="form-group col-sm-10"> + <input type="text" class="form-control" id="hostName" name="hostName" placeholder="Will be shown on the event page (optional)." x-model="data.hostName" > + </div> +</div> +<div class="form-group row"> + <label for="creatorEmail" class="col-sm-2 col-form-label">Your email</label> + <div class="form-group col-sm-10"> + <input type="email" class="form-control" id="creatorEmail" name="creatorEmail" placeholder="Will not be shown anywhere (optional)" x-model="data.creatorEmail" > + <small class="form-text">If you provide your email, we will send your secret editing password here, and use it to notify you of updates to the event.</small> + </div> +</div> +<div class="form-group row"> + <div class="col-sm-2">Options</div> + <div class="col-sm-10"> + <div class="form-check"> + <input class="form-check-input" type="checkbox" id="eventGroupCheckbox" name="eventGroupCheckbox" x-model="data.eventGroupCheckbox"> + <label class="form-check-label" for="eventGroupCheckbox"> + This event is part of an event group + </label> + </div> + <div class="card my-2" id="eventGroupData" x-show="data.eventGroupCheckbox"> + <div class="card-header"> + <strong>Link this event to an event group</strong> + </div> + <div class="card-body"> + <div class="form-group row"> + <label for="eventGroupID" class="col-12">Event group ID</label> + <div class="form-group col-12"> + <input type="text" class="form-control" id="eventGroupID" name="eventGroupID" placeholder="" x-model="data.eventGroupID" > + <small class="form-text">You can find this short string of characters in the event group's link, in your confirmation email, or on the event group's page.</small> + </div> + </div> + <div class="form-group row"> + <label for="eventGroupEditToken" class="col-12">Event group secret editing code</label> + <div class="form-group col-12"> + <input type="text" class="form-control" id="eventGroupEditToken" name="eventGroupEditToken" placeholder="" x-model="data.eventGroupEditToken" > + <small class="form-text">You can find this long string of characters in the confirmation email you received when you created the event group.</small> + </div> + </div> + </div> + </div> + <div class="form-check"> + <input class="form-check-input" type="checkbox" id="interactionCheckbox" name="interactionCheckbox" x-model="data.interactionCheckbox"> + <label class="form-check-label" for="interactionCheckbox"> + Users can post comments on this event + </label> + </div> + <div class="form-check"> + <input class="form-check-input" type="checkbox" id="joinCheckbox" name="joinCheckbox" x-model="data.joinCheckbox"> + <label class="form-check-label" for="joinCheckbox"> + Users can mark themselves as attending this event + </label> + </div> + <div class="form-check" id="maxAttendeesCheckboxContainer" x-show="data.joinCheckbox"> + <input class="form-check-input" type="checkbox" id="maxAttendeesCheckbox" name="maxAttendeesCheckbox" x-model="data.maxAttendeesCheckbox"> + <label class="form-check-label" for="maxAttendeesCheckbox"> + Set a limit on the maximum number of attendees + </label> + </div> + </div> +</div> +<div class="form-group row" id="maxAttendeesContainer" x-show="data.maxAttendeesCheckbox && data.joinCheckbox"> + <label for="maxAttendees" class="col-sm-2 col-form-label">Attendee limit</label> + <div class="form-group col-sm-10"> + <input type="number" class="form-control" id="maxAttendees" name="maxAttendees" placeholder="Enter a number." x-model="data.maxAttendees" > + </div> +</div> +<div class="form-group row"> + <div class="col-12"> + <div + class="alert alert-danger" + role="alert" + x-show="errors.length > 0" + > + <p><i class="fas fa-exclamation-triangle"></i> Please fix these errors:</p> + <ul> + <template x-for="error in errors"> + <li x-text="error.message"></li> + </template> + </ul> + </div> + </div> +</div> diff --git a/views/partials/neweventform.handlebars b/views/partials/neweventform.handlebars deleted file mode 100755 index 3c7e060..0000000 --- a/views/partials/neweventform.handlebars +++ /dev/null @@ -1,179 +0,0 @@ -<h4 class="mb-2">Create an event</h4> -<form id="newEventForm" action="/newevent" method="post" enctype="multipart/form-data"> - <div class="form-group row"> - <label for="eventName" class="col-sm-2 col-form-label">Event name</label> - <div class="form-group col-sm-10"> - <input type="text" class="form-control" id="eventName" name="eventName" placeholder="Make it snappy." value="{{data.eventName}}" data-validation="required length" data-validation-length="3-120"> - </div> - </div> - <div class="form-group row"> - <label for="eventLocation" class="col-sm-2 col-form-label">Location</label> - <div class="form-group col-sm-10"> - <input type="text" class="form-control" id="eventLocation" name="eventLocation" placeholder="Be specific." value="{{data.eventLocation}}" data-validation="required length" data-validation-length="3-120"> - </div> - </div> - <div class="form-group row"> - <label for="eventStart" class="col-sm-2 col-form-label">Starts</label> - <div class="form-group col-sm-10"> - <input readonly type="text" class="form-control" id="eventStart" name="eventStart" placeholder="Click me!" value="{{data.eventStart}}" data-validation="required"> - </div> - </div> - <div class="form-group row"> - <label for="eventEnd" class="col-sm-2 col-form-label">Ends</label> - <div class="form-group col-sm-10"> - <input readonly type="text" class="form-control" id="eventEnd" name="eventEnd" placeholder="Click me!" value="{{data.eventEnd}}" data-validation="required"> - </div> - </div> - <div class="form-group row"> - <label for="timezone" class="col-sm-2 col-form-label">Timezone</label> - <div class="form-group col-sm-10"> - <select class="select2" id="timezone" name="timezone"></select> - </div> - </div> - <div class="form-group row"> - <label for="eventDescription" class="col-sm-2 col-form-label">Description</label> - <div class="form-group col-sm-10"> - <textarea class="form-control expand" id="eventDescription" name="eventDescription" data-validation="required" placeholder="You can always edit it later."></textarea> - <small class="form-text"><a href="https://commonmark.org/help/">Markdown</a> formatting supported.</small> - </div> - </div> - <div class="form-group row"> - <label for="eventURL" class="col-sm-2 col-form-label">Link</label> - <div class="form-group col-sm-10"> - <input type="url" class="form-control" id="eventURL" name="eventURL" placeholder="For tickets or another event page (optional)." data-validation="url" data-validation-optional="true"> - </div> - </div> - <div class="form-group row"> - <label for="eventImage" class="col-sm-2 col-form-label">Cover image</label> - <div class="form-group col-sm-10"> - <div class="image-preview" id="eventImagePreview"> - <label for="image-upload" id="eventImageLabel">Choose file</label> - <input type="file" name="imageUpload" id="eventImageUpload" accept="image/jpeg,image/gif,image/png" /> - </div> - <small class="form-text">Recommended dimensions (w x h): 920px by 300px.</small> - </div> - </div> - <div class="form-group row"> - <label for="hostName" class="col-sm-2 col-form-label">Host name</label> - <div class="form-group col-sm-10"> - <input type="text" class="form-control" id="hostName" name="hostName" placeholder="Will be shown on the event page (optional)." data-validation="length" data-validation-length="2-60" data-validation-optional="true"> - </div> - </div> - <div class="form-group row"> - <label for="creatorEmail" class="col-sm-2 col-form-label">Your email</label> - <div class="form-group col-sm-10"> - <input type="email" class="form-control" id="creatorEmail" name="creatorEmail" placeholder="We won't spam you <3 (optional)" data-validation="email" data-validation-optional="true"> - <small class="form-text">If you provide your email, we will send your secret editing password here, and use it to notify you of updates to the event.</small> - </div> - </div> - <div class="form-group row"> - <div class="col-sm-2">Options</div> - <div class="col-sm-10"> - <div class="form-check"> - <input class="form-check-input" type="checkbox" id="eventGroupCheckbox" name="eventGroupCheckbox"> - <label class="form-check-label" for="eventGroupCheckbox"> - This event is part of an event group - </label> - </div> - <div class="card text-white bg-secondary my-2" id="eventGroupData"> - <div class="card-header"> - <strong>Link this event to an event group</strong> - </div> - <div class="card-body"> - <div class="form-group row"> - <label for="eventGroupID" class="col-sm-2 col-form-label">Event group ID</label> - <div class="form-group col-sm-10"> - <input type="text" class="form-control" id="eventGroupID" name="eventGroupID" placeholder="" data-validation-optional="true"> - <small class="form-text">You can find this short string of characters in the event group's link, in your confirmation email, or on the event group's page.</small> - </div> - </div> - <div class="form-group row"> - <label for="eventGroupEditToken" class="col-sm-2 col-form-label">Event group secret editing code</label> - <div class="form-group col-sm-10"> - <input type="text" class="form-control" id="eventGroupEditToken" name="eventGroupEditToken" placeholder="" data-validation-optional="true"> - <small class="form-text">You can find this long string of characters in the confirmation email you received when you created the event group.</small> - </div> - </div> - </div> - </div> - <div class="form-check"> - <input class="form-check-input" type="checkbox" id="interactionCheckbox" name="interactionCheckbox"> - <label class="form-check-label" for="interactionCheckbox"> - Users can post comments on this event - </label> - </div> - <div class="form-check"> - <input class="form-check-input" type="checkbox" id="joinCheckbox" name="joinCheckbox"> - <label class="form-check-label" for="joinCheckbox"> - Users can mark themselves as attending this event - </label> - </div> - <div class="form-check" id="maxAttendeesCheckboxContainer"> - <input class="form-check-input" type="checkbox" id="maxAttendeesCheckbox" name="maxAttendeesCheckbox"> - <label class="form-check-label" for="maxAttendeesCheckbox"> - Set a limit on the maximum number of attendees - </label> - </div> - </div> - </div> - <div class="form-group row" id="maxAttendeesContainer"> - <label for="maxAttendees" class="col-sm-2 col-form-label">Attendee limit</label> - <div class="form-group col-sm-10"> - <input type="number" class="form-control" id="maxAttendees" name="maxAttendees" placeholder="Enter a number." data-validation="number" data-validation-optional="true"> - </div> - </div> - <div class="form-group row"> - <div class="col-sm-12 pt-3 pb-3 text-center"> - <button id="newEventFormSubmit" type="submit" class="btn btn-primary w-50">Create</button> - </div> - </div> -</form> - -<script type="text/javascript" src="/js/generate-timezones.js"></script> - -<script> - $(document).ready(function() { - $.uploadPreview({ - input_field: "#eventImageUpload", - preview_box: "#eventImagePreview", - label_field: "#eventImageLabel", - label_default: "Choose file", - label_selected: "Change file", - no_label: false - }); - autosize($('textarea')); - $("#maxAttendeesCheckbox").on("click", function() { - if ($(this).is(':checked')) { - $("#maxAttendeesContainer").slideDown('fast').css("display","flex"); - $("#maxAttendees").attr("data-validation-optional","false"); - } - else { - $("#maxAttendeesContainer").slideUp('fast'); - $("#maxAttendees").attr("data-validation-optional","true").val("").removeClass('is-valid is-invalid'); - } - }); - $("#joinCheckbox").on("click", function() { - if ($(this).is(':checked')) { - $("#maxAttendeesCheckboxContainer").slideDown('fast').css("display","flex"); - } - else { - $("#maxAttendeesCheckboxContainer").slideUp('fast'); - $("#maxAttendeesCheckbox").prop("checked",false); - $("#maxAttendeesContainer").slideUp('fast'); - $("#maxAttendees").attr("data-validation-optional","true").val("").removeClass('is-valid is-invalid'); - } - }); - $("#eventGroupCheckbox").on("click", function() { - if ($(this).is(':checked')) { - $("#eventGroupData").slideDown('fast'); - $("#eventGroupID").removeAttr("data-validation-optional").attr("data-validation","required"); - $("#eventGroupEditToken").removeAttr("data-validation-optional").attr("data-validation","required"); - } - else { - $("#eventGroupData").slideUp('fast'); - $("#eventGroupID").removeAttr("data-validation").attr("data-validation-optional","true").val(""); - $("#eventGroupEditToken").removeAttr("data-validation").attr("data-validation-optional","true").val(""); - } - }); - }); -</script> |