Implement use cases page
This commit is contained in:
@@ -2,11 +2,18 @@
|
||||
|
||||
import { useState, useEffect, memo, useMemo, useCallback } from "react";
|
||||
import { useIsMobile } from "../../../hooks";
|
||||
import { useMessages } from "../../../contexts/MessagesContext";
|
||||
import { RelatedArticlesView } from "./RelatedArticles.view";
|
||||
import type { RelatedArticlesProps } from "./RelatedArticles.types";
|
||||
|
||||
const RelatedArticlesContainer = memo<RelatedArticlesProps>(
|
||||
({ relatedPosts, currentPostSlug, slugOrder = [] }) => {
|
||||
({
|
||||
relatedPosts,
|
||||
currentPostSlug,
|
||||
slugOrder = [],
|
||||
variant = "default",
|
||||
}) => {
|
||||
const messages = useMessages();
|
||||
// Memoize filtered posts to prevent unnecessary re-computations
|
||||
const filteredPosts = useMemo(
|
||||
() => relatedPosts.filter((post) => post.slug !== currentPostSlug),
|
||||
@@ -95,6 +102,11 @@ const RelatedArticlesContainer = memo<RelatedArticlesProps>(
|
||||
return () => clearInterval(progressInterval);
|
||||
}, [currentIndex, filteredPosts.length, isMobile]);
|
||||
|
||||
const useCasesHeadingLines =
|
||||
variant === "useCases"
|
||||
? messages.pages.useCases.relatedArticles.title
|
||||
: undefined;
|
||||
|
||||
return (
|
||||
<RelatedArticlesView
|
||||
filteredPosts={filteredPosts}
|
||||
@@ -103,6 +115,8 @@ const RelatedArticlesContainer = memo<RelatedArticlesProps>(
|
||||
transformStyle={transformStyle}
|
||||
getProgressStyle={getProgressStyle}
|
||||
onMouseDown={handleMouseDown}
|
||||
variant={variant}
|
||||
useCasesHeadingLines={useCasesHeadingLines}
|
||||
/>
|
||||
);
|
||||
},
|
||||
|
||||
@@ -1,9 +1,17 @@
|
||||
import type { BlogPost } from "../../../../lib/content";
|
||||
|
||||
export type RelatedArticlesVariant = "default" | "useCases";
|
||||
|
||||
export interface RelatedArticlesProps {
|
||||
relatedPosts: BlogPost[];
|
||||
currentPostSlug: string;
|
||||
slugOrder?: string[];
|
||||
/**
|
||||
* **`useCases`**: Figma related section — baseline [**22112-872308**](https://www.figma.com/design/agv0VBLiBlcnSAaiAORgPR/Community-Rule-System?node-id=22112-872308&m=dev),
|
||||
* **`md`** [**22085-863216**](https://www.figma.com/design/agv0VBLiBlcnSAaiAORgPR/Community-Rule-System?node-id=22085-863216&m=dev),
|
||||
* **`lg`** [**20711-14231**](https://www.figma.com/design/agv0VBLiBlcnSAaiAORgPR/Community-Rule-System?node-id=20711-14231&m=dev) (shell + card row gutter / padding).
|
||||
*/
|
||||
variant?: RelatedArticlesVariant;
|
||||
}
|
||||
|
||||
export interface RelatedArticlesViewProps {
|
||||
@@ -13,4 +21,7 @@ export interface RelatedArticlesViewProps {
|
||||
transformStyle: React.CSSProperties;
|
||||
getProgressStyle: (_index: number) => React.CSSProperties;
|
||||
onMouseDown?: (_e: React.MouseEvent<HTMLDivElement>) => void;
|
||||
variant?: RelatedArticlesVariant;
|
||||
/** Stacked title lines (`pages.useCases.relatedArticles.title`) when `variant="useCases"`. */
|
||||
useCasesHeadingLines?: readonly string[];
|
||||
}
|
||||
|
||||
@@ -8,25 +8,66 @@ export function RelatedArticlesView({
|
||||
transformStyle,
|
||||
getProgressStyle,
|
||||
onMouseDown,
|
||||
variant = "default",
|
||||
useCasesHeadingLines,
|
||||
}: RelatedArticlesViewProps) {
|
||||
if (filteredPosts.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const isUseCases = variant === "useCases";
|
||||
|
||||
return (
|
||||
<section
|
||||
className="py-[var(--spacing-scale-032)] lg:py-[var(--spacing-scale-064)]"
|
||||
className={
|
||||
isUseCases
|
||||
? "px-[var(--spacing-scale-020)] py-[var(--spacing-scale-032)] md:px-[var(--spacing-scale-024)] md:py-[var(--spacing-scale-048)] lg:px-[var(--spacing-scale-120)] lg:py-[var(--spacing-scale-064)]"
|
||||
: "py-[var(--spacing-scale-032)] lg:py-[var(--spacing-scale-064)]"
|
||||
}
|
||||
data-testid="related-articles"
|
||||
{...(isUseCases ? { "data-figma-node": "20711-14231" } : {})}
|
||||
>
|
||||
<div className="flex flex-col gap-[var(--spacing-scale-032)] lg:gap-[51px]">
|
||||
<h2 className="text-[32px] lg:text-[44px] leading-[110%] font-medium text-[var(--color-content-inverse-primary)] text-center">
|
||||
Related Articles
|
||||
</h2>
|
||||
<div
|
||||
className={
|
||||
isUseCases
|
||||
? "mx-auto flex w-full max-w-[1440px] flex-col items-center gap-[var(--spacing-scale-024)] md:gap-[var(--spacing-scale-032)]"
|
||||
: "flex flex-col gap-[var(--spacing-scale-032)] lg:gap-[51px]"
|
||||
}
|
||||
>
|
||||
{isUseCases && useCasesHeadingLines?.length ? (
|
||||
<h2 className="mx-auto w-full min-w-0 max-w-[693px] text-center font-bricolage-grotesque text-[28px] font-bold leading-9 text-[var(--color-content-default-primary)] md:text-[32px] md:leading-[40px] lg:text-[40px] lg:leading-[52px]">
|
||||
{/* Baseline 22112-872308: stacked lines; md+ single line; lg 20711-14231: 40/52, max 693px */}
|
||||
<span className="flex flex-col md:hidden">
|
||||
{useCasesHeadingLines.map((line, index) => (
|
||||
<span key={`${index}-${line}`} className="block">
|
||||
{line}
|
||||
</span>
|
||||
))}
|
||||
</span>
|
||||
<span className="hidden md:block">
|
||||
{useCasesHeadingLines.join(" ")}
|
||||
</span>
|
||||
</h2>
|
||||
) : (
|
||||
<h2 className="text-center text-[32px] font-medium leading-[110%] text-[var(--color-content-inverse-primary)] lg:text-[44px]">
|
||||
Related Articles
|
||||
</h2>
|
||||
)}
|
||||
|
||||
{/* Horizontal Articles Row - Carousel on mobile, Scrollable slider on desktop */}
|
||||
<div className="flex justify-center overflow-hidden">
|
||||
<div
|
||||
className={
|
||||
isUseCases
|
||||
? "flex w-full max-w-[1440px] justify-center overflow-hidden"
|
||||
: "flex justify-center overflow-hidden"
|
||||
}
|
||||
>
|
||||
<div
|
||||
className={`flex gap-0 transition-transform duration-500 ease-in-out ${
|
||||
isUseCases
|
||||
? "lg:gap-[var(--spacing-scale-012)] lg:pl-[var(--spacing-scale-024)]"
|
||||
: ""
|
||||
} ${
|
||||
!isMobile
|
||||
? "overflow-x-auto scrollbar-hide cursor-grab active:cursor-grabbing"
|
||||
: ""
|
||||
|
||||
@@ -1,2 +1,5 @@
|
||||
export { default } from "./RelatedArticles.container";
|
||||
export type { RelatedArticlesProps } from "./RelatedArticles.types";
|
||||
export type {
|
||||
RelatedArticlesProps,
|
||||
RelatedArticlesVariant,
|
||||
} from "./RelatedArticles.types";
|
||||
|
||||
Reference in New Issue
Block a user