Full cleanup pass
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import { memo } from "react";
|
||||
import { useTranslation } from "../../../contexts/MessagesContext";
|
||||
import { CreateFlowFooterView } from "./CreateFlowFooter.view";
|
||||
import type { CreateFlowFooterProps } from "./CreateFlowFooter.types";
|
||||
|
||||
@@ -16,7 +17,10 @@ const CreateFlowFooterContainer = memo<CreateFlowFooterProps>(
|
||||
proportionBarVariant,
|
||||
onBackClick,
|
||||
className = "",
|
||||
footerAriaLabel,
|
||||
}) => {
|
||||
const t = useTranslation("controlsChrome");
|
||||
|
||||
return (
|
||||
<CreateFlowFooterView
|
||||
secondButton={secondButton}
|
||||
@@ -25,6 +29,7 @@ const CreateFlowFooterContainer = memo<CreateFlowFooterProps>(
|
||||
proportionBarVariant={proportionBarVariant}
|
||||
onBackClick={onBackClick}
|
||||
className={className}
|
||||
footerAriaLabel={footerAriaLabel ?? t("createFlowFooterAriaLabel")}
|
||||
/>
|
||||
);
|
||||
},
|
||||
|
||||
@@ -36,4 +36,8 @@ export interface CreateFlowFooterProps {
|
||||
* Additional CSS classes
|
||||
*/
|
||||
className?: string;
|
||||
/**
|
||||
* Accessible name for the footer landmark.
|
||||
*/
|
||||
footerAriaLabel?: string;
|
||||
}
|
||||
|
||||
@@ -9,13 +9,14 @@ export function CreateFlowFooterView({
|
||||
proportionBarVariant: proportionBarVariantProp,
|
||||
onBackClick,
|
||||
className = "",
|
||||
footerAriaLabel,
|
||||
}: CreateFlowFooterProps) {
|
||||
const proportionBarVariant = proportionBarVariantProp ?? "default";
|
||||
return (
|
||||
<footer
|
||||
className={`bg-black w-full ${className}`}
|
||||
role="contentinfo"
|
||||
aria-label="Create Flow Footer"
|
||||
aria-label={footerAriaLabel}
|
||||
>
|
||||
{/* Progress Bar - Top */}
|
||||
{progressBar && (
|
||||
|
||||
@@ -1,10 +1,14 @@
|
||||
"use client";
|
||||
|
||||
import { memo } from "react";
|
||||
import { memo, useCallback, useEffect, useId, useMemo, useRef, useState } from "react";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useCreateFlowSm2Up } from "../../../(app)/create/hooks/useCreateFlowSm2Up";
|
||||
import { useTranslation } from "../../../contexts/MessagesContext";
|
||||
import { CreateFlowTopNavView } from "./CreateFlowTopNav.view";
|
||||
import type { CreateFlowTopNavProps } from "./CreateFlowTopNav.types";
|
||||
import type {
|
||||
CreateFlowTopNavActionMenuItem,
|
||||
CreateFlowTopNavProps,
|
||||
} from "./CreateFlowTopNav.types";
|
||||
|
||||
/**
|
||||
* Figma: Utility / CreateFlowTopNav — wizard header (create-flow chrome).
|
||||
@@ -34,15 +38,168 @@ const CreateFlowTopNavContainer = memo<CreateFlowTopNavProps>(
|
||||
const router = useRouter();
|
||||
const t = useTranslation("create.topNav");
|
||||
const tPopover = useTranslation("modals.popoverExport");
|
||||
const sm2Up = useCreateFlowSm2Up();
|
||||
const exitButtonText =
|
||||
exitLabel ?? (saveDraftOnExit ? t("saveAndExit") : t("exit"));
|
||||
const [exportMenuOpen, setExportMenuOpen] = useState(false);
|
||||
const [actionsMenuOpen, setActionsMenuOpen] = useState(false);
|
||||
const exportWrapRef = useRef<HTMLDivElement>(null);
|
||||
const actionsWrapRef = useRef<HTMLDivElement>(null);
|
||||
const exportMenuId = useId();
|
||||
const actionsMenuId = useId();
|
||||
|
||||
const handleExit = (options?: { saveDraft?: boolean }) => {
|
||||
if (onExit) {
|
||||
onExit(options);
|
||||
} else {
|
||||
// Default behavior: navigate to home
|
||||
router.push("/");
|
||||
const handleExit = useCallback(
|
||||
(options?: { saveDraft?: boolean }) => {
|
||||
if (onExit) {
|
||||
onExit(options);
|
||||
} else {
|
||||
// Default behavior: navigate to home
|
||||
router.push("/");
|
||||
}
|
||||
},
|
||||
[onExit, router],
|
||||
);
|
||||
|
||||
const hasSecondaryActions =
|
||||
hasShare ||
|
||||
hasExport ||
|
||||
hasEdit ||
|
||||
hasDuplicate ||
|
||||
hasManageStakeholders;
|
||||
const useKebabMenu = hasSecondaryActions && !sm2Up;
|
||||
|
||||
const actionMenuItems = useMemo((): CreateFlowTopNavActionMenuItem[] => {
|
||||
const items: CreateFlowTopNavActionMenuItem[] = [];
|
||||
|
||||
if (hasShare && onShare) {
|
||||
items.push({
|
||||
id: "share",
|
||||
label: t("share"),
|
||||
leadingIcon: "mail",
|
||||
onClick: onShare,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
if (hasExport && onSelectExportFormat) {
|
||||
items.push(
|
||||
{
|
||||
id: "export-pdf",
|
||||
label: tPopover("downloadPdf"),
|
||||
leadingIcon: "picture_as_pdf",
|
||||
onClick: () => onSelectExportFormat("pdf"),
|
||||
},
|
||||
{
|
||||
id: "export-csv",
|
||||
label: tPopover("downloadCsv"),
|
||||
leadingIcon: "csv",
|
||||
onClick: () => onSelectExportFormat("csv"),
|
||||
},
|
||||
{
|
||||
id: "export-markdown",
|
||||
label: tPopover("downloadMarkdown"),
|
||||
leadingIcon: "markdown_copy",
|
||||
onClick: () => onSelectExportFormat("markdown"),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
if (hasDuplicate && onDuplicate) {
|
||||
items.push({
|
||||
id: "duplicate",
|
||||
label: duplicateLabel ?? t("edit"),
|
||||
leadingIcon: "content_copy",
|
||||
onClick: onDuplicate,
|
||||
});
|
||||
} else if (hasEdit && onEdit) {
|
||||
items.push({
|
||||
id: "edit",
|
||||
label: t("edit"),
|
||||
leadingIcon: "edit",
|
||||
onClick: onEdit,
|
||||
});
|
||||
}
|
||||
|
||||
if (hasManageStakeholders && onManageStakeholders) {
|
||||
items.push({
|
||||
id: "manage-stakeholders",
|
||||
label: t("manageStakeholders"),
|
||||
leadingIcon: "tags",
|
||||
onClick: onManageStakeholders,
|
||||
});
|
||||
}
|
||||
|
||||
items.push({
|
||||
id: "exit",
|
||||
label: exitButtonText,
|
||||
leadingIcon: "log_out",
|
||||
onClick: () => void handleExit({ saveDraft: saveDraftOnExit }),
|
||||
});
|
||||
|
||||
return items;
|
||||
}, [
|
||||
duplicateLabel,
|
||||
exitButtonText,
|
||||
handleExit,
|
||||
hasDuplicate,
|
||||
hasEdit,
|
||||
hasExport,
|
||||
hasManageStakeholders,
|
||||
hasShare,
|
||||
onDuplicate,
|
||||
onEdit,
|
||||
onManageStakeholders,
|
||||
onSelectExportFormat,
|
||||
onShare,
|
||||
saveDraftOnExit,
|
||||
t,
|
||||
tPopover,
|
||||
]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!exportMenuOpen) return;
|
||||
const onDoc = (e: MouseEvent) => {
|
||||
if (
|
||||
exportWrapRef.current &&
|
||||
!exportWrapRef.current.contains(e.target as Node)
|
||||
) {
|
||||
setExportMenuOpen(false);
|
||||
}
|
||||
};
|
||||
document.addEventListener("mousedown", onDoc);
|
||||
return () => document.removeEventListener("mousedown", onDoc);
|
||||
}, [exportMenuOpen]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!actionsMenuOpen) return;
|
||||
const onDoc = (e: MouseEvent) => {
|
||||
if (
|
||||
actionsWrapRef.current &&
|
||||
!actionsWrapRef.current.contains(e.target as Node)
|
||||
) {
|
||||
setActionsMenuOpen(false);
|
||||
}
|
||||
};
|
||||
document.addEventListener("mousedown", onDoc);
|
||||
return () => document.removeEventListener("mousedown", onDoc);
|
||||
}, [actionsMenuOpen]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!exportMenuOpen) return;
|
||||
const onKey = (e: KeyboardEvent) => {
|
||||
if (e.key === "Escape") setExportMenuOpen(false);
|
||||
};
|
||||
window.addEventListener("keydown", onKey);
|
||||
return () => window.removeEventListener("keydown", onKey);
|
||||
}, [exportMenuOpen]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!actionsMenuOpen) return;
|
||||
const onKey = (e: KeyboardEvent) => {
|
||||
if (e.key === "Escape") setActionsMenuOpen(false);
|
||||
};
|
||||
window.addEventListener("keydown", onKey);
|
||||
return () => window.removeEventListener("keydown", onKey);
|
||||
}, [actionsMenuOpen]);
|
||||
|
||||
return (
|
||||
<CreateFlowTopNavView
|
||||
@@ -63,6 +220,17 @@ const CreateFlowTopNavContainer = memo<CreateFlowTopNavProps>(
|
||||
duplicateAriaLabel={duplicateAriaLabel}
|
||||
buttonPalette={buttonPalette}
|
||||
className={className}
|
||||
exitButtonText={exitButtonText}
|
||||
useKebabMenu={useKebabMenu}
|
||||
exportMenuOpen={exportMenuOpen}
|
||||
setExportMenuOpen={setExportMenuOpen}
|
||||
actionsMenuOpen={actionsMenuOpen}
|
||||
setActionsMenuOpen={setActionsMenuOpen}
|
||||
exportWrapRef={exportWrapRef}
|
||||
actionsWrapRef={actionsWrapRef}
|
||||
exportMenuId={exportMenuId}
|
||||
actionsMenuId={actionsMenuId}
|
||||
actionMenuItems={actionMenuItems}
|
||||
exportPopoverMenuAriaLabel={tPopover("menuAriaLabel")}
|
||||
exportPopoverPdfLabel={tPopover("downloadPdf")}
|
||||
exportPopoverCsvLabel={tPopover("downloadCsv")}
|
||||
|
||||
@@ -5,6 +5,16 @@
|
||||
* Includes logo and action buttons (Share, Export, Edit, Exit).
|
||||
*/
|
||||
|
||||
import type { Dispatch, RefObject, SetStateAction } from "react";
|
||||
import type { IconName } from "../../asset/icon";
|
||||
|
||||
export type CreateFlowTopNavActionMenuItem = {
|
||||
id: string;
|
||||
label: string;
|
||||
leadingIcon: IconName;
|
||||
onClick: () => void;
|
||||
};
|
||||
|
||||
export interface CreateFlowTopNavProps {
|
||||
/**
|
||||
* Whether to show the Share button
|
||||
@@ -81,8 +91,19 @@ export interface CreateFlowTopNavProps {
|
||||
className?: string;
|
||||
}
|
||||
|
||||
/** Resolved copy for the export popover; supplied by the container. */
|
||||
/** Resolved copy and menu state; supplied by the container. */
|
||||
export type CreateFlowTopNavViewProps = CreateFlowTopNavProps & {
|
||||
exitButtonText: string;
|
||||
useKebabMenu: boolean;
|
||||
exportMenuOpen: boolean;
|
||||
setExportMenuOpen: Dispatch<SetStateAction<boolean>>;
|
||||
actionsMenuOpen: boolean;
|
||||
setActionsMenuOpen: Dispatch<SetStateAction<boolean>>;
|
||||
exportWrapRef: RefObject<HTMLDivElement | null>;
|
||||
actionsWrapRef: RefObject<HTMLDivElement | null>;
|
||||
exportMenuId: string;
|
||||
actionsMenuId: string;
|
||||
actionMenuItems: CreateFlowTopNavActionMenuItem[];
|
||||
exportPopoverMenuAriaLabel: string;
|
||||
exportPopoverPdfLabel: string;
|
||||
exportPopoverCsvLabel: string;
|
||||
|
||||
@@ -1,12 +1,9 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect, useId, useMemo, useRef, useState } from "react";
|
||||
import type { IconName } from "../../asset/icon";
|
||||
import Logo from "../../asset/Logo";
|
||||
import Button from "../../buttons/Button";
|
||||
import ListItem from "../../layout/ListItem";
|
||||
import Popover from "../../modals/Popover";
|
||||
import { useCreateFlowSm2Up } from "../../../(app)/create/hooks/useCreateFlowSm2Up";
|
||||
import { useTranslation } from "../../../contexts/MessagesContext";
|
||||
import type { CreateFlowTopNavViewProps } from "./CreateFlowTopNav.types";
|
||||
|
||||
@@ -16,13 +13,6 @@ const outlineButtonClass =
|
||||
const exitButtonFigmaClass =
|
||||
"!rounded-[var(--radius-measures-radius-full,9999px)] !border-[1.25px] !px-[var(--spacing-measures-spacing-250,10px)] !py-[var(--spacing-measures-spacing-200,8px)] md:!text-[12px] md:!leading-[14px]";
|
||||
|
||||
type ActionMenuItem = {
|
||||
id: string;
|
||||
label: string;
|
||||
leadingIcon: IconName;
|
||||
onClick: () => void;
|
||||
};
|
||||
|
||||
function KebabIcon({ className = "" }: { className?: string }) {
|
||||
return (
|
||||
<svg
|
||||
@@ -54,11 +44,21 @@ export function CreateFlowTopNavView({
|
||||
onDuplicate,
|
||||
onManageStakeholders,
|
||||
onExit,
|
||||
exitLabel,
|
||||
duplicateLabel,
|
||||
duplicateAriaLabel,
|
||||
buttonPalette = "default",
|
||||
className = "",
|
||||
exitButtonText,
|
||||
useKebabMenu,
|
||||
exportMenuOpen,
|
||||
setExportMenuOpen,
|
||||
actionsMenuOpen,
|
||||
setActionsMenuOpen,
|
||||
exportWrapRef,
|
||||
actionsWrapRef,
|
||||
exportMenuId,
|
||||
actionsMenuId,
|
||||
actionMenuItems,
|
||||
exportPopoverMenuAriaLabel,
|
||||
exportPopoverPdfLabel,
|
||||
exportPopoverCsvLabel,
|
||||
@@ -67,15 +67,6 @@ export function CreateFlowTopNavView({
|
||||
actionsMenuAriaLabel,
|
||||
}: CreateFlowTopNavViewProps) {
|
||||
const t = useTranslation("create.topNav");
|
||||
const sm2Up = useCreateFlowSm2Up();
|
||||
const exitButtonText =
|
||||
exitLabel ?? (saveDraftOnExit ? t("saveAndExit") : t("exit"));
|
||||
const [exportMenuOpen, setExportMenuOpen] = useState(false);
|
||||
const [actionsMenuOpen, setActionsMenuOpen] = useState(false);
|
||||
const exportWrapRef = useRef<HTMLDivElement>(null);
|
||||
const actionsWrapRef = useRef<HTMLDivElement>(null);
|
||||
const exportMenuId = useId();
|
||||
const actionsMenuId = useId();
|
||||
|
||||
const hasSecondaryActions =
|
||||
hasShare ||
|
||||
@@ -83,142 +74,6 @@ export function CreateFlowTopNavView({
|
||||
hasEdit ||
|
||||
hasDuplicate ||
|
||||
hasManageStakeholders;
|
||||
const useKebabMenu = hasSecondaryActions && !sm2Up;
|
||||
|
||||
const actionMenuItems = useMemo((): ActionMenuItem[] => {
|
||||
const items: ActionMenuItem[] = [];
|
||||
|
||||
if (hasShare && onShare) {
|
||||
items.push({
|
||||
id: "share",
|
||||
label: t("share"),
|
||||
leadingIcon: "mail",
|
||||
onClick: onShare,
|
||||
});
|
||||
}
|
||||
|
||||
if (hasExport && onSelectExportFormat) {
|
||||
items.push(
|
||||
{
|
||||
id: "export-pdf",
|
||||
label: exportPopoverPdfLabel,
|
||||
leadingIcon: "picture_as_pdf",
|
||||
onClick: () => onSelectExportFormat("pdf"),
|
||||
},
|
||||
{
|
||||
id: "export-csv",
|
||||
label: exportPopoverCsvLabel,
|
||||
leadingIcon: "csv",
|
||||
onClick: () => onSelectExportFormat("csv"),
|
||||
},
|
||||
{
|
||||
id: "export-markdown",
|
||||
label: exportPopoverMarkdownLabel,
|
||||
leadingIcon: "markdown_copy",
|
||||
onClick: () => onSelectExportFormat("markdown"),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
if (hasDuplicate && onDuplicate) {
|
||||
items.push({
|
||||
id: "duplicate",
|
||||
label: duplicateLabel ?? t("edit"),
|
||||
leadingIcon: "content_copy",
|
||||
onClick: onDuplicate,
|
||||
});
|
||||
} else if (hasEdit && onEdit) {
|
||||
items.push({
|
||||
id: "edit",
|
||||
label: t("edit"),
|
||||
leadingIcon: "edit",
|
||||
onClick: onEdit,
|
||||
});
|
||||
}
|
||||
|
||||
if (hasManageStakeholders && onManageStakeholders) {
|
||||
items.push({
|
||||
id: "manage-stakeholders",
|
||||
label: t("manageStakeholders"),
|
||||
leadingIcon: "tags",
|
||||
onClick: onManageStakeholders,
|
||||
});
|
||||
}
|
||||
|
||||
items.push({
|
||||
id: "exit",
|
||||
label: exitButtonText,
|
||||
leadingIcon: "log_out",
|
||||
onClick: () => void onExit?.({ saveDraft: saveDraftOnExit }),
|
||||
});
|
||||
|
||||
return items;
|
||||
}, [
|
||||
duplicateLabel,
|
||||
exitButtonText,
|
||||
exportPopoverCsvLabel,
|
||||
exportPopoverMarkdownLabel,
|
||||
exportPopoverPdfLabel,
|
||||
hasDuplicate,
|
||||
hasEdit,
|
||||
hasExport,
|
||||
hasManageStakeholders,
|
||||
hasShare,
|
||||
onDuplicate,
|
||||
onEdit,
|
||||
onExit,
|
||||
onManageStakeholders,
|
||||
onSelectExportFormat,
|
||||
onShare,
|
||||
saveDraftOnExit,
|
||||
t,
|
||||
]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!exportMenuOpen) return;
|
||||
const onDoc = (e: MouseEvent) => {
|
||||
if (
|
||||
exportWrapRef.current &&
|
||||
!exportWrapRef.current.contains(e.target as Node)
|
||||
) {
|
||||
setExportMenuOpen(false);
|
||||
}
|
||||
};
|
||||
document.addEventListener("mousedown", onDoc);
|
||||
return () => document.removeEventListener("mousedown", onDoc);
|
||||
}, [exportMenuOpen]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!actionsMenuOpen) return;
|
||||
const onDoc = (e: MouseEvent) => {
|
||||
if (
|
||||
actionsWrapRef.current &&
|
||||
!actionsWrapRef.current.contains(e.target as Node)
|
||||
) {
|
||||
setActionsMenuOpen(false);
|
||||
}
|
||||
};
|
||||
document.addEventListener("mousedown", onDoc);
|
||||
return () => document.removeEventListener("mousedown", onDoc);
|
||||
}, [actionsMenuOpen]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!exportMenuOpen) return;
|
||||
const onKey = (e: KeyboardEvent) => {
|
||||
if (e.key === "Escape") setExportMenuOpen(false);
|
||||
};
|
||||
window.addEventListener("keydown", onKey);
|
||||
return () => window.removeEventListener("keydown", onKey);
|
||||
}, [exportMenuOpen]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!actionsMenuOpen) return;
|
||||
const onKey = (e: KeyboardEvent) => {
|
||||
if (e.key === "Escape") setActionsMenuOpen(false);
|
||||
};
|
||||
window.addEventListener("keydown", onKey);
|
||||
return () => window.removeEventListener("keydown", onKey);
|
||||
}, [actionsMenuOpen]);
|
||||
|
||||
const inlineActions = (
|
||||
<>
|
||||
|
||||
@@ -14,6 +14,7 @@ import { getAssetPath, ASSETS } from "../../../lib/assetUtils";
|
||||
*/
|
||||
const Footer = memo(() => {
|
||||
const t = useTranslation("footer");
|
||||
const tChrome = useTranslation("controlsChrome");
|
||||
|
||||
const linkFocusClass =
|
||||
"hover:opacity-80 active:opacity-60 focus:opacity-80 focus:outline-none focus:ring-2 focus:ring-[var(--color-content-default-primary)] focus:ring-offset-2 focus:ring-offset-[var(--color-surface-default-primary)] transition-opacity";
|
||||
@@ -129,7 +130,7 @@ const Footer = memo(() => {
|
||||
</div>
|
||||
|
||||
<nav
|
||||
aria-label="Footer"
|
||||
aria-label={tChrome("footerAriaLabel")}
|
||||
className="order-1 flex w-full max-w-full flex-col
|
||||
items-start
|
||||
gap-[var(--spacing-scale-032)]
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
"use client";
|
||||
|
||||
/**
|
||||
* Figma: "Utility / Menu Item" (see registry)
|
||||
*/
|
||||
|
||||
import { memo } from "react";
|
||||
import MenuItemView from "./MenuItem.view";
|
||||
import type { MenuItemProps } from "./MenuItem.types";
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
"use client";
|
||||
|
||||
/**
|
||||
* Figma: "Navigation / NavigationItem" (see registry)
|
||||
*/
|
||||
|
||||
import { memo } from "react";
|
||||
import NavigationItemView from "./NavigationItem.view";
|
||||
import type { NavigationItemProps } from "./NavigationItem.types";
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
"use client";
|
||||
|
||||
/**
|
||||
* Figma: "Navigation / Top" (22078-808559)
|
||||
*/
|
||||
|
||||
import { memo, useCallback } from "react";
|
||||
import { usePathname, useRouter } from "next/navigation";
|
||||
import { useAuthModal } from "../../../contexts/AuthModalContext";
|
||||
@@ -24,11 +28,17 @@ const NAV_SIZE_TO_MENU_ITEM_SIZE: Record<NavSize, MenuClusterSize> = {
|
||||
xlarge: "X Large",
|
||||
};
|
||||
|
||||
export const avatarImages = [
|
||||
{ src: getAssetPath(ASSETS.AVATAR_3), alt: "Avatar 3" },
|
||||
{ src: getAssetPath(ASSETS.AVATAR_2), alt: "Avatar 2" },
|
||||
{ src: getAssetPath(ASSETS.AVATAR_1), alt: "Avatar 1" },
|
||||
];
|
||||
export const avatarImageSources = [
|
||||
getAssetPath(ASSETS.AVATAR_3),
|
||||
getAssetPath(ASSETS.AVATAR_2),
|
||||
getAssetPath(ASSETS.AVATAR_1),
|
||||
] as const;
|
||||
|
||||
/** @deprecated Use `avatarImageSources` — alts are resolved in `TopContainer` via `topNav` messages. */
|
||||
export const avatarImages = avatarImageSources.map((src, index) => ({
|
||||
src,
|
||||
alt: `Avatar ${3 - index}`,
|
||||
}));
|
||||
|
||||
const TopContainer = memo<TopProps>(
|
||||
({ folderTop = false, loggedIn = false, profile = false, logIn = true }) => {
|
||||
@@ -36,6 +46,7 @@ const TopContainer = memo<TopProps>(
|
||||
const router = useRouter();
|
||||
const { openLogin } = useAuthModal();
|
||||
const t = useTranslation("header");
|
||||
const tTopNav = useTranslation("topNav");
|
||||
|
||||
/**
|
||||
* `Top` is hidden on `/create` routes by ConditionalNavigationClient, so
|
||||
@@ -58,7 +69,7 @@ const TopContainer = memo<TopProps>(
|
||||
name: "CommunityRule",
|
||||
url: "https://communityrule.com",
|
||||
...(folderTop && {
|
||||
description: "Build operating manuals for successful communities",
|
||||
description: tTopNav("schemaDescription"),
|
||||
}),
|
||||
potentialAction: {
|
||||
"@type": "SearchAction",
|
||||
@@ -110,11 +121,11 @@ const TopContainer = memo<TopProps>(
|
||||
) => {
|
||||
return (
|
||||
<AvatarContainer size={containerSize}>
|
||||
{avatarImages.map((avatar, index) => (
|
||||
{avatarImageSources.map((src, index) => (
|
||||
<Avatar
|
||||
key={index}
|
||||
src={avatar.src}
|
||||
alt={avatar.alt}
|
||||
src={src}
|
||||
alt={tTopNav(`avatarAlts.${3 - index}`)}
|
||||
size={avatarSize}
|
||||
/>
|
||||
))}
|
||||
|
||||
Reference in New Issue
Block a user