Files
community-rule/app/components/sections/HeroBanner/HeroBanner.container.tsx
T
adilalloandCursor 33cdaf135c Match Home, top nav, hero, and logo wall to the current marketing frames.
Puts Workshops in the header, pairs the hero with a static rule card and breakpoint CTAs, and shows the three pilot marks with no wall label.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-11-02 18:50:32 -07:00

86 lines
2.7 KiB
TypeScript

"use client";
/**
* Figma: "Section / Hero Banner" (18477:15473)
*/
import { memo, useCallback, useEffect, useMemo, useState } from "react";
import { useRouter } from "next/navigation";
import { useMessages, useTranslation } from "../../../contexts/MessagesContext";
import { fetchAuthSession } from "../../../../lib/create/api";
import { prepareFreshCreateFlowEntrySync } from "../../../(app)/create/utils/prepareFreshCreateFlowEntry";
import type { Category } from "../../cards/Rule";
import type { ChipOption } from "../../controls/MultiSelect/MultiSelect.types";
import HeroBannerView from "./HeroBanner.view";
import type { HeroBannerProps } from "./HeroBanner.types";
function chipsFromLabels(labels: string[]): ChipOption[] {
return labels.map((label) => ({
id: label.toLowerCase().replace(/[^a-z0-9]+/g, "-"),
label,
state: "unselected" as const,
}));
}
const HeroBannerContainer = memo<HeroBannerProps>(
({ title, subtitle, description }) => {
const router = useRouter();
const messages = useMessages();
const tHome = useTranslation("pages.home.heroBanner");
const tHero = useTranslation("heroBanner");
const [signedIn, setSignedIn] = useState(false);
useEffect(() => {
let cancelled = false;
void fetchAuthSession()
.then(({ user }) => {
if (!cancelled) setSignedIn(Boolean(user));
})
.catch(() => {
/* guest fallback */
});
return () => {
cancelled = true;
};
}, []);
const handleCreateRule = useCallback(() => {
prepareFreshCreateFlowEntrySync({ signedIn });
router.push("/create/informational");
}, [router, signedIn]);
const ruleCategories = useMemo<Category[]>(() => {
const groups = messages.heroBanner.ruleCard.categories;
return [
groups.values,
groups.communication,
groups.membership,
groups.decisionMaking,
groups.conflictManagement,
].map((group) => ({
name: group.name,
chipOptions: chipsFromLabels(group.chips),
}));
}, [messages]);
return (
<HeroBannerView
title={title ?? tHome("title")}
subtitle={subtitle ?? tHome("subtitle")}
description={description ?? tHome("description")}
facilitatorCta={tHero("facilitatorCta")}
facilitatorHref={tHero("facilitatorHref")}
createRuleCta={tHero("createRuleCta")}
onCreateRule={handleCreateRule}
ruleTitle={tHero("ruleCard.title")}
ruleDescription={tHero("ruleCard.description")}
ruleCategories={ruleCategories}
/>
);
},
);
HeroBannerContainer.displayName = "HeroBanner";
export default HeroBannerContainer;