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>
This commit is contained in:
1 parent
e12e06f7ce
commit
33cdaf135c
47 files changed
+728
-527
No files matched your search
@@ -0,0 +1,85 @@
|
||||
"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;
|
||||
Reference in new issue
Block a user