components/SlidesOverlay/SlidesOverlay.jsxjavascript
import { useState } from "react";
import { UIMCButton } from "@ui-marcom/react/button";
import { UIMCToggleButtonSwitch } from "@ui-marcom/react/toggle-button-switch";
import { useContent } from "../../services/content";
import "./SlidesOverlay.scss";
const ALL_TAB_ID = "all";
const INTRO_ID = "intro";
// One clickable thumbnail in the grid, labelled from its view's headline/
// storyTitle block, falling back to the view id when neither is present.
const SlideThumb = ({ id, view, isCurrent, onSelect }) => {
const blocks = view.elements || [];
const label =
blocks.find((block) => block.type === "headline")?.text ||
blocks.find((block) => block.type === "storyTitle")?.title ||
id;
return (
<button
type="button"
className={`slides-overlay__thumb${isCurrent ? " slides-overlay__thumb--current" : ""}`}
aria-current={isCurrent || undefined}
onClick={() => onSelect(id)}>
{view.thumbnail ? (
<img
className="slides-overlay__thumb-image"
src={view.thumbnail}
alt={label}
loading="lazy"
decoding="async"
width="270"
height="480"
/>
) : (
<span className="slides-overlay__thumb-label">{label}</span>
)}
</button>
);
};
/**
* Full-screen overlay listing every slide of the loaded content file as a
* clickable thumbnail (from the view's optional `thumbnail` field, with a
* text placeholder as fallback), grouped by story. A toggle switch selects
* "All Slides" or a single story (the "intro" story is excluded from the
* switch entirely - its slides only show up under "All Slides"); it opens on
* the current view's story, or "All Slides" when that story isn't offered as
* its own tab. Rendered by SlideNavigation in its "slides" mode.
*
* @param {Object} props
* @param {string} props.currentViewId - View to highlight and to derive the initial story tab from.
* @param {function(string): void} props.onSelectSlide - Called with the clicked slide's view id.
*/
export const SlidesOverlay = ({ currentViewId, onSelectSlide }) => {
const { views, stories } = useContent();
const storyIds = Object.keys(stories);
// console.log("hi", currentViewId);
// const [activeTabId, setActiveTabId] = useState(
// () => views.get(currentViewId)?.story || ALL_TAB_ID
// );
// a story's views in authoring order: root slides and their sub views all
// carry an explicit `story` field
const getStoryViewIds = (storyId) =>
[...views.entries()].filter(([, view]) => view.story === storyId).map(([viewId]) => viewId);
// const tabs = [
// { id: ALL_TAB_ID, label: "All Slides" },
// ...storyIds.map((id) => ({ id, label: stories[id].name })),
// ];
const tabs = [
{ id: ALL_TAB_ID, label: "All Slides" },
...storyIds
.map((id) => ({ id, label: stories[id].name }))
.filter(({ label }) => label.toLowerCase() !== INTRO_ID), // Entfernt das Intro vollständig
];
const [activeTabId, setActiveTabId] = useState(() => {
const currentStoryId = views.get(currentViewId)?.story;
const storyExistsInTabs = tabs.some((tab) => tab.id === currentStoryId);
return storyExistsInTabs ? currentStoryId : ALL_TAB_ID;
});
const activeTabIndex = Math.max(
tabs.findIndex(({ id }) => id === activeTabId),
0
);
const renderGrid = (storyId) => (
<div className="slides-overlay__grid">
{getStoryViewIds(storyId).map((id) => (
<SlideThumb
key={id}
id={id}
view={views.get(id)}
isCurrent={id === currentViewId}
onSelect={onSelectSlide}
/>
))}
</div>
);
const renderBlockGrid = (viewIds) => (
<div className="slides-overlay__grid">
{viewIds.map(
(id) => (
<SlideThumb
key={id}
id={id}
view={views.get(id)}
isCurrent={id === currentViewId}
onSelect={onSelectSlide}
/>
)
// console.log(views.get(id))
)}
</div>
);
const renderStorySwitch = () => (
<div className="slides-overlay__switch">
<UIMCToggleButtonSwitch
className="slides-overlay__switchtoggle"
size="small"
current={activeTabIndex}
onChange={(index) => setActiveTabId(tabs[index].id)}>
{tabs.map(({ id, label }) => (
<UIMCButton className="slides-overlay__togglebtn" key={id}>
{label}
</UIMCButton>
))}
</UIMCToggleButtonSwitch>
</div>
);
// the story switch (renderStorySwitch) renders inside .slides-overlay__content,
// below the grid; SlideNavigation renders its own menu bar as a sibling of
// this whole overlay, not nested inside it
return (
<>
<div className="slides-overlay" role="dialog" aria-modal="true" aria-label="Slides">
<div className="slides-overlay__content">
{activeTabId === ALL_TAB_ID
? // ? storyIds.map((storyId) => (
// <div key={storyId} className="slides-overlay__story-section">
// {/* <h3 className="slides-overlay__story-name">{stories[storyId].name}</h3> */}
// {renderGrid(storyId)}
// </div>
// ))
renderBlockGrid(storyIds.flatMap((storyId) => getStoryViewIds(storyId)))
: renderGrid(activeTabId)}
{renderStorySwitch()}
</div>
</div>
</>
);
};