From d5148f8c485fdfde17a3b6ac8c3dd7b67b1211a9 Mon Sep 17 00:00:00 2001 From: alex Date: Sun, 4 Feb 2024 22:52:57 +0100 Subject: [PATCH] share calendar --- public/locales/de/translation.json | 14 ++- public/locales/en/translation.json | 14 ++- src/Pages/Store/Calendar/index.js | 158 +++++++++++++++++++++++++++-- src/utils.js | 2 + 4 files changed, 180 insertions(+), 8 deletions(-) diff --git a/public/locales/de/translation.json b/public/locales/de/translation.json index 461d306..3e75bac 100644 --- a/public/locales/de/translation.json +++ b/public/locales/de/translation.json @@ -269,7 +269,19 @@ "checkboxDeleteCalendars": "Kalender für Öffnungszeiten und Termine löschen (Alle Termine werden gelöscht und können nicht wiederhergestellt werden)", "button": "Google Kalender trennen" }, - "calendarFrameCustomerView": "Terminkalenderansicht der Kunden" + "calendarFrameCustomerView": "Terminkalenderansicht der Kunden", + "modalShareCalendarLink": { + "title": "Kalender-Link teilen", + "shareButtons": { + "emailSubject": "Buchen Sie einen Termin bei uns", + "emailBody": "Hallo,\n\n nutzen Sie den folgenden Link, um unseren Kalender einzusehen und einen Termin zu buchen.\n\n{{link}}\n\nMit freundlichen Grüßen\n\n{{username}}", + "whatsAppBody": "Hallo, nutzen Sie den folgenden Link, um unseren Kalender einzusehen und einen Termin zu buchen.\n\n{{link}}\n\nMit freundlichen Grüßen\n\n{{username}}" + }, + "info": "Geben Sie den folgenden Link an Ihre Kunden weiter, damit diese Ihren Kalender einsehen und Termine buchen können.", + "bookingPageLink": "Link zur Buchungsseite", + "embed": "Einbetten", + "embedInfo": "Binden Sie den Kalender mit folgendem Code in Ihre Website ein." + } }, "storeSettings": { "pageTitle": "Einstellungen" diff --git a/public/locales/en/translation.json b/public/locales/en/translation.json index 1162497..39065d2 100644 --- a/public/locales/en/translation.json +++ b/public/locales/en/translation.json @@ -272,7 +272,19 @@ "checkboxDeleteCalendars": "Delete calendar for opening hours and appointments (all appointments are deleted and cannot be restored)", "button": "Unlink Google Calendar" }, - "calendarFrameCustomerView": "Appointment diary view of customers" + "calendarFrameCustomerView": "Appointment diary view of customers", + "modalShareCalendarLink": { + "title": "Share calendar link", + "shareButtons": { + "emailSubject": "Book an appointment with us", + "emailBody": "Hello,\n\nuse the following link to view our calendar and book an appointment.\n\n{{link}}\n\nBest regards\n\n{{username}}", + "whatsAppBody": "Hello, use the following link to view our calendar and book an appointment:\n\n{{link}}\n\nBest regards\n\n{{username}}" + }, + "info": "Share the following link with your customers to allow them to view your calendar and book appointments.", + "bookingPageLink": "Booking page link", + "embed": "Embed", + "embedInfo": "Embed the calendar on your website with the following code." + } }, "storeSettings": { "pageTitle": "Settings" diff --git a/src/Pages/Store/Calendar/index.js b/src/Pages/Store/Calendar/index.js index dcbf944..889cc24 100644 --- a/src/Pages/Store/Calendar/index.js +++ b/src/Pages/Store/Calendar/index.js @@ -2,8 +2,10 @@ import { Button, Card, Col, + Flex, Form, Grid, + QRCode, Result, Row, Space, @@ -34,8 +36,17 @@ import { } from "../../../Components/MyRequestStateItem"; import MyModal, { MyModalCloseConfirmButtonFooter, + MyModalOnlyCloseButtonFooter, } from "../../../Components/MyModal"; import { useParams } from "react-router-dom"; +import { + DownloadOutlined, + MailOutlined, + ShareAltOutlined, + WhatsAppOutlined, +} from "@ant-design/icons"; +import Paragraph from "antd/es/typography/Paragraph"; +import { useSideBarContext } from "../../../Contexts/SideBarContext"; const { useBreakpoint } = Grid; @@ -191,20 +202,22 @@ export default function StoreCalendar() { - - - + ); } -function CalendarFrame({ storeId }) { +function CalendarFrameCard({ storeId }) { + const { t } = useTranslation(); const [isLoading, setIsLoading] = useState(true); return ( - <> + } + > {isLoading && (
+ + ); +} + +function ModalShareCalendarLink({ storeId }) { + const { t } = useTranslation(); + + const [isModalOpen, setIsModalOpen] = useState(false); + const sideBarContext = useSideBarContext(); + + const handleModalClose = () => setIsModalOpen(false); + + const embedPreContent = ` + +`; + + const downloadQRCode = () => { + const canvas = document + .getElementById("calendar-qrcode") + ?.querySelector("canvas"); + if (canvas) { + const url = canvas.toDataURL(); + const a = document.createElement("a"); + a.download = "QRCode.png"; + a.href = url; + document.body.appendChild(a); + a.click(); + document.body.removeChild(a); + } + }; + + return ( + <> + setIsModalOpen(true)} /> + + } + > + + + window.open( + `mailto:?subject=${t( + "calendar.modalShareCalendarLink.shareButtons.emailSubject" + )}&body=${encodeURIComponent( + t("calendar.modalShareCalendarLink.shareButtons.emailBody", { + link: `${Constants.EMBED_CALENDAR_ADDRESS}${storeId}`, + username: sideBarContext.username, + }) + )}`, + "_self" + ) + } + /> + + window.open( + `https://web.whatsapp.com/send?text=${encodeURIComponent( + t( + "calendar.modalShareCalendarLink.shareButtons.whatsAppBody", + { + link: `${Constants.EMBED_CALENDAR_ADDRESS}${storeId}`, + username: sideBarContext.username, + } + ) + )}` + ) + } + /> + + +
+ +
+ + + + {t("calendar.modalShareCalendarLink.info")} + + + +
+              {`${Constants.EMBED_CALENDAR_ADDRESS}${storeId}`}
+            
+
+ + + {t("calendar.modalShareCalendarLink.embed")} + + + + {t("calendar.modalShareCalendarLink.embedInfo")} + + + +
{embedPreContent}
+
+
+
); } @@ -301,7 +447,7 @@ function CardPersonalCalendarSettings({ settings }) { t: t, }) .then(() => setRequestState(RequestState.SUCCESS)) - .catch((errStatus) => setRequestState(RequestState.FAILED)); + .catch(() => setRequestState(RequestState.FAILED)); }, 500); }, [usingPrimaryCalendar, maxFutureBookingDays, minEarliestBookingTime]); diff --git a/src/utils.js b/src/utils.js index 40bb38e..b5f06d9 100644 --- a/src/utils.js +++ b/src/utils.js @@ -34,6 +34,8 @@ export const Constants = { //STATIC_CONTENT_ADDRESS: staticContentAddress, // WS_ADDRESS: wsAddress, EMBED_CALENDAR_ADDRESS: "https://calendar.ex.umbach.dev/embed/?id=", + EMBED_CALENDAR_SCRIPT_ADDRESS: + "https://calendar.ex.umbach.dev/embedPopup/script.js", ROUTE_PATHS: { AUTHENTICATION: { LOGIN: "/login",