f6a0673082
CI Pipeline / test (20) (pull_request) Failing after 1m17s
CI Pipeline / test (18) (pull_request) Failing after 1m28s
CI Pipeline / e2e (chromium) (pull_request) Failing after 1m33s
CI Pipeline / e2e (firefox) (pull_request) Failing after 1m27s
CI Pipeline / e2e (webkit) (pull_request) Failing after 1m34s
CI Pipeline / visual-regression (pull_request) Failing after 2m9s
CI Pipeline / storybook (pull_request) Failing after 1m5s
CI Pipeline / performance (pull_request) Failing after 1m42s
CI Pipeline / lint (pull_request) Failing after 49s
CI Pipeline / build (pull_request) Failing after 1m29s
85 lines
2.9 KiB
TypeScript
85 lines
2.9 KiB
TypeScript
"use client";
|
|
|
|
import React, { memo } from "react";
|
|
import { getAssetPath } from "../../lib/assetUtils";
|
|
import ContentContainer from "./ContentContainer";
|
|
import type { BlogPost } from "../../lib/content";
|
|
|
|
interface ContentBannerProps {
|
|
post: BlogPost;
|
|
}
|
|
|
|
const ContentBanner = memo<ContentBannerProps>(({ post }) => {
|
|
// Get article-specific horizontal thumbnail (small) and banner (md+)
|
|
const getBackgroundImage = (post: BlogPost): string => {
|
|
if (post.frontmatter?.thumbnail?.horizontal) {
|
|
return `/content/blog/${post.frontmatter.thumbnail.horizontal}`;
|
|
}
|
|
// Fallback to default image
|
|
return getAssetPath("assets/Content_Banner.svg");
|
|
};
|
|
|
|
const getBannerImageMd = (post: BlogPost): string => {
|
|
// Use banner.horizontal when provided; fallback to horizontal thumbnail
|
|
if (post.frontmatter?.banner?.horizontal) {
|
|
return `/content/blog/${post.frontmatter.banner.horizontal}`;
|
|
}
|
|
// Fallback to horizontal thumbnail, then default banner
|
|
if (post.frontmatter?.thumbnail?.horizontal) {
|
|
return `/content/blog/${post.frontmatter.thumbnail.horizontal}`;
|
|
}
|
|
return getAssetPath("assets/Content_Banner_2.svg");
|
|
};
|
|
|
|
const backgroundImage = getBackgroundImage(post);
|
|
const bannerImageMd = getBannerImageMd(post);
|
|
|
|
return (
|
|
<div className="pt-[var(--measures-spacing-016)] md:pt-[var(--measures-spacing-008)] lg:pt-[50px] xl:pt-[112px] h-[275px] sm:h-[326px] md:h-[224px] lg:h-[358.4px] xl:h-[504px] relative w-full sm:overflow-hidden">
|
|
{/* Background SVG - Default to sm breakpoint */}
|
|
<div
|
|
className="absolute inset-0 w-full h-full bg-cover bg-no-repeat aspect-[320/225.5]"
|
|
style={{
|
|
backgroundImage: `url(${backgroundImage})`,
|
|
backgroundPosition: "center bottom",
|
|
}}
|
|
/>
|
|
|
|
{/* Background SVG - md breakpoint and above (article banner image) */}
|
|
<div
|
|
className="absolute inset-0 w-full h-full bg-cover bg-no-repeat aspect-[640/224] md:block hidden"
|
|
style={{
|
|
backgroundImage: `url(${bannerImageMd})`,
|
|
backgroundPosition: "center bottom",
|
|
}}
|
|
/>
|
|
|
|
{/* Content Container */}
|
|
<div
|
|
className="
|
|
relative z-10 h-full
|
|
flex flex-col
|
|
pl-[var(--measures-spacing-016)] md:pl-[var(--measures-spacing-024)] lg:pl-[var(--measures-spacing-064)]
|
|
pr-[96px] md:pr-[350px]
|
|
|
|
/* default: normal flow, top-aligned */
|
|
justify-start
|
|
|
|
/* only at md: take out of flow and center vertically */
|
|
md:absolute md:inset-x-0 md:top-1/2 md:-translate-y-1/2 md:w-full md:h-auto
|
|
|
|
/* after md (lg+): snap back to normal flow/top align */
|
|
lg:static lg:translate-y-0 lg:top-auto lg:h-full lg:justify-start
|
|
"
|
|
>
|
|
{/* ContentContainer with post data */}
|
|
<ContentContainer post={post} size="responsive" />
|
|
</div>
|
|
</div>
|
|
);
|
|
});
|
|
|
|
ContentBanner.displayName = "ContentBanner";
|
|
|
|
export default ContentBanner;
|