services/orientation.jsjavascript
/*
  Resolves which orientation ("landscape"/"portrait") the *current route*
  expects the kiosk to be held in, so RotateOverlay
  (src/components/RotateOverlay/RotateOverlay.jsx) can compare it against
  the physical orientation from useOrientation (src/hooks/orientation.jsx)
  and tell the visitor to rotate the display when they don't match.

  Two sources, in priority order:
    1. `deviceType` (config-schema.js, URL param) - when explicitly set to
       "landscape" or "portrait" it forces that orientation for every route
       on this kiosk, e.g. for a device that's physically bolted into a
       fixed orientation regardless of which app is open. Its default,
       "default", means "no override, defer to the route".
    2. The route's own `orientation` - "/" (AppSelection) is landscape,
       every other route's is declared in PRESENTATION_MODES
       (services/presentationModes.js).
*/

import { useLocation } from "react-router";
import { useConfig } from "./config/config";
import { PRESENTATION_MODES } from "./presentationModes";

// AppSelection ("/") isn't part of PRESENTATION_MODES (it's the hub, not a
// presentation mode itself), so its expected orientation is declared here.
const ROOT_ORIENTATION = "landscape";

const DEVICE_TYPE_ORIENTATIONS = ["landscape", "portrait"];

/**
 * @returns {"landscape"|"portrait"|null} The orientation the current route
 *   (optionally overridden by `deviceType`) expects, or `null` if the route
 *   has no orientation requirement.
 */
export const useRequiredOrientation = () => {
  const { pathname } = useLocation();
  const { deviceType } = useConfig();

  // deviceType overrides whatever the route would normally require - the
  // kiosk's physical mounting takes precedence over the app's own preference.
  if (DEVICE_TYPE_ORIENTATIONS.includes(deviceType)) return deviceType;

  if (pathname === "/") return ROOT_ORIENTATION;

  const mode = PRESENTATION_MODES.find(
    ({ path }) => pathname === path || pathname.startsWith(`${path}/`)
  );
  return mode?.orientation ?? null;
};