diff --git a/apps/scandic-web/app/globals.css b/apps/scandic-web/app/globals.css index dd827f06d..a19cee6ec 100644 --- a/apps/scandic-web/app/globals.css +++ b/apps/scandic-web/app/globals.css @@ -31,6 +31,7 @@ --back-to-top-button: 80; --language-switcher-z-index: 85; --sidepeek-z-index: 100; + --chatbot-z-index: 149; --lightbox-z-index: 150; --default-modal-overlay-z-index: 100; --default-modal-z-index: 101; @@ -73,6 +74,15 @@ body.overflow-hidden { border-width: 0; } +#kindly-chat-api { + z-index: var(--chatbot-z-index); +} + +/* Hide chat widget when booking widget is open */ +body:has([data-booking-widget-open="true"]) #kindly-chat-api { + z-index: -1 !important; +} + @media screen and (min-width: 768px) { :root { --max-width-single-spacing: var(--Layout-Tablet-Margin-Margin-min); diff --git a/apps/scandic-web/components/ChatbotScript/Client.tsx b/apps/scandic-web/components/ChatbotScript/Client.tsx new file mode 100644 index 000000000..84f1c1fd1 --- /dev/null +++ b/apps/scandic-web/components/ChatbotScript/Client.tsx @@ -0,0 +1,54 @@ +"use client" + +import { usePathname, useSearchParams } from "next/navigation" +import Script from "next/script" +import { useEffect } from "react" + +import { shouldShowChatbot } from "@/components/ChatbotScript/utils" +import useLang from "@/hooks/useLang" + +interface ChatbotClientProps { + liveLangs: string[] +} + +export function ChatbotClient({ liveLangs }: ChatbotClientProps) { + const lang = useLang() + const pathname = usePathname() + const searchParams = useSearchParams() + const currentLang = useLang() + const isLive = liveLangs.includes(currentLang) + const shouldShow = + isLive && shouldShowChatbot(pathname, searchParams, currentLang) + + useEffect(() => { + window.kindlyOptions = { + position: { + bottom: "130px", + right: "20px", + }, + } + }, []) + + useEffect(() => { + if (window.kindlyChat) { + if (!shouldShow) { + window.kindlyChat.closeChat() + window.kindlyChat.hideBubble() + } else { + window.kindlyChat.showBubble() + } + } + }, [shouldShow]) + + return ( + + ) +} diff --git a/apps/scandic-web/components/ChatbotScript/RouteChange.tsx b/apps/scandic-web/components/ChatbotScript/RouteChange.tsx deleted file mode 100644 index deba88533..000000000 --- a/apps/scandic-web/components/ChatbotScript/RouteChange.tsx +++ /dev/null @@ -1,34 +0,0 @@ -"use client" - -import { usePathname } from "next/navigation" -import { useEffect } from "react" - -import useLang from "@/hooks/useLang" - -import { CHATBOT_HIDE_ROUTES } from "./constants" - -interface ChatbotRouteChangeProps { - liveLangs: string[] -} - -export function ChatbotRouteChange({ liveLangs }: ChatbotRouteChangeProps) { - const pathName = usePathname() - const currentLang = useLang() - - useEffect(() => { - const isLive = liveLangs.includes(currentLang) - const shouldHideChatbot = CHATBOT_HIDE_ROUTES.some((route) => - pathName.includes(route) - ) - if (window.kindlyChat) { - if (shouldHideChatbot || !isLive) { - window.kindlyChat.closeChat() - window.kindlyChat.hideBubble() - } else { - window.kindlyChat.showBubble() - } - } - }, [pathName, liveLangs, currentLang]) - - return null -} diff --git a/apps/scandic-web/components/ChatbotScript/constants.ts b/apps/scandic-web/components/ChatbotScript/constants.ts index 00d2f51db..17f2f5abe 100644 --- a/apps/scandic-web/components/ChatbotScript/constants.ts +++ b/apps/scandic-web/components/ChatbotScript/constants.ts @@ -1 +1,18 @@ -export const CHATBOT_HIDE_ROUTES = ["/hotelreservation"] +import { Lang } from "@scandic-hotels/common/constants/language" + +export const CHATBOT_SHOW_ROUTES = { + [Lang.en]: [ + "/customer-service", // Customer service pages + "/scandic-friends", // My pages + "/hotels", // Hotel pages + ], + [Lang.sv]: [], + [Lang.no]: [], + [Lang.fi]: [], + [Lang.da]: [], + [Lang.de]: [], +} as const + +export const CHATBOT_HIDE_CONDITIONS = { + searchParams: [{ key: "view", value: "map" }], +} as const diff --git a/apps/scandic-web/components/ChatbotScript/index.tsx b/apps/scandic-web/components/ChatbotScript/index.tsx index 136ab1d68..4756f3a2e 100644 --- a/apps/scandic-web/components/ChatbotScript/index.tsx +++ b/apps/scandic-web/components/ChatbotScript/index.tsx @@ -1,33 +1,9 @@ -import Script from "next/script" - import { env } from "@/env/server" -import { CHATBOT_HIDE_ROUTES } from "@/components/ChatbotScript/constants" -import { ChatbotRouteChange } from "@/components/ChatbotScript/RouteChange" -import { getLang } from "@/i18n/serverContext" -import { getPathname } from "@/utils/getPathname" +import { ChatbotClient } from "@/components/ChatbotScript/Client" export default async function ChatbotScript() { - const lang = await getLang() const liveLangs = env.CHATBOT_LIVE_LANGS - const pathName = await getPathname() - const isLive = liveLangs.includes(lang) - const shouldHideChatbot = CHATBOT_HIDE_ROUTES.some((route) => - pathName.includes(route) - ) - return ( - <> - - - > - ) + return } diff --git a/apps/scandic-web/components/ChatbotScript/utils.ts b/apps/scandic-web/components/ChatbotScript/utils.ts new file mode 100644 index 000000000..2fb484fa5 --- /dev/null +++ b/apps/scandic-web/components/ChatbotScript/utils.ts @@ -0,0 +1,42 @@ +import { + removeMultipleSlashes, + removeTrailingSlash, +} from "@scandic-hotels/common/utils/url" + +import { CHATBOT_HIDE_CONDITIONS, CHATBOT_SHOW_ROUTES } from "./constants" + +import type { Lang } from "@scandic-hotels/common/constants/language" + +export function shouldShowChatbot( + pathname: string, + searchParams: URLSearchParams | null, + lang: Lang +): boolean { + const cleanPathname = removeTrailingSlash(removeMultipleSlashes(pathname)) + const isOnShowRoute = CHATBOT_SHOW_ROUTES[lang].some((route) => { + const fullRoute = removeTrailingSlash( + removeMultipleSlashes(`/${lang}${route}`) + ) + return cleanPathname.startsWith(fullRoute) + }) + + const isOnStartPage = cleanPathname === `/${lang}` + + if (!isOnShowRoute && !isOnStartPage) { + return false + } + + if (searchParams) { + const shouldHideOnSearchParams = CHATBOT_HIDE_CONDITIONS.searchParams.some( + ({ key, value }) => { + const paramValue = searchParams.get(key) + return paramValue === value + } + ) + if (shouldHideOnSearchParams) { + return false + } + } + + return true +} diff --git a/apps/scandic-web/types/window.d.ts b/apps/scandic-web/types/window.d.ts index 316f310ff..25a529c2f 100644 --- a/apps/scandic-web/types/window.d.ts +++ b/apps/scandic-web/types/window.d.ts @@ -23,4 +23,10 @@ interface Window { showChat: () => void hideBubble: () => void } + kindlyOptions: { + position?: { + bottom?: string + right?: string + } + } } diff --git a/packages/booking-flow/global.d.ts b/packages/booking-flow/global.d.ts index b9b55f677..a9369ce0a 100644 --- a/packages/booking-flow/global.d.ts +++ b/packages/booking-flow/global.d.ts @@ -1,7 +1,7 @@ import "@scandic-hotels/common/global.d.ts" -import "@scandic-hotels/trpc/types.d.ts" import "@scandic-hotels/trpc/auth.d.ts" import "@scandic-hotels/trpc/jwt.d.ts" +import "@scandic-hotels/trpc/types.d.ts" declare global { interface Window { diff --git a/packages/booking-flow/lib/components/BookingWidget/BookingWidgetForm/FormContent/formContent.module.css b/packages/booking-flow/lib/components/BookingWidget/BookingWidgetForm/FormContent/formContent.module.css index 076a1e24b..e55772870 100644 --- a/packages/booking-flow/lib/components/BookingWidget/BookingWidgetForm/FormContent/formContent.module.css +++ b/packages/booking-flow/lib/components/BookingWidget/BookingWidgetForm/FormContent/formContent.module.css @@ -29,7 +29,7 @@ .label { color: var(--Text-Accent-Primary); } -.when:has([data-isopen="true"]) .label, +.when:has([data-datepicker-open="true"]) .label, .rooms:has([data-pressed="true"]) .label { color: var(--Text-Interactive-Focus); } @@ -113,7 +113,7 @@ .rooms:hover { background-color: var(--Surface-Primary-Hover); } - .when:has([data-isopen="true"]), + .when:has([data-datepicker-open="true"]), .rooms:has([data-focus-visible="true"], [data-pressed="true"]) { background-color: var(--Surface-Primary-Hover); border: 1px solid var(--Border-Interactive-Focus); diff --git a/packages/booking-flow/lib/components/BookingWidget/Client.tsx b/packages/booking-flow/lib/components/BookingWidget/Client.tsx index 825391c3b..a92830ee5 100644 --- a/packages/booking-flow/lib/components/BookingWidget/Client.tsx +++ b/packages/booking-flow/lib/components/BookingWidget/Client.tsx @@ -241,7 +241,11 @@ export default function BookingWidgetClient({ return ( - + { closeOnBlur(e.nativeEvent) }} - data-isopen={isOpen} + data-datepicker-open={isOpen} ref={ref} >