pages/ValuePartnership/PartnershipsPage/SlideView.jsxjavascript
import { useEffect, useRef, useState } from "react";
import PropTypes from "prop-types";
import { UIMCButton } from "@ui-marcom/react/button";
import { UIMCControlButton } from "@ui-marcom/react/control-button";
import { UIMCPagination } from "@ui-marcom/react/pagination";
// ui-marcom-pagination's own "compact" template renders a <ui-marcom-dropdown>
// for the page counter but never imports @ui-marcom/dropdown itself (likely a
// packaging oversight) - register it ourselves or the dropdown just sits
// inert/undefined (same fix as GlobeBottomNav.jsx; route-level code
// splitting means that page's own registration can't be relied on here).
import "@ui-marcom/dropdown";
import { QrCodeCanvas } from "./QrCodeCanvas";
import { resolveWebLink } from "./qrCodeLink";
import "./SlideView.scss";
/**
* Fullscreen presentation-deck viewer, ported from value-slideview.js
* (minus the QR/congress-app "save highlights" checkbox mode, which lives in
* PresentationBrowser, and the manual `<link rel=preload>` injection, replaced
* by the browser's own image decoding/caching). Mount with `key={ppt.id}` so
* opening a different deck resets `page` cleanly instead of syncing it via effect.
*
* @param {Object} props
* @param {{id: string, content: string, pictures: string[]}} props.ppt
* @param {number} [props.initialPage=1]
* @param {Object} props.labels
* @param {function(): void} props.onClose
*/
// ported verbatim from value-slideview.js's __disclaimer block, which hard-
// codes this the same way (not content/labels-driven there either)
const COPYRIGHT_NOTICE = "Unrestricted © Siemens Healthineers AG, 2025";
export const SlideView = ({ ppt, initialPage = 1, labels, onClose }) => {
const [page, setPage] = useState(initialPage);
const [qrOpen, setQrOpen] = useState(false);
const total = ppt.pictures.length;
const webLink = resolveWebLink(ppt.webLink);
// keeps the active thumbnail visible as `page` changes (Prev/Next,
// thumbnail click, or a deep initialPage on mount) - .slide-view__thumbnails
// scrolls independently of the rest of the bar, and nothing else keeps the
// highlighted thumbnail (see --active in SlideView.scss) in view otherwise
const activeThumbRef = useRef(null);
useEffect(() => {
activeThumbRef.current?.scrollIntoView({
behavior: "smooth",
inline: "center",
block: "nearest",
});
}, [page]);
return (
<div className="slide-view">
<div className="slide-view__slide">
<img src={ppt.pictures[page - 1]} alt="" />
{labels.showQRCode && webLink && (
<UIMCButton
className="slide-view__qr-trigger"
variant="primary-cta"
title={labels.showQRCode}
onClick={() => setQrOpen(true)}>
<ui-marcom-icon slot="prefix" icon="arrow-right-medium"></ui-marcom-icon>
{labels.showQRCode}
</UIMCButton>
)}
</div>
<div className="slide-view__nav">
<div className="slide-view__nav-buttons">
<UIMCControlButton
icon="home"
title="Home"
onClick={onClose}
className="slide-view__nav-button--home"
/>
<UIMCButton
variant="standard"
title={labels.backToOverview}
onClick={onClose}
className="slide-view__nav-button--back">
<ui-marcom-icon slot="prefix" icon="arrow-long-left"></ui-marcom-icon>
{labels.backToOverview}
</UIMCButton>
<UIMCPagination
className="slide-view__pagination"
variant="compact"
totalItems={total}
itemsPerPage={1}
currentPage={page}
i18n={{
prev: labels.previous,
next: labels.next,
prevLabel: labels.previous,
nextLabel: labels.next,
separatorLabel: "of",
}}
onChange={(newPage) => setPage(newPage)}
/>
</div>
<div className="slide-view__thumbnails">
{ppt.pictures.map((src, index) => {
const isActive = index === page - 1;
return (
<div
key={src}
ref={isActive ? activeThumbRef : undefined}
className={
isActive
? "slide-view__thumbnail slide-view__thumbnail--active"
: "slide-view__thumbnail"
}
onClick={() => setPage(index + 1)}>
<img src={src} alt="" loading="lazy" />
<span>Slide {index + 1}</span>
</div>
);
})}
</div>
<div className="slide-view__nav-meta">
<span className="slide-view__copyright">{COPYRIGHT_NOTICE}</span>
</div>
</div>
{qrOpen && (
<div className="slide-view__qr-overlay" onClick={() => setQrOpen(false)}>
<div className="slide-view__qr-card" onClick={(e) => e.stopPropagation()}>
<h5>Scan your assets to read them later</h5>
<QrCodeCanvas url={webLink} />
<UIMCControlButton icon="close" title="Schließen" onClick={() => setQrOpen(false)} />
</div>
</div>
)}
</div>
);
};
SlideView.propTypes = {
ppt: PropTypes.shape({
id: PropTypes.string,
content: PropTypes.string,
pictures: PropTypes.arrayOf(PropTypes.string).isRequired,
}).isRequired,
initialPage: PropTypes.number,
labels: PropTypes.object.isRequired,
onClose: PropTypes.func.isRequired,
};