summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRaphael Kabo <raphaelkabo@hey.com>2023-10-09 19:22:39 +0100
committerRaphael Kabo <raphaelkabo@hey.com>2023-10-09 19:22:39 +0100
commit7fe1f42d56edb98875399b1da5e9b7e972209a0d (patch)
tree6f96696b583e4fab1a2d1f54a2f99bcee3267c04
parentdbbb94117c2d6266cfc45a091b4b87012024f788 (diff)
Add known group linker to event form
-rwxr-xr-xpublic/css/style.css41
-rw-r--r--public/images/seigaiha-single.pngbin0 -> 3463 bytes
-rw-r--r--public/js/modules/event-edit.js7
-rw-r--r--public/js/modules/group-linker.js85
-rw-r--r--src/routes/group.ts60
-rwxr-xr-xviews/newevent.handlebars13
-rw-r--r--views/partials/editeventmodal.handlebars12
-rwxr-xr-xviews/partials/eventForm.handlebars36
8 files changed, 243 insertions, 11 deletions
diff --git a/public/css/style.css b/public/css/style.css
index 8e6322e..04d6e97 100755
--- a/public/css/style.css
+++ b/public/css/style.css
@@ -405,3 +405,44 @@ article.static-page header {
margin-bottom: 1rem;
border-bottom: 1px solid #e0e0e0;
}
+
+.card--group-preview {
+ display: grid;
+ grid-template-columns: 60px 1fr;
+ overflow: hidden;
+ gap: 1rem;
+
+ transition: background-color 0.15s;
+}
+
+.card--group-preview:hover {
+ background-color: #f5f5f5;
+}
+
+.card--group-preview img {
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+}
+
+.card--group-preview__text {
+ text-decoration: none;
+ color: #1b1b1b;
+ overflow: hidden;
+ padding-right: 1rem;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+}
+
+.card--group-preview__text strong,
+.card--group-preview__text p {
+ overflow: hidden;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+ margin: 0;
+}
+
+.card--group-preview:hover {
+ text-decoration: none;
+}
diff --git a/public/images/seigaiha-single.png b/public/images/seigaiha-single.png
new file mode 100644
index 0000000..e963ad6
--- /dev/null
+++ b/public/images/seigaiha-single.png
Binary files differ
diff --git a/public/js/modules/event-edit.js b/public/js/modules/event-edit.js
index 65d9889..0a295cb 100644
--- a/public/js/modules/event-edit.js
+++ b/public/js/modules/event-edit.js
@@ -47,6 +47,13 @@ function editEventForm() {
this.data.timezone = event.target.value;
});
this.data.timezone = this.select2.val();
+
+ // Set checkboxes
+ this.data.eventGroupCheckbox = window.eventData.eventGroupID !== "";
+ this.data.interactionCheckbox = window.eventData.usersCanComment;
+ this.data.joinCheckbox = window.eventData.usersCanAttend;
+ this.data.maxAttendeesCheckbox =
+ window.eventData.maxAttendees !== null;
},
async submitForm() {
this.submitting = true;
diff --git a/public/js/modules/group-linker.js b/public/js/modules/group-linker.js
new file mode 100644
index 0000000..ca5e159
--- /dev/null
+++ b/public/js/modules/group-linker.js
@@ -0,0 +1,85 @@
+function eventGroupLinker() {
+ return {
+ data: {
+ eventGroupID: "",
+ eventGroupEditToken: "",
+ groups: [],
+ },
+ async init() {
+ this.$watch("data.eventGroupID", () => {
+ this.$dispatch(
+ "event-group-id-changed",
+ this.data.eventGroupID,
+ );
+ });
+ this.$watch("data.eventGroupEditToken", () => {
+ this.$dispatch(
+ "event-group-edit-token-changed",
+ this.data.eventGroupEditToken,
+ );
+ });
+ if (window.eventData && window.eventData.eventGroupID !== "") {
+ this.data.eventGroupID = window.eventData.eventGroupID;
+ }
+ if (window.eventData && window.eventGroupEditToken !== "") {
+ this.data.eventGroupEditToken =
+ window.eventData.eventGroupEditToken;
+ }
+ try {
+ const editTokens = JSON.parse(
+ localStorage.getItem("editTokens"),
+ );
+ if (!editTokens) {
+ return;
+ }
+ const response = await fetch("/known/groups", {
+ method: "POST",
+ body: JSON.stringify(editTokens),
+ headers: {
+ "Content-Type": "application/json",
+ },
+ });
+ if (!response.ok) {
+ return;
+ }
+ const json = await (await response).json();
+ this.data.groups = json;
+ } catch (e) {
+ return false;
+ }
+ },
+ selectGroup(e) {
+ const group = this.data.groups.find(
+ (group) => group.id === e.target.value,
+ );
+ if (!group) {
+ this.data.eventGroupID = "";
+ this.data.eventGroupEditToken = "";
+ return;
+ }
+ this.data.eventGroupID = group.id;
+ this.data.eventGroupEditToken = group.editToken;
+ },
+ showGroupPreview() {
+ return (
+ this.data.eventGroupID !== "" &&
+ this.data.groups.some(
+ (group) =>
+ group.id === this.data.eventGroupID &&
+ group.editToken === this.data.eventGroupEditToken,
+ )
+ );
+ },
+ groupPreview() {
+ if (!this.showGroupPreview()) {
+ return {};
+ }
+ return this.data.groups.find(
+ (group) => group.id === this.data.eventGroupID,
+ );
+ },
+ resetGroupSelector() {
+ this.$refs.eventGroupSelect.value = "";
+ },
+ };
+}
diff --git a/src/routes/group.ts b/src/routes/group.ts
index 2801248..40dcccb 100644
--- a/src/routes/group.ts
+++ b/src/routes/group.ts
@@ -7,6 +7,8 @@ import Jimp from "jimp";
import { addToLog } from "../helpers.js";
import EventGroup from "../models/EventGroup.js";
import { sendEmailFromTemplate } from "../lib/email.js";
+import { marked } from "marked";
+import { renderPlain } from "../util/markdown.js";
const config = getConfig();
@@ -237,4 +239,62 @@ router.put(
},
);
+// Accepts a JSON object of event/group IDs mapped to edit tokens.
+// Returns an object of basic group data for each of the IDs
+// which are valid groups and have an edit token which matches.
+router.post("/known/groups", async (req: Request, res: Response) => {
+ const known = req.body;
+ if (!known) {
+ return res.status(400).json({
+ errors: [
+ {
+ message: "No known IDs were provided.",
+ },
+ ],
+ });
+ }
+
+ try {
+ const knownIDs = Object.keys(known);
+ const groups = await EventGroup.find({
+ id: { $in: knownIDs },
+ });
+ const knownGroups = groups.filter((group) => {
+ return group.editToken === known[group.id];
+ });
+ const groupData = knownGroups.map((group) => {
+ return {
+ id: group.id,
+ name: group.name,
+ description: marked
+ .parse(group.description, {
+ renderer: renderPlain(),
+ })
+ .split(" ")
+ .splice(0, 40)
+ .join(" ")
+ .trim(),
+ image: group.image,
+ editToken: group.editToken,
+ url: `/group/${group.id}`,
+ };
+ });
+ return res.status(200).json(groupData);
+ } catch (err) {
+ console.error(err);
+ addToLog(
+ "getKnownGroups",
+ "error",
+ "Attempt to get known groups failed with error: " + err,
+ );
+ return res.status(500).json({
+ errors: [
+ {
+ message: err,
+ },
+ ],
+ });
+ }
+});
+
export default router;
diff --git a/views/newevent.handlebars b/views/newevent.handlebars
index a3b35b3..d8d2f28 100755
--- a/views/newevent.handlebars
+++ b/views/newevent.handlebars
@@ -19,7 +19,15 @@
<div id="newEventFormContainer">
<h4 class="mb-2">Create an event</h4>
- <form id="newEventForm" enctype="multipart/form-data" x-data="newEventForm()" x-init="init()" @submit.prevent="submitForm">
+ <form
+ id="newEventForm"
+ enctype="multipart/form-data"
+ x-data="newEventForm()"
+ x-init="init()"
+ @submit.prevent="submitForm"
+ @event-group-id-changed="data.eventGroupID = $event.detail"
+ @event-group-edit-token-changed="data.eventGroupEditToken = $event.detail"
+ >
{{>eventForm}}
<div class="form-group row">
<div class="col-sm-12 pt-3 pb-3 text-center">
@@ -55,4 +63,5 @@
</article>
<script src="/js/generate-timezones.js"></script>
-<script src="/js/modules/new.js"></script> \ No newline at end of file
+<script src="/js/modules/new.js"></script>
+<script src="/js/modules/group-linker.js"></script> \ No newline at end of file
diff --git a/views/partials/editeventmodal.handlebars b/views/partials/editeventmodal.handlebars
index a36cd98..a9fe626 100644
--- a/views/partials/editeventmodal.handlebars
+++ b/views/partials/editeventmodal.handlebars
@@ -8,8 +8,15 @@
</button>
</div>
<div class="modal-body">
- <form id="editEventForm" enctype="multipart/form-data" x-data="editEventForm()" x-init="init()"
- @submit.prevent="submitForm">
+ <form
+ id="editEventForm"
+ enctype="multipart/form-data"
+ x-data="editEventForm()"
+ x-init="init()"
+ @submit.prevent="submitForm"
+ @event-group-id-changed="data.eventGroupID = $event.detail"
+ @event-group-edit-token-changed="data.eventGroupEditToken = $event.detail"
+ >
{{> eventForm }}
@@ -47,3 +54,4 @@
<script type="text/javascript" src="/js/generate-timezones.js"></script>
<script type="text/javascript" src="/js/modules/event-edit.js"></script>
+<script src="/js/modules/group-linker.js"></script>
diff --git a/views/partials/eventForm.handlebars b/views/partials/eventForm.handlebars
index 93d679d..49c0f86 100755
--- a/views/partials/eventForm.handlebars
+++ b/views/partials/eventForm.handlebars
@@ -80,18 +80,40 @@
<div class="card-header">
<strong>Link this event to an event group</strong>
</div>
- <div class="card-body">
+ <div class="card-body" x-data="eventGroupLinker()">
+ <div class="form-group-label" x-show="data.groups.length > 0">
+ <label>Choose a group you've edited before</label>
+ </div>
+ <div class="form-group" x-show="data.groups.length > 0">
+ <select x-ref="eventGroupSelect" id="eventGroupSelect" name="eventGroupSelect" class="form-control" x-on:change="selectGroup">
+ <option value="">Choose a group</option>
+ <template x-for="group in data.groups">
+ <option :value="group.id" x-text="group.name"></option>
+ </template>
+ </select>
+ </div>
+ <a class="card shadow-sm card--group-preview mb-3" x-show="showGroupPreview()" x-bind:href="groupPreview().url" target="_blank">
+ <img :src="'/events/' + groupPreview().image" x-show="groupPreview().image"/>
+ <img src="/images/seigaiha-single.png" x-show="!groupPreview().image"/>
+ <div class="card--group-preview__text">
+ <strong x-text="groupPreview().name"></strong>
+ <p x-text="groupPreview().description"></p>
+ </div>
+ </a>
+ <div class="alert alert-info text-center" role="alert" x-show="data.groups.length > 0">
+ <i class="fas fa-info-circle"></i> You can also enter the group ID and secret editing code manually.
+ </div>
<div class="form-group">
- <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" >
+ <label for="eventGroupID">Event group ID</label>
+ <div class="form-group">
+ <input type="text" class="form-control" id="eventGroupID" name="eventGroupID" x-model="data.eventGroupID" x-on:input="resetGroupSelector">
<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="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" >
+ <label for="eventGroupEditToken">Event group secret editing code</label>
+ <div class="form-group">
+ <input type="text" class="form-control" id="eventGroupEditToken" name="eventGroupEditToken" x-model="data.eventGroupEditToken" x-on:input="resetGroupSelector">
<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>