diff --git a/public/css/Cis4/Cis.css b/public/css/Cis4/Cis.css
index 3056d36b6..91807cd02 100644
--- a/public/css/Cis4/Cis.css
+++ b/public/css/Cis4/Cis.css
@@ -33,6 +33,10 @@ html {
background-color: var(--fhc-primary) !important;
}
+.fhc-primary-border-color {
+ border-color: var(--fhc-primary) !important;
+}
+
.fhc-primary-highlight-bg {
background-color: var(--fhc-primary-highlight) !important;
}
@@ -860,4 +864,12 @@ html {
border: 1px solid rgba(0, 0, 0, 0.15);
border-radius: 0.5rem;
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.25);
+}
+
+#coodleParticipantsSearchResults {
+ background-color: var(--fhc-background);
+ border: 1px solid var(--fhc-border);
+}
+.coodleParticipantSearchResult:hover {
+ opacity: 80%;
}
\ No newline at end of file
diff --git a/public/js/components/Cis/Coodle/Components/CoodleSurvey.js b/public/js/components/Cis/Coodle/Components/CoodleSurvey.js
index c772343b9..2e427b374 100644
--- a/public/js/components/Cis/Coodle/Components/CoodleSurvey.js
+++ b/public/js/components/Cis/Coodle/Components/CoodleSurvey.js
@@ -1,14 +1,20 @@
-import CoodleSurveyVotingTable from "./CoodleSurveyVotingTable.js";
+import CoodleSurveyVotingTable from "./CoodleSurvey/CoodleSurveyVotingTable.js";
+import CoodleSurveyCalendar from "./CoodleSurvey/CoodleSurveyCalendar.js";
+import CoodleSurveyParticipants from "./CoodleSurvey/CoodleSurveyParticipants.js";
+import CoodleSurveyDurationSelector from "./CoodleSurvey/CoodleSurveyDurationSelector.js";
+import CoodleSurveyBasicInfo from "./CoodleSurvey/CoodleSurveyBasicInfo.js";
-import {
- formatDate,
- numberPadding,
- addMinutesToDate,
-} from "../../../../helpers/DateHelpers.js";
+import { formatDate, numberPadding } from "../../../../helpers/DateHelpers.js";
export default {
name: "CoodleSurvey",
- components: { CoodleSurveyVotingTable },
+ components: {
+ CoodleSurveyVotingTable,
+ CoodleSurveyCalendar,
+ CoodleSurveyParticipants,
+ CoodleSurveyDurationSelector,
+ CoodleSurveyBasicInfo,
+ },
props: {
survey: { type: Object | null },
uid: { type: String | null },
@@ -75,57 +81,6 @@ export default {
return "New survey";
}
},
- formattedSurveyDescription() {
- return this.$props.survey?.description?.replaceAll("\n", "
");
- },
- formattedSurveyTimeslotDuration() {
- const minutes = this.$props.survey.timeslotDuration % 60;
- const hours = (this.$props.survey.timeslotDuration - minutes) / 60;
- let formattedDuration = hours ? hours + " hr " : "";
- formattedDuration += minutes + " min";
- return formattedDuration;
- },
- formattedSurveyEndsAt() {
- if (this.$props.survey?.endsAt) {
- return formatDate(this.$props.survey.endsAt);
- } else {
- return "";
- }
- },
- formattedSurveyCreatedAt() {
- if (this.$props.survey?.createdAt) {
- return formatDate(this.$props.survey.createdAt);
- } else {
- return "";
- }
- },
- formattedSurveyUpdatedAt() {
- if (this.$props.survey?.updatedAt) {
- return formatDate(this.$props.survey.updatedAt);
- } else {
- return "";
- }
- },
- formattedSurveyCanceledAt() {
- if (this.$props.survey?.canceledAt) {
- return formatDate(this.$props.survey.canceledAt);
- } else {
- return "";
- }
- },
- formattedSurveyCompletedAt() {
- if (this.$props.survey?.completedAt) {
- return formatDate(this.$props.survey.completedAt);
- } else {
- return "";
- }
- },
- surveyCreatorProfileHref() {
- return this.$router.resolve({
- name: "ProfilView",
- params: { uid: this.survey?.creator?.uid },
- }).href;
- },
parsedSelectedTimeslot() {
return this.$props.survey?.selectedTimeslotId
? this.parseTimeslot(
@@ -149,7 +104,7 @@ export default {
},
watch: {
survey: {
- handler() {
+ async handler() {
this.setSurveyFormData();
if (!this.survey?.id) {
this.isEditInProgress = true;
@@ -157,38 +112,52 @@ export default {
},
deep: true,
},
+ isEditInProgress() {
+ if (!this.isEditInProgress) {
+ this.setSurveyFormData();
+ }
+ },
},
methods: {
setSurveyFormData() {
if (this.$props.survey) {
this.surveyFormData = { ...this.$props.survey };
- return;
+ } else {
+ let defaultEndsAtDate = new Date();
+ defaultEndsAtDate.setDate(defaultEndsAtDate.getDate() + 7);
+
+ this.surveyFormData = {
+ id: null,
+ creator: null,
+ title: "",
+ description: "",
+ timeslotDuration: 60,
+ maxSelections: 1,
+ areParticipantsAnonymized: false,
+ areSelectionsAnonymized: false,
+ selectedTimeslot: null,
+ endsAt: defaultEndsAtDate.toISOString().slice(0, 10),
+ completedAt: null,
+ canceledAt: null,
+ updatedAt: null,
+ createdAt: null,
+ timeslots: [],
+ participants: [],
+ };
}
- this.surveyFormData = {
- id: null,
- creator: null,
- title: "",
- description: "",
- timeslotDuration: 60,
- maxSelections: 1,
- areParticipantsAnonymized: false,
- areSelectionsAnonymized: false,
- selectedTimeslot: null,
- endsAt: null, //todo: set to current date + 7
- completedAt: null,
- canceledAt: null,
- updatedAt: null,
- createdAt: null,
- timeslots: [],
- participants: [],
- };
+ this.surveyFormData.participants.forEach(
+ (participant) => {
+ participant.isCalendarShown = false;
+ },
+ );
},
parseTimeslot(timeslot) {
const timeslotStartsAt = new Date(timeslot.startsAt + " UTC");
- const timeslotEndsAt = addMinutesToDate(
- timeslotStartsAt,
- this.$props.survey?.timeslotDuration ?? 0,
+ let timeslotEndsAt = new Date(timeslot.startsAt + " UTC");
+ timeslotEndsAt.setMinutes(
+ timeslotEndsAt.getMinutes() +
+ (this.$props.survey?.timeslotDuration ?? 0),
);
return {
@@ -224,6 +193,10 @@ export default {
console.log("canceling...");
// todo
},
+ submitForm() {
+ console.log("submitting...");
+ // todo
+ },
},
created() {
this.setSurveyFormData();
@@ -269,91 +242,65 @@ export default {
-
+
-
-
- {{ "This survey was completed on " + formattedSurveyCompletedAt + ". " }}
-
- {{
- "The timeslot (((timeslot))) was selected.".replace(
- "(((timeslot)))",
- parsedSelectedTimeslot.weekday +
- " " +
- parsedSelectedTimeslot.fullDate +
- " " +
- parsedSelectedTimeslot.startTime +
- "-" +
- parsedSelectedTimeslot.endTime
- )
- }}
-
- {{ "No timeslot was selected." }}
-
-
- {{ "This survey was canceled on " + formattedSurveyCanceledAt + "." }}
-
-
-
-
-
{{ "Last edited on " + formattedSurveyUpdatedAt }}
-
{{ "Planned to end on " + formattedSurveyEndsAt }}
-
-
-
-
-
-
-
- {{ "Proposed appointment duration: " }}
- {{ formattedSurveyTimeslotDuration }}
-
-
-
-
-
-
-
- {{ "Maximum selectable timeslots: " }}
- {{ $props.survey.maxSelections}}
-
-
-
-
-
-
-
- {{ "Are participants anonymized: " }}
- {{ $props.survey.areParticipantsAnonymized ? "yes" : "no" }}
-
-
-
-
-
-
-
- {{ "Are votes anonymized: " }}
- {{ $props.survey.areSelectionsAnonymized ? "yes" : "no" }}
-
-
-
-
-
`,
diff --git a/public/js/components/Cis/Coodle/Components/CoodleSurvey/CoodleSurveyBasicInfo.js b/public/js/components/Cis/Coodle/Components/CoodleSurvey/CoodleSurveyBasicInfo.js
new file mode 100644
index 000000000..80388a271
--- /dev/null
+++ b/public/js/components/Cis/Coodle/Components/CoodleSurvey/CoodleSurveyBasicInfo.js
@@ -0,0 +1,235 @@
+import { formatDate } from "../../../../../helpers/DateHelpers.js";
+
+export default {
+ name: "CoodleSurveyBasicInfo",
+ props: {
+ survey: Object | null,
+ surveyFormDataModelValue: Object | null,
+ parsedSelectedTimeslot: Object | null,
+ isEditInProgress: Boolean,
+ },
+ emits: ["update:surveyFormDataModelValue"],
+ computed: {
+ formattedSurveyDescription() {
+ return this.$props.survey?.description?.replaceAll("\n", "
");
+ },
+ formattedSurveyTimeslotDuration() {
+ const minutes = this.$props.survey.timeslotDuration % 60;
+ const hours = (this.$props.survey.timeslotDuration - minutes) / 60;
+ let formattedDuration = hours ? hours + " hr " : "";
+ formattedDuration += minutes + " min";
+ return formattedDuration;
+ },
+ formattedSurveyEndsAt() {
+ if (this.$props.survey?.endsAt) {
+ return formatDate(this.$props.survey.endsAt);
+ } else {
+ return "";
+ }
+ },
+ formattedSurveyCreatedAt() {
+ if (this.$props.survey?.createdAt) {
+ return formatDate(this.$props.survey.createdAt);
+ } else {
+ return "";
+ }
+ },
+ formattedSurveyUpdatedAt() {
+ if (this.$props.survey?.updatedAt) {
+ return formatDate(this.$props.survey.updatedAt);
+ } else {
+ return "";
+ }
+ },
+ formattedSurveyCanceledAt() {
+ if (this.$props.survey?.canceledAt) {
+ return formatDate(this.$props.survey.canceledAt);
+ } else {
+ return "";
+ }
+ },
+ formattedSurveyCompletedAt() {
+ if (this.$props.survey?.completedAt) {
+ return formatDate(this.$props.survey.completedAt);
+ } else {
+ return "";
+ }
+ },
+ surveyCreatorProfileHref() {
+ return this.$router.resolve({
+ name: "ProfilView",
+ params: { uid: this.survey?.creator?.uid },
+ }).href;
+ },
+ surveyFormData: {
+ get() {
+ return this.$props.surveyFormDataModelValue;
+ },
+ set(newValue) {
+ this.$emit("update:surveyFormDataModelValue", newValue);
+ },
+ },
+ },
+ template: /*html*/ `
+
+
+
+ {{ "This survey was completed on " + formattedSurveyCompletedAt + ". " }}
+
+ {{
+ "The timeslot (((timeslot))) was selected.".replace(
+ "(((timeslot)))",
+ parsedSelectedTimeslot?.weekday +
+ " " +
+ parsedSelectedTimeslot?.fullDate +
+ " " +
+ parsedSelectedTimeslot?.startTime +
+ "-" +
+ parsedSelectedTimeslot?.endTime
+ )
+ }}
+
+ {{ "No timeslot was selected." }}
+
+
+ {{ "This survey was canceled on " + formattedSurveyCanceledAt + "." }}
+
+
+
+
+
{{ "Last edited on " + formattedSurveyUpdatedAt }}
+
{{ "Planned to end on " + formattedSurveyEndsAt }}
+
+
+
+
+
+
+
+ {{ "Proposed appointment duration: " }}
+ {{ formattedSurveyTimeslotDuration }}
+
+
+
+
+
+
+
+ {{ "Maximum selectable timeslots: " }}
+ {{ $props.survey.maxSelections}}
+
+
+
+
+
+
+
+ {{ "Are participants anonymized: " }}
+ {{ $props.survey.areParticipantsAnonymized ? "yes" : "no" }}
+
+
+
+
+
+
+
+ {{ "Are votes anonymized: " }}
+ {{ $props.survey.areSelectionsAnonymized ? "yes" : "no" }}
+
+
+
+
+
+ {{ "Required inputs are marked with *." }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ `,
+};
diff --git a/public/js/components/Cis/Coodle/Components/CoodleSurvey/CoodleSurveyCalendar.js b/public/js/components/Cis/Coodle/Components/CoodleSurvey/CoodleSurveyCalendar.js
new file mode 100644
index 000000000..5604e05d5
--- /dev/null
+++ b/public/js/components/Cis/Coodle/Components/CoodleSurvey/CoodleSurveyCalendar.js
@@ -0,0 +1,18 @@
+export default {
+ name: "CoodleSurveyCalendar",
+ components: {},
+ props: {},
+ emits: [],
+ data() {
+ return {}
+ },
+ computed: {},
+ watch: {},
+ methods: {},
+ created() {},
+ template: /*html*/ `
+
+ calendar placeholder
+
+ `,
+}
\ No newline at end of file
diff --git a/public/js/components/Cis/Coodle/Components/CoodleSurvey/CoodleSurveyDurationSelector.js b/public/js/components/Cis/Coodle/Components/CoodleSurvey/CoodleSurveyDurationSelector.js
new file mode 100644
index 000000000..d54b80061
--- /dev/null
+++ b/public/js/components/Cis/Coodle/Components/CoodleSurvey/CoodleSurveyDurationSelector.js
@@ -0,0 +1,91 @@
+export default {
+ name: "CoodleSurveyDurationSelector",
+ props: {
+ durationModelValue: Number | null,
+ survey: Object,
+ },
+ emits: ["update:durationModelValue"],
+ data() {
+ return {
+ appointmentDurationPresets: [15, 30, 45, 60, 90, 120],
+ selectedDurationPreset: null,
+ durationCustomInput: null,
+ };
+ },
+ computed: {
+ duration: {
+ get() {
+ return this.$props.durationModelValue;
+ },
+ set(newValue) {
+ this.$emit("update:durationModelValue", newValue);
+ },
+ },
+ },
+ watch: {
+ durationCustomInput() {
+ if (this.durationCustomInput) {
+ this.duration = this.durationCustomInput;
+ this.selectedDurationPreset = null;
+ }
+ },
+ survey: {
+ handler() {
+ this.initializeInputs();
+ },
+ deep: true,
+ },
+ },
+ methods: {
+ selectAppointmentDurationPreset(preset) {
+ this.selectedDurationPreset = preset;
+ this.duration = preset;
+ this.durationCustomInput = null;
+ },
+ initializeInputs() {
+ this.selectedDurationPreset = null;
+ this.durationCustomInput = null;
+ if (this.appointmentDurationPresets.includes(this.duration)) {
+ this.selectedDurationPreset = this.duration;
+ } else {
+ this.durationCustomInput = this.duration;
+ }
+ },
+ },
+ created() {
+ this.initializeInputs();
+ },
+ template: /*html*/ `
+
+
+
+
+
+ {{ durationPreset }}
+
+
{{ "Custom duration: " }}
+
+
+
+
+
+
+ `,
+};
diff --git a/public/js/components/Cis/Coodle/Components/CoodleSurvey/CoodleSurveyParticipants.js b/public/js/components/Cis/Coodle/Components/CoodleSurvey/CoodleSurveyParticipants.js
new file mode 100644
index 000000000..3962d116a
--- /dev/null
+++ b/public/js/components/Cis/Coodle/Components/CoodleSurvey/CoodleSurveyParticipants.js
@@ -0,0 +1,251 @@
+export default {
+ name: "CoodleSurveyParticipants",
+ components: {},
+ props: {
+ participantsModelValue: Array,
+ },
+ emits: ["update:participantsModelValue"],
+ data() {
+ return {
+ searchInput: "",
+ isSearchingForParticipants: false,
+ searchResults: [],
+ areSearchResultsShown: false,
+ // todo: increase depending on feedback
+ warningGroupSize: 5,
+ // todo: remove
+ searchResultsDevExample: [
+ {
+ uid: "ma1000",
+ name: "Test User 10",
+ type: "user",
+ },
+ {
+ uid: "ma1001",
+ name: "Test User 11",
+ type: "user",
+ },
+ {
+ uid: "ma1002",
+ name: "Test User 12",
+ type: "user",
+ },
+ {
+ uid: "ma1003",
+ name: "Test User 13",
+ type: "user",
+ },
+ {
+ uid: "ABC-DEF",
+ name: "ABC-DEF",
+ type: "group",
+ users: [
+ {
+ uid: "ma1003",
+ name: "Test User 13",
+ },
+ {
+ uid: "ma1004",
+ name: "Test User 14",
+ },
+ ],
+ },
+ {
+ uid: "GHI-JKL",
+ name: "GHI-JKL",
+ type: "group",
+ users: [
+ {
+ uid: "ma1004",
+ name: "Test User 14",
+ },
+ {
+ uid: "ma1005",
+ name: "Test User 15",
+ },
+ {
+ uid: "ma1006",
+ name: "Test User 16",
+ },
+ {
+ uid: "ma1007",
+ name: "Test User 17",
+ },
+ {
+ uid: "ma1008",
+ name: "Test User 18",
+ },
+ {
+ uid: "ma1009",
+ name: "Test User 19",
+ },
+ ],
+ },
+ ],
+ };
+ },
+ computed: {
+ participants: {
+ get() {
+ return this.$props.participantsModelValue;
+ },
+ set(newValue) {
+ this.$emit("update:participantsModelValue", newValue);
+ },
+ },
+ },
+ watch: {
+ searchInput() {
+ if (this.searchInput.length >= 2) {
+ this.areSearchResultsShown = true;
+ this.searchParticipants();
+ } else {
+ this.areSearchResultsShown = false;
+ }
+ },
+ },
+ methods: {
+ async hideSearchResults() {
+ // todo: clean up, don't use timeout
+ setTimeout(() => {
+ this.areSearchResultsShown = false;
+ }, 100);
+ },
+ searchParticipants() {
+ this.isSearchingForParticipants = true;
+
+ // todo
+ this.searchResults = this.searchResultsDevExample;
+
+ this.isSearchingForParticipants = false;
+ },
+ selectSearchResult(searchResult) {
+ if (
+ searchResult.type === "group" &&
+ searchResult.users.length > this.warningGroupSize
+ ) {
+ let warningMessage =
+ "Group (((groupName))) contains (((n))) users. Are you sure you want to add all (((n))) users to your survey?";
+ warningMessage = warningMessage.replace(
+ "(((groupName)))",
+ searchResult.name,
+ );
+ warningMessage = warningMessage.replaceAll(
+ "(((n)))",
+ searchResult.users.length,
+ );
+ if (!window.confirm(warningMessage)) {
+ return;
+ }
+ }
+
+ const addedParticipants =
+ searchResult.type === "group"
+ ? searchResult.users
+ : [searchResult];
+ this.addParticipants(addedParticipants);
+ },
+ addParticipants(newParticipants) {
+ newParticipants = newParticipants.filter((newParticipant) => {
+ return !this.participants.some(
+ (existingParticipant) =>
+ existingParticipant.uid === newParticipant.uid,
+ );
+ }).map((newParticipant) => {
+ return {
+ uid: newParticipant.uid,
+ name: newParticipant.name,
+ isCalendarShown: false,
+ }
+ });
+
+ this.participants = this.participants.concat(newParticipants);
+ },
+ removeParticipant(participantToBeRemoved) {
+ this.participants = this.participants.filter(
+ (participant) => participant.uid !== participantToBeRemoved.uid,
+ );
+ },
+ showCalendar(participantForCalendarToBeDisplayed) {
+ this.participants = this.participants.map((participant) => {
+ let updatedParticipant = { ...participant };
+ if (
+ participant.uid === participantForCalendarToBeDisplayed.uid
+ ) {
+ updatedParticipant.isCalendarShown = true;
+ }
+ return updatedParticipant;
+ });
+ },
+ },
+ template: /*html*/ `
+
+
+
+
+
+
+
+
+
+ {{ "No results found!" }}
+
+
+
+
+
+ {{ searchResult.name }}
+
+
+
+
+
+ {{ "No participants added yet!" }}
+
+
+
+
{{ participant.name }}
+
+
+
+
+
+
+
+
+ `,
+};
diff --git a/public/js/components/Cis/Coodle/Components/CoodleSurveyVotingTable.js b/public/js/components/Cis/Coodle/Components/CoodleSurvey/CoodleSurveyVotingTable.js
similarity index 93%
rename from public/js/components/Cis/Coodle/Components/CoodleSurveyVotingTable.js
rename to public/js/components/Cis/Coodle/Components/CoodleSurvey/CoodleSurveyVotingTable.js
index 503bfe4a1..d9f25085a 100644
--- a/public/js/components/Cis/Coodle/Components/CoodleSurveyVotingTable.js
+++ b/public/js/components/Cis/Coodle/Components/CoodleSurvey/CoodleSurveyVotingTable.js
@@ -143,6 +143,7 @@ export default {
},
submitVote() {
// todo
+ console.log("voting...");
},
submitFinalSelection() {
if (!this.$props.survey.id) return;
@@ -153,7 +154,7 @@ export default {
window.alert("You haven't made a selection!");
return;
} else if (this.selectedTimeslotId === "none") {
- selectedTimeslot = "\"No appointment is possible\"";
+ selectedTimeslot = '"No appointment is possible"';
} else {
const selectedTimeslotInfo = this.$props.timeslots.find(
(timeslot) => timeslot.id === this.selectedTimeslotId,
@@ -181,6 +182,37 @@ export default {
) {
return;
}
+
+ let participantsThatHaveNotVoted =
+ this.participantsWithoutAuthUser.reduce((sum, participant) => {
+ return (
+ sum +
+ (!Object.values(participant.selection).filter(
+ (isSelected) => isSelected,
+ ).length
+ ? 1
+ : 0)
+ );
+ }, 0);
+
+ if (
+ !Object.values(this.authUserParticipant.selection).filter(
+ (isSelected) => isSelected,
+ ).length
+ ) {
+ participantsThatHaveNotVoted++;
+ }
+
+ if (participantsThatHaveNotVoted) {
+ if (
+ !window.confirm(
+ "Not all participants have voted. Are you sure you want to proceed?",
+ )
+ ) {
+ return;
+ }
+ }
+
console.log("finalizing...");
// todo
},
diff --git a/public/js/components/Cis/Coodle/Coodle.js b/public/js/components/Cis/Coodle/Coodle.js
index 8a01c466c..6f80640e2 100644
--- a/public/js/components/Cis/Coodle/Coodle.js
+++ b/public/js/components/Cis/Coodle/Coodle.js
@@ -9,8 +9,9 @@ export default {
data() {
return {
uid: null,
- // todo: return view to activeSurveysTable and survey to null
view: "survey",
+ // survey: null,
+ // todo: delete comment after dev
survey: {
id: 1,
creator: {
@@ -19,13 +20,13 @@ export default {
},
title: "Test Meeting",
description:
- "To discuss many important matters. \n Another line of the description.",
+ "To discuss many important matters.\nAnother line of the description.",
timeslotDuration: 75,
maxSelections: 2,
areParticipantsAnonymized: false,
areSelectionsAnonymized: false,
selectedTimeslotId: null,
- endsAt: "2026-06-23 23:30:30",
+ endsAt: "2026-06-23",
completedAt: null,
canceledAt: null,
createdAt: "2026-06-14 23:30:30",
@@ -43,6 +44,14 @@ export default {
id: 3,
startsAt: "2026-06-25 07:00:00",
},
+ {
+ id: 4,
+ startsAt: "2026-06-24 09:00:00",
+ },
+ {
+ id: 5,
+ startsAt: "2026-06-27 12:30:00",
+ },
],
participants: [
{
@@ -57,12 +66,12 @@ export default {
},
{
uid: "ma1436",
- name: "Test User 2",
+ name: "Test Userrr 2",
selection: null,
},
{
uid: "ma1437",
- name: "Test User 3",
+ name: "Test Userrrrr 3",
selection: [2,3],
},
],
@@ -70,6 +79,8 @@ export default {
1: 0,
2: 2,
3: 1,
+ 4: 0,
+ 5: 0,
"none": 1,
},
},
diff --git a/public/js/helpers/DateHelpers.js b/public/js/helpers/DateHelpers.js
index 2114f160b..28e3880c1 100644
--- a/public/js/helpers/DateHelpers.js
+++ b/public/js/helpers/DateHelpers.js
@@ -61,14 +61,3 @@ export function formatDate(d) {
);
}
}
-
-/**
- * adds some number of minutes to a date
- *
- * @param {Date} d - the date to which the minutes are added
- * @param {int} m - number of minutes
- * @returns {Date} updated date
- */
-export function addMinutesToDate(d, m) {
- return new Date(d.getTime() + m * 60000);
-}