Implement create flow topnav and footer

This commit is contained in:
adilallo
2026-02-07 22:42:30 -07:00
parent 343b96a9bb
commit e6c1002dbb
10 changed files with 319 additions and 4 deletions
@@ -0,0 +1,49 @@
"use client";
import { memo } from "react";
import { useRouter } from "next/navigation";
import { CreateFlowTopNavView } from "./CreateFlowTopNav.view";
import type { CreateFlowTopNavProps } from "./CreateFlowTopNav.types";
const CreateFlowTopNavContainer = memo<CreateFlowTopNavProps>(
({
hasShare = false,
hasExport = false,
hasEdit = false,
loggedIn = false,
onShare,
onExport,
onEdit,
onExit,
className = "",
}) => {
const router = useRouter();
const handleExit = () => {
if (onExit) {
onExit();
} else {
// Default behavior: navigate to home
router.push("/");
}
};
return (
<CreateFlowTopNavView
hasShare={hasShare}
hasExport={hasExport}
hasEdit={hasEdit}
loggedIn={loggedIn}
onShare={onShare}
onExport={onExport}
onEdit={onEdit}
onExit={handleExit}
className={className}
/>
);
},
);
CreateFlowTopNavContainer.displayName = "CreateFlowTopNav";
export default CreateFlowTopNavContainer;
@@ -0,0 +1,49 @@
/**
* Type definitions for CreateFlowTopNav component
*
* Top navigation bar for the create rule flow.
* Includes logo and action buttons (Share, Export, Edit, Exit).
*/
export interface CreateFlowTopNavProps {
/**
* Whether to show the Share button
* @default false
*/
hasShare?: boolean;
/**
* Whether to show the Export button
* @default false
*/
hasExport?: boolean;
/**
* Whether to show the Edit button
* @default false
*/
hasEdit?: boolean;
/**
* Whether the user is logged in
* @default false
*/
loggedIn?: boolean;
/**
* Callback when Share button is clicked
*/
onShare?: () => void;
/**
* Callback when Export button is clicked
*/
onExport?: () => void;
/**
* Callback when Edit button is clicked
*/
onEdit?: () => void;
/**
* Callback when Exit/Save & Exit button is clicked
*/
onExit?: () => void;
/**
* Additional CSS classes
*/
className?: string;
}
@@ -0,0 +1,101 @@
import Logo from "../../icons/Logo";
import Button from "../../buttons/Button";
import type { CreateFlowTopNavProps } from "./CreateFlowTopNav.types";
export function CreateFlowTopNavView({
hasShare = false,
hasExport = false,
hasEdit = false,
loggedIn = false,
onShare,
onExport,
onEdit,
onExit,
className = "",
}: CreateFlowTopNavProps) {
const exitButtonText = loggedIn ? "Save & Exit" : "Exit";
return (
<header
className={`bg-black w-full border-b border-[var(--color-border-default-tertiary)] ${className}`}
role="banner"
aria-label="Create Rule Flow Navigation"
>
<nav
className="flex items-center justify-between mx-auto max-w-[639px] md:max-w-[1920px] px-[var(--spacing-measures-spacing-500,20px)] md:px-[48px] py-[var(--spacing-measures-spacing-300,12px)] md:py-[var(--spacing-measures-spacing-016,16px)]"
role="navigation"
aria-label="Create Flow Navigation"
>
{/* Logo - Left */}
<Logo size="createFlow" showText={true} />
{/* Button Group - Right */}
<div className="flex items-center gap-[var(--spacing-scale-012,12px)]">
{hasShare && (
<Button
buttonType="outline"
palette="default"
size="xsmall"
onClick={onShare}
ariaLabel="Share"
className="md:!text-[12px] md:!leading-[14px] !text-[10px] !leading-[12px] !px-[var(--spacing-scale-006,6px)] md:!px-[var(--spacing-scale-008,8px)] !py-[6px] md:!py-[8px] !border md:!border-[1.5px]"
>
Share
</Button>
)}
{hasExport && (
<Button
buttonType="outline"
palette="default"
size="xsmall"
onClick={onExport}
ariaLabel="Export"
className="justify-center gap-[var(--spacing-scale-002,2px)] !pl-[var(--spacing-scale-012,12px)] !pr-[var(--spacing-scale-006,6px)] md:!pr-[var(--spacing-scale-006,6px)] !text-[10px] md:!text-[12px] !leading-[12px] md:!leading-[14px] !py-[6px] md:!py-[8px] !border md:!border-[1.5px]"
>
<span>Export</span>
<svg
width="12"
height="12"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth={2}
strokeLinecap="round"
strokeLinejoin="round"
className="shrink-0 md:w-[14px] md:h-[14px]"
aria-hidden="true"
>
<path d="M19 9l-7 7-7-7" />
</svg>
</Button>
)}
{hasEdit && (
<Button
buttonType="outline"
palette="default"
size="xsmall"
onClick={onEdit}
ariaLabel="Edit"
className="md:!text-[12px] md:!leading-[14px] !text-[10px] !leading-[12px] !px-[var(--spacing-scale-006,6px)] md:!px-[var(--spacing-scale-008,8px)] !py-[6px] md:!py-[8px] !border md:!border-[1.5px]"
>
Edit
</Button>
)}
<Button
buttonType="outline"
palette="default"
size="xsmall"
onClick={onExit}
ariaLabel={exitButtonText}
className="md:!text-[12px] md:!leading-[14px] !text-[10px] !leading-[12px] !px-[var(--spacing-scale-006,6px)] md:!px-[var(--spacing-scale-008,8px)] !py-[6px] md:!py-[8px] !border md:!border-[1.5px]"
>
{exitButtonText}
</Button>
</div>
</nav>
</header>
);
}
@@ -0,0 +1,2 @@
export { default } from "./CreateFlowTopNav.container";
export type { CreateFlowTopNavProps } from "./CreateFlowTopNav.types";