diff --git a/apps/scandic-web/components/MyPages/DigitalTeamMemberCard/Client.tsx b/apps/scandic-web/components/MyPages/DigitalTeamMemberCard/Client.tsx index bad0ecc96..c1ed47aae 100644 --- a/apps/scandic-web/components/MyPages/DigitalTeamMemberCard/Client.tsx +++ b/apps/scandic-web/components/MyPages/DigitalTeamMemberCard/Client.tsx @@ -1,5 +1,6 @@ "use client" +import { useState } from "react" import { Button } from "react-aria-components" import { useIntl } from "react-intl" @@ -7,6 +8,7 @@ import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon" import { Typography } from "@scandic-hotels/design-system/Typography" import Modal from "@/components/Modal" +import useWakeLock from "@/hooks/useWakeLock" import styles from "./digitalTeamMemberCard.module.css" @@ -20,97 +22,109 @@ export default function DigitalTeamMemberCardClient({ user, }: DigitalTeamMemberCardClientProps) { const intl = useIntl() + const [isOpen, setIsOpen] = useState(false) + + const { release, request } = useWakeLock({ + reacquireOnPageVisible: true, + }) + + function onToggle(modalState: boolean) { + setIsOpen(modalState) + if (modalState) { + request() + } else { + release() + } + } return ( - - - - {/* @ts-expect-error Icon is supported in font, just not in React Material Symbols package */} - - {intl.formatMessage({ - defaultMessage: "Show Team Member Card", - })} - - - - } - className={styles.modal} - > - -

- {intl.formatMessage({ defaultMessage: "Scandic Family" })} -

-
-
-
-
- - - {intl.formatMessage({ defaultMessage: "Team Member" })} - - - - {/* TODO: Should display country of employment */} - {/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */} - SWE - -
-
-
- - {/* TODO: Should display employee number */} - {/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */} -
123 456
+ <> + + + +

+ {intl.formatMessage({ defaultMessage: "Scandic Family" })} +

+
+
+
+
+ + + {intl.formatMessage({ defaultMessage: "Team Member" })} + + + + {/* TODO: Should display country of employment */} + {/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */} + SWE - - -
- - -
- {user.firstName} {user.lastName} +
+
+ + {/* TODO: Should display employee number */} + {/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */} +
123 456
+
+ + +
- -
-
- - - {/* TODO: Should display department of employment */} - {/* eslint-disable formatjs/no-literal-string-in-jsx */} - Haymarket by Scandic - {/* eslint-enable */} - - - - {/* TODO: Should display current state of employment */} - {/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */} - Employee - + + +
+ {user.firstName} {user.lastName} +
+
+
+
+ + + {/* TODO: Should display department of employment */} + {/* eslint-disable formatjs/no-literal-string-in-jsx */} + Haymarket by Scandic + {/* eslint-enable */} + + + + {/* TODO: Should display current state of employment */} + {/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */} + Employee + +
-
- -
- {intl.formatMessage({ - defaultMessage: - "Book discounted stays for yourself, family and friends!", - })} -
-
-
+ +
+ {intl.formatMessage({ + defaultMessage: + "Book discounted stays for yourself, family and friends!", + })} +
+
+ + ) } diff --git a/apps/scandic-web/hooks/useWakeLock.ts b/apps/scandic-web/hooks/useWakeLock.ts new file mode 100644 index 000000000..5eb0a5cad --- /dev/null +++ b/apps/scandic-web/hooks/useWakeLock.ts @@ -0,0 +1,72 @@ +"use client" + +import { useCallback, useEffect, useRef } from "react" + +let isSupported = false + +if ("wakeLock" in navigator) { + isSupported = true +} + +interface Options { + reacquireOnPageVisible?: boolean + onRequest?: () => void + onRelease?: () => void +} + +/** + * Uses the Wake Lock API to keep the screen from dimming or locking. + * https://developer.mozilla.org/en-US/docs/Web/API/Screen_Wake_Lock_API + */ +export default function useWakeLock({ + reacquireOnPageVisible = false, + onRequest = () => undefined, + onRelease = () => undefined, +}: Options = {}) { + const wakeLock = useRef(null) + + const request = useCallback(async () => { + if (!isSupported) { + return + } + + try { + wakeLock.current = await navigator.wakeLock.request("screen") + + onRequest() + + wakeLock.current.onrelease = () => { + onRelease() + } + } catch (_err) { + // ignore + } + }, [onRelease, onRequest]) + + const release = useCallback(() => { + if (!isSupported) { + return + } + wakeLock.current?.release().then(() => { + wakeLock.current = null + }) + }, []) + + useEffect(() => { + const handleVisibilityChange = () => { + if (wakeLock.current !== null && document.visibilityState === "visible") { + request() + } + } + + if (reacquireOnPageVisible) { + document.addEventListener("visibilitychange", handleVisibilityChange) + } + + return () => { + document.removeEventListener("visibilitychange", handleVisibilityChange) + } + }, [reacquireOnPageVisible, request]) + + return { isSupported, request, release } +}