Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@ jobs:
- name: Use pnpm
uses: pnpm/action-setup@v3
with:
version: 9
version: 10

- name: Use Node.js
uses: actions/setup-node@v4
with:
node-version: 20
node-version: 22
cache: 'pnpm'

- name: Install dependencies
Expand Down
27 changes: 25 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,35 @@
# Changelog

## v2506.0.0

*Released 02.07.2025*

### Breaking Changes:

- Updated `node.js` to 22 LTS
- Updated pnpm to version 10
- Updated `schema.json` to CoreMedia Content Cloud v12 - 2506.0

### Features:

- Enhanced CoreMedia Engagement Cloud integration

### Bugfixes and Changes:

- Updated vite to v7
- Updated storybook to v9
- Updated minor versions of dependencies
- Updated nginx docker image to v1.29

---

## v2412.0.0

*Released 04.03.2025*
*Released 03.04.2025*

### Breaking Changes:

- Updated `schema.json` to CoreMedia Content Cloud v12 - 2604.0
- Updated `schema.json` to CoreMedia Content Cloud v12 - 2412.0

### Features:

Expand Down
4 changes: 2 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
FROM node:20
RUN npm install -g pnpm@9
FROM node:22-slim
RUN npm install -g pnpm@10
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
![CoreMedia Labs Logo](https://documentation.coremedia.com/badges/banner_coremedia_labs_wide.png)

![CoreMedia Content Cloud Version](https://img.shields.io/static/v1?message=2412&label=CoreMedia%20Content%20Cloud&style=for-the-badge&labelColor=666666&color=672779
![CoreMedia Content Cloud Version](https://img.shields.io/static/v1?message=2506&label=CoreMedia%20Content%20Cloud&style=for-the-badge&labelColor=666666&color=672779
"This badge shows the CoreMedia version this project is compatible with.
Please read the versioning section of the project to see what other CoreMedia versions are supported and how to find them."
)
Expand Down Expand Up @@ -50,7 +50,7 @@ Please refer to the [changelog](CHANGELOG.md) for more details.

## Quickstart

You need at least Node.js 20 (LTS), pnpm 9 and a running instance of the CoreMedia Content Cloud.
You need at least Node.js 22 (LTS), pnpm 10 and a running instance of the CoreMedia Content Cloud.
Define your environment variables in `.env` file for the stitching server:

[servers/stitching/.env](servers/stitching/.env.example)
Expand Down
2 changes: 1 addition & 1 deletion apps/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM nginx:1.24-alpine
FROM nginx:1.29-alpine

COPY spark/dist /usr/share/nginx/html
COPY standalone-fragment/dist /usr/share/nginx/html/standalone
Expand Down
2 changes: 1 addition & 1 deletion apps/spark/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,6 @@ VITE_FQDN=https://<headless-stitching-server.example>
# Set loglevel, default is "warn" for prod and "info" for dev.
#VITE_LOGLEVEL=debug

# Engagement Cloud Integration, default URL: https://bywe2.byside.com/agent/bwc_we2.js
# Engagement Cloud Integration, default URL: https://cdn.engagement.coremedia.cloud/cmec_we2.js
#VITE_ENGAGEMENT_CLOUD_ID=<your-webcare-id>
#VITE_ENGAGEMENT_CLOUD_TAG_URL=<your-custom-tag-url>
4 changes: 2 additions & 2 deletions apps/spark/.storybook/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ export default {
stories: ["../src/**/*.stories.@(ts|tsx)"],
addons: [
"@storybook/addon-links",
"@storybook/addon-essentials",
"@chromatic-com/storybook"
"@chromatic-com/storybook",
"@storybook/addon-docs"
],

framework: {
Expand Down
64 changes: 28 additions & 36 deletions apps/spark/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,71 +18,63 @@
"build-storybook": "storybook build -o dist/storybook"
},
"dependencies": {
"@apollo/client": "^3.11.10",
"@apollo/client": "^3.13.8",
"@coremedia-labs/graphql-layer": "workspace:^",
"@coremedia-labs/preview-integration": "workspace:^",
"@coremedia-labs/view-dispatcher": "workspace:^",
"@js-joda/core": "^5.6.3",
"@js-joda/timezone": "^2.21.1",
"country-flag-icons": "^1.5.13",
"@js-joda/core": "^5.6.5",
"@js-joda/timezone": "^2.22.0",
"country-flag-icons": "^1.5.19",
"crypto-hash": "^2.0.1",
"graphql": "^16.9.0",
"graphql": "^16.11.0",
"i18next": "^23.16.8",
"i18next-browser-languagedetector": "^7.2.1",
"i18next-http-backend": "^2.7.1",
"i18next-browser-languagedetector": "^7.2.2",
"i18next-http-backend": "^2.7.3",
"loglevel": "^1.9.2",
"query-string": "^7.1.3",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-helmet-async": "^1.3.0",
"react-helmet-async": "^2.0.5",
"react-i18next": "^11.18.6",
"react-is": "^18.3.1",
"react-player": "^2.16.0",
"react-responsive": "^9.0.2",
"react-router-dom": "^5.3.4",
"react-router-hash-link": "^2.4.3",
"react-slick": "^0.30.2",
"react-slick": "^0.30.3",
"require-from-string": "^2.0.2",
"slick-carousel": "^1.8.1",
"styled-components": "^5.3.11"
},
"devDependencies": {
"@chromatic-com/storybook": "^3.2.2",
"@storybook/addon-actions": "^8.4.5",
"@storybook/addon-backgrounds": "^8.4.5",
"@storybook/addon-docs": "^8.4.5",
"@storybook/addon-essentials": "^8.4.5",
"@storybook/addon-links": "^8.4.5",
"@storybook/addon-measure": "^8.4.5",
"@storybook/addon-outline": "^8.4.5",
"@storybook/client-logger": "^8.4.5",
"@storybook/node-logger": "^8.4.5",
"@storybook/react": "^8.4.5",
"@storybook/react-vite": "^8.4.5",
"@types/node": "^20.17.6",
"@types/react": "^17.0.83",
"@types/react-dom": "^17.0.25",
"@chromatic-com/storybook": "^4.0.1",
"@storybook/addon-docs": "^9.0.15",
"@storybook/addon-links": "^9.0.15",
"@storybook/react-vite": "^9.0.15",
"@types/node": "^22.15.34",
"@types/react": "^17.0.87",
"@types/react-dom": "^17.0.26",
"@types/react-router-dom": "^5.3.3",
"@types/react-router-hash-link": "^2.4.9",
"@types/react-slick": "^0.23.13",
"@types/styled-components": "^5.1.34",
"@typescript-eslint/eslint-plugin": "^7.18.0",
"@typescript-eslint/parser": "^7.18.0",
"@vitejs/plugin-react-swc": "^3.7.1",
"dotenv": "^16.4.5",
"@vitejs/plugin-react-swc": "^3.10.2",
"dotenv": "^16.6.1",
"eslint": "^8.57.1",
"eslint-config-prettier": "^9.1.0",
"eslint-import-resolver-typescript": "^3.6.3",
"eslint-plugin-import": "^2.31.0",
"eslint-plugin-prettier": "^5.2.1",
"eslint-plugin-react": "^7.37.2",
"eslint-plugin-storybook": "^0.11.1",
"prettier": "^3.3.3",
"storybook": "^8.4.5",
"typedoc": "^0.26.11",
"eslint-import-resolver-typescript": "^3.10.1",
"eslint-plugin-import": "^2.32.0",
"eslint-plugin-prettier": "^5.5.1",
"eslint-plugin-react": "^7.37.5",
"eslint-plugin-storybook": "^9.0.15",
"prettier": "^3.6.2",
"storybook": "^9.0.15",
"typedoc": "^0.28.7",
"typescript": "~5.2.2",
"vite": "^5.4.17",
"vitest": "^2.1.9"
"vite": "^7.0.0",
"vitest": "^3.2.4"
},
"browserslist": {
"production": [
Expand Down
2 changes: 1 addition & 1 deletion apps/spark/src/components/App/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ const App: FC = () => {
setLogLevel();

const location = useLocation();
const rootSegment = getRootSegment(location.pathname) || "calista";
const rootSegment = getRootSegment(location.pathname) || "corporate";
const previewDate = getPreviewDate(location.search);
const previewCampaignId = getPreviewCampaignId(location.search);
const urlSearchParams = useMemo(() => new URLSearchParams(location.search), [location.search]);
Expand Down
8 changes: 5 additions & 3 deletions apps/spark/src/components/App/CmecTag.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,25 @@ import { useSiteContextState } from "../../context/SiteContextProvider";
import { isPreview } from "../../utils/Preview/Preview";

const CmecTag: FC = () => {
const { siteLocale, cmecConfig } = useSiteContextState();
const { siteLocale, siteId, cmecConfig } = useSiteContextState();
let cmecVars = "";

/* no cmec configuration available, just load p13n */
if (!cmecConfig) {
return <></>;
return null;
}

log.info("Loading CoreMedia Engagement Cloud Tag", cmecConfig.id, cmecConfig.url);

cmecVars = `var bysideWebcare_webcare_id="${cmecConfig?.id}";`;
const lang = new Intl.Locale(siteLocale);
cmecVars += `var bysideWebcare_lang="${lang.language}";`;
cmecVars += `var bysideWebcare_locale="${siteLocale}";`;
cmecVars += `var bysideWebcare_site_id="${siteId}";`;
if (isPreview()) {
cmecVars += `var bysideWebcare_preview=true;`;
}
// we need to tell the cmec script that the page is loaded asynchronously
cmecVars += `var bysideWebcare_processAfterContentLoaded = true;`;

return (
<Helmet>
Expand Down
11 changes: 10 additions & 1 deletion apps/spark/src/components/Cart/DetailedCart.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React, { useEffect } from "react";
import { useTranslation } from "react-i18next";
import styled, { css } from "styled-components";
import { Helmet } from "react-helmet-async";
import { useCartContextState } from "../../context/CartContext";
import Link from "../Link/Link";
import ProductPricing, { formatPrice } from "../Product/ProductPricing";
Expand Down Expand Up @@ -152,16 +153,24 @@ const CartContent = styled.div<{ addBorder?: boolean }>`
`;

const DetailedCart: React.FC = () => {
const { rootSegment } = useSiteContextState();
const { rootSegment, cmecConfig } = useSiteContextState();
const { cartItems, itemCount, increase, decrease, removeProduct, total, hideSideCart } = useCartContextState();
const { t } = useTranslation();

useEffect(() => {
hideSideCart();
}, []);

// cmec extra metrics
const cmecPageData = `var bysideWebcare_content_unavailable = new Date().getTime();`;

return (
<StyledCol zone={"main"}>
{!!cmecConfig && (
<Helmet>
<script>{cmecPageData}</script>
</Helmet>
)}
<Headline>{t("DetailedCart.headline")}</Headline>
{itemCount === 0 && (
<EmptyCart>
Expand Down
9 changes: 6 additions & 3 deletions apps/spark/src/components/Date/Date.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import React from "react";
import { convert, ZonedDateTime } from "@js-joda/core";
import styled from "styled-components";
import { convert, ZonedDateTime } from "@js-joda/core";
import "@js-joda/timezone/dist/js-joda-timezone-10-year-range";
import { metaDataProperty } from "../../utils/Preview/MetaData";
import "@js-joda/timezone";
import { useSiteContextState } from "../../context/SiteContextProvider";

interface Props {
date: string | undefined;
Expand All @@ -11,11 +12,13 @@ interface Props {
export const Time = styled.time``;

const Date: React.FC<Props> = ({ date }) => {
const { siteLocale } = useSiteContextState();

let parsedDate: string | undefined = "";
if (date !== undefined) {
const zonedDateTime = ZonedDateTime.parse(date);
const jsDate: Date = convert(zonedDateTime).toDate();
parsedDate = jsDate.toLocaleDateString("en-US");
parsedDate = jsDate.toLocaleDateString(siteLocale);
}
return (
<Time dateTime={parsedDate} {...metaDataProperty("properties.extDisplayedDate")}>
Expand Down
6 changes: 3 additions & 3 deletions apps/spark/src/components/Error/Alert.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export const StyledAlert = styled.div`

export const Alert: FC<Props> = ({ errorCode = 404, title = "Alert", message = "", icon = NotFoundIcon }) => {
return (
<StyledAlert>
<StyledAlert className={"error"}>
{icon && <img src={icon} alt="" />}
{title && (
<h1>
Expand Down Expand Up @@ -68,7 +68,7 @@ export const ApolloClientAlert: React.FC<Props> = ({ error }) => {
log.error("Apollo Client Error: Endpoint =", getEndpoint());
log.error(error);
}
const statusCode = error?.networkError as ServerError;
const networkError = error?.networkError as ServerError;
const errorMessage = [...new Set(error?.message.split("\n"))].toString().replaceAll(",", "\n"); // filter duplicate messages
return <Alert errorCode={statusCode?.statusCode || 500} title="Apollo Client Error" message={errorMessage} />;
return <Alert errorCode={networkError?.statusCode || 500} title="Apollo Client Error" message={errorMessage} />;
};
12 changes: 6 additions & 6 deletions apps/spark/src/components/Footer/Footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ const Version = styled.div`
`;

const Footer: FC = () => {
const { footer } = useSiteContextState();
const { footer, cmecConfig } = useSiteContextState();
const name = footer?.metadata?.root.id || "footer";

return (
Expand All @@ -135,20 +135,20 @@ const Footer: FC = () => {

<SocialIcons>
<a href="https://www.facebook.com/coremedia" target="_blank" rel="noopener noreferrer">
<i style={{ backgroundImage: `url(${Facebook})` }} />
<i style={{ backgroundImage: `url("${Facebook}")` }} />
</a>
<a href="https://de.linkedin.com/company/coremedia-ag" target="_blank" rel="noopener noreferrer">
<i style={{ backgroundImage: `url(${LinkedIn})` }} />
<i style={{ backgroundImage: `url("${LinkedIn}")` }} />
</a>
<a href="https://twitter.com/CoreMedia" target="_blank" rel="noopener noreferrer">
<i style={{ backgroundImage: `url(${Twitter})` }} />
<i style={{ backgroundImage: `url("${Twitter}")` }} />
</a>
<a href="https://www.youtube.com/user/coremediachannel" target="_blank" rel="noopener noreferrer">
<i style={{ backgroundImage: `url(${YouTube})` }} />
<i style={{ backgroundImage: `url("${YouTube}")` }} />
</a>
</SocialIcons>
<Version>
Version: <b>{getWorkspaceVersion()}</b>
Version: <b>{getWorkspaceVersion()}</b> {cmecConfig ? "with CMEC" : ""}
</Version>
</FooterWrapper>
</StyledFooter>
Expand Down
2 changes: 1 addition & 1 deletion apps/spark/src/components/Header/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ const Logo = styled(Link)`
margin: 0 auto;
transform: translateX(-22px); // 50% of the mobile button

background: url(${SparkLogo}) no-repeat center center transparent;
background: url("${SparkLogo}") no-repeat center center transparent;
width: 120px;
height: 40px;
background-size: contain;
Expand Down
2 changes: 1 addition & 1 deletion apps/spark/src/components/Media/Image.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export const StyledImage = styled.img<{ uncropped?: boolean; loaded?: boolean }>
${(props) =>
props.loaded === false &&
css`
background: var(--color-background-image) url(${loader}) center/10% no-repeat;
background: var(--color-background-image) url("${loader}") center/10% no-repeat;
`}
`;
const Image: FC<ImageProps> = ({ picture, cropName, width, aspectRatio = "auto" }) => {
Expand Down
2 changes: 1 addition & 1 deletion apps/spark/src/components/Media/ModalVideo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export const PlayButton = styled.div`
> * {
width: 90px;
height: 90px;
mask-image: url(${PlayIcon});
mask-image: url("${PlayIcon}");
background-color: #ffffff;
opacity: 50%;
background-size: contain;
Expand Down
2 changes: 1 addition & 1 deletion apps/spark/src/components/Person/PersonWithInfo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ const EmailIcon = styled.span`
display: inline-block;
background-repeat: no-repeat;
background-position: 50%;
background-image: url(${Envelop});
background-image: url("${Envelop}");
height: 18px;
width: 18px;
margin-right: 6px;
Expand Down
Loading