diff --git a/src/assets/img/icons/Google.svg b/src/assets/img/icons/Google.svg new file mode 100644 index 000000000..606351ec9 --- /dev/null +++ b/src/assets/img/icons/Google.svg @@ -0,0 +1,14 @@ + diff --git a/src/assets/img/icons/Outlook.com.svg b/src/assets/img/icons/Outlook.com.svg new file mode 100644 index 000000000..467b585ac --- /dev/null +++ b/src/assets/img/icons/Outlook.com.svg @@ -0,0 +1,16 @@ + diff --git a/src/assets/img/icons/Outlook.svg b/src/assets/img/icons/Outlook.svg new file mode 100644 index 000000000..f974fb13a --- /dev/null +++ b/src/assets/img/icons/Outlook.svg @@ -0,0 +1,16 @@ + diff --git a/src/assets/img/icons/Yahoo.svg b/src/assets/img/icons/Yahoo.svg new file mode 100644 index 000000000..0206eccbb --- /dev/null +++ b/src/assets/img/icons/Yahoo.svg @@ -0,0 +1,13 @@ + diff --git a/src/assets/img/icons/iCal.svg b/src/assets/img/icons/iCal.svg new file mode 100644 index 000000000..399bcdea0 --- /dev/null +++ b/src/assets/img/icons/iCal.svg @@ -0,0 +1,11 @@ + diff --git a/src/constants/calendar-options.js b/src/constants/calendar-options.js new file mode 100644 index 000000000..c87a85b18 --- /dev/null +++ b/src/constants/calendar-options.js @@ -0,0 +1,8 @@ +const calendarOptions = { + ICAL: "iCal", + GOOGLE: "Google", + OUTLOOK: "Outlook", + OUTLOOKCOM: "Outlook.com", + YAHOO: "Yahoo", +}; +export { calendarOptions }; diff --git a/src/constants/calendar-status.js b/src/constants/calendar-status.js new file mode 100644 index 000000000..38cf23467 --- /dev/null +++ b/src/constants/calendar-status.js @@ -0,0 +1,7 @@ +const calendarStatus = { + FREE: "Free", + BUSY: "Busy", + TENTATIVE: "Tentative", + OUT_OF_THE_OFFICE: "OutOfTheOffice", +}; +export { calendarStatus }; diff --git a/src/helpers/add-to-calendar-helper.js b/src/helpers/add-to-calendar-helper.js new file mode 100644 index 000000000..36c700cb3 --- /dev/null +++ b/src/helpers/add-to-calendar-helper.js @@ -0,0 +1,76 @@ +import { calendarStatus } from "@/constants/calendar-status"; +import { getDateFormat } from "@/helpers/date-helper"; +export function getCalendarFile(calFile) { + const dateFormat = "yyyyMMddTHHmmss"; + var calEvent = []; + calEvent.push("BEGIN:VCALENDAR"); + calEvent.push("VERSION:2.0"); + calEvent.push("BEGIN:VEVENT"); + calEvent.push("DTSTAMP:" + getDateFormat(new Date(), dateFormat)); + calEvent.push("UID:" + calFile.UniqueId + "@safelite.com"); + calEvent.push("PRODID:noreply@safelite.com"); + switch (calFile.Status) { + case calendarStatus.BUSY: + calEvent.push("X-MICROSOFT-CDO-BUSYSTATUS:BUSY"); + break; + case calendarStatus.FREE: + calEvent.push("TRANSP:TRANSPARENT"); + break; + case calendarStatus.TENTATIVE: + calEvent.push("STATUS:TENTATIVE"); + break; + case calendarStatus.OUT_OF_THE_OFFICE: + calEvent.push("X-MICROSOFT-CDO-BUSYSTATUS:OOF"); + break; + default: + //throw new Exception("Invalid CalendarStatus"); + } + if (calFile.AllDayEvent) { + calEvent.push("DTSTART;VALUE=DATE:" + getDateFormat(calFile.StartDate, dateFormat)); + calEvent.push("DTEND;;VALUE=DATE:" + getDateFormat(calFile.EndDate, dateFormat)); + } else { + calEvent.push("DTSTART:" + getDateFormat(calFile.StartDate, dateFormat)); + calEvent.push("DTEND:" + getDateFormat(calFile.EndDate, dateFormat)); + } + + calEvent.push("SUMMARY:" + ToCalendarFileString(calFile.Subject, " ")); + if (calFile.Location != null && calFile.Location != "") { + calEvent.push("LOCATION:" + ToCalendarFileString(calFile.Location, " ")); + } + if (calFile.Body != null && calFile.Body != "") { + if (calFile.IsHTML) { + calEvent.push("DESCRIPTION:" + ToCalendarFileString(calFile.Body)); + calEvent.push( + "X-ALT-DESC;FMTTYPE=text/html:" + + '' + + "
' + + "" + + ToCalendarFileString(calFile.Body) + + "" + ); + } else { + calEvent.push("DESCRIPTION:" + ToCalendarFileString(calFile.Body)); + } + } + calEvent.push("END:VEVENT"); + calEvent.push("END:VCALENDAR"); + return calEvent.join("\r\n"); +} + +function ToCalendarFileString(str, replacementArg = "
") {
+ return str.replace("\r\n", replacementArg);
+}
+
+export function download(filename, fileBody) {
+ var element = document.createElement("a");
+ element.setAttribute("href", "data:text/plain;charset=utf-8," + encodeURIComponent(fileBody));
+ element.setAttribute("download", filename);
+
+ element.style.display = "none";
+ document.body.appendChild(element);
+
+ element.click();
+
+ document.body.removeChild(element);
+}
diff --git a/src/helpers/date-helper.js b/src/helpers/date-helper.js
index 48b3122ab..d1c9f968b 100644
--- a/src/helpers/date-helper.js
+++ b/src/helpers/date-helper.js
@@ -8,7 +8,6 @@ export function getDateDifferenceInDays(startDate, endDate) {
// To calculate the no. of days between two dates
return Difference_In_Time / (1000 * 3600 * 24);
}
-
export function getFullDayName(date) {
if (date instanceof Date !== true) return;
const days = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
@@ -62,3 +61,67 @@ export function get12HourTimeMobileFormat(time) {
}
return time.join(""); // return adjusted time or original string
}
+export function getDateFormat(date, format) {
+ if (date instanceof Date !== true) return;
+ const year = date.getFullYear();
+ const month = ("0" + (date.getMonth() + 1)).slice(-2);
+ const day = ("0" + date.getDate()).slice(-2);
+ const hour = ("0" + date.getHours()).slice(-2);
+ const minute = ("0" + date.getMinutes()).slice(-2);
+ const second = ("0" + date.getSeconds()).slice(-2);
+ return format
+ .replace("yyyy", year)
+ .replace("MM", month)
+ .replace("dd", day)
+ .replace("hh", hour)
+ .replace("HH", hour)
+ .replace("mm", minute)
+ .replace("ss", second);
+}
+export function calculateDuration(startDate, endDate) {
+ if (startDate instanceof Date !== true) return;
+ if (endDate instanceof Date !== true) return;
+ return convertMsToTime(endDate - startDate);
+}
+export function convertMsToTime(milliseconds) {
+ let seconds = Math.floor(milliseconds / 1000);
+ let minutes = Math.floor(seconds / 60);
+ let hours = Math.floor(minutes / 60);
+
+ seconds = seconds % 60;
+ minutes = minutes % 60;
+ //commenting to get 24 time format
+ //hours = hours % 24;
+
+ return `${padTo2Digits(hours)}${padTo2Digits(minutes)}`;
+}
+export function padTo2Digits(time) {
+ return ("0" + time).slice(-2);
+}
+export function combineDateAndTime(date, time) {
+ var newDate = new Date(date);
+ var timeParts = time.split(":");
+ newDate.setHours(timeParts[0]);
+ newDate.setMinutes(timeParts[1]);
+ return newDate;
+}
+export function addMinutes(date, minutes) {
+ return new Date(date.getTime() + minutes * 60000);
+}
+export function shortTimeString(date) {
+ if (date instanceof Date !== true) return;
+ const hour = ("0" + date.getHours()).slice(-2);
+ const minute = ("0" + date.getMinutes()).slice(-2);
+ //const second = ("0" + date.getSeconds()).slice(-2);
+ let time = hour + ":" + minute;
+ // Check correct time format and split into components
+ time = time.toString().match(/^([01]\d|2[0-3])(:)([0-5]\d)?$/) || [time];
+
+ if (time.length > 1) {
+ // If time format correct
+ time = time.slice(1); // Remove full string match value
+ time[5] = +time[0] < 12 ? " AM" : " PM"; // Set AM/PM
+ time[0] = +time[0] % 12 || 12; // Adjust hours
+ }
+ return time.join(""); // return adjusted time or original string
+}
diff --git a/src/layouts/add-to-calendar/add-to-calendar.spec.js b/src/layouts/add-to-calendar/add-to-calendar.spec.js
new file mode 100644
index 000000000..1bee62c2c
--- /dev/null
+++ b/src/layouts/add-to-calendar/add-to-calendar.spec.js
@@ -0,0 +1,94 @@
+// Components
+import addToCalendar from "@/layouts/add-to-calendar/add-to-calendar.vue";
+
+// Supporting Files
+import { shallowMount } from "@vue/test-utils";
+import { getMountOptions } from "@/helpers/unit-test-helper.js";
+import store from "@/store";
+
+beforeEach(() => {
+ jest.restoreAllMocks();
+ jest.clearAllMocks();
+ store.getters = {
+ order: {
+ schedule: {
+ date: "2019-01-01",
+ startTime: "09:00",
+ endTime: "10:00",
+ routeCode: "000",
+ },
+ lineItems: {
+ glassParts: [
+ {
+ partNumber: "ABC123",
+ },
+ ],
+ supportingItems: [],
+ },
+ serviceLocation: {
+ address: "",
+ address2: null,
+ city: "",
+ state: "AZ",
+ appointmentType: "Inshop",
+ zipCode: "12345",
+ zipCodeCtu: "01234",
+ provider: {
+ providerNumber: "123",
+ address: {
+ streetAddress: "test1",
+ city: "test",
+ state: "AZ",
+ zipCode: "12345",
+ zipCodeCtu: "01234",
+ },
+ },
+ },
+ damage: {
+ isRepair: false,
+ },
+ referralNumber: "1234567",
+ },
+ payment: {
+ isInsurance: true,
+ },
+ lineItems: {
+ glassParts: [],
+ supportingItems: [],
+ },
+ };
+});
+afterEach(() => {
+ store.getters = {};
+ jest.restoreAllMocks();
+ jest.clearAllMocks();
+});
+
+describe("Add-to-calendar methods...", () => {
+ test("Add-to-calendar should trigger openModal method", () => {
+ //Arrange
+ const { wrapper } = setupMocks({});
+
+ //Act
+ wrapper.vm.openCalendarModal();
+
+ //Assert
+ expect(wrapper.vm.$refs.calendarModalQuestion.openModal).toBeCalled();
+ });
+});
+
+function setupMocks({ customMountOptions }) {
+ const mountOptions = getMountOptions({
+ ...customMountOptions,
+ });
+
+ const wrapper = shallowMount(addToCalendar, mountOptions);
+
+ //wrapper.vm.setCmsContent = jest.fn();
+ //wrapper.vm.$refs.datePicker.initializeComponent = jest.fn();
+ //wrapper.vm.$refs.locationAlerts.initializeComponent = jest.fn();
+ //wrapper.vm.$refs.funnelFooter.updateButtonText = jest.fn();
+ wrapper.vm.$refs.calendarModalQuestion.openModal = jest.fn();
+
+ return { wrapper };
+}
diff --git a/src/layouts/add-to-calendar/add-to-calendar.vue b/src/layouts/add-to-calendar/add-to-calendar.vue
new file mode 100644
index 000000000..b0306b5d0
--- /dev/null
+++ b/src/layouts/add-to-calendar/add-to-calendar.vue
@@ -0,0 +1,300 @@
+
+
{{ this.getScheduleDate() }}
{{ this.getScheduleTime() }}
- -