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>
86 lines
2.7 KiB
TypeScript
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;
|