feat(nx-dev): update top-level navbar
This commit is contained in:
parent
6904789b10
commit
9921496d64
@ -2,7 +2,7 @@
|
||||
title: Improve your architecture and CI pipeline times with Nx projects
|
||||
slug: improve-architecture-and-ci-times-with-projects
|
||||
authors: [Philip Fulcher]
|
||||
tags: [nx, enterprise]
|
||||
tags: [nx, 'customer story']
|
||||
cover_image: '/blog/images/2024-10-25/header.avif'
|
||||
pinned: true
|
||||
---
|
||||
|
||||
@ -2,6 +2,7 @@ import type { Metadata, ResolvingMetadata } from 'next';
|
||||
import { blogApi } from '../../../lib/blog.api';
|
||||
import { BlogDetails } from '@nx/nx-dev/ui-blog';
|
||||
import { DefaultLayout } from '@nx/nx-dev/ui-common';
|
||||
import { tryNxCloudForFree } from '../../../lib/components/headerCtaConfigs';
|
||||
|
||||
interface BlogPostDetailProps {
|
||||
params: { slug: string };
|
||||
@ -44,12 +45,13 @@ export async function generateStaticParams() {
|
||||
export default async function BlogPostDetail({
|
||||
params: { slug },
|
||||
}: BlogPostDetailProps) {
|
||||
const ctaHeaderConfig = [tryNxCloudForFree];
|
||||
const blog = await blogApi.getBlogPostBySlug(slug);
|
||||
return blog ? (
|
||||
<>
|
||||
{/* This empty div is necessary as app router does not automatically scroll on route changes */}
|
||||
<div></div>
|
||||
<DefaultLayout>
|
||||
<DefaultLayout headerCTAConfig={ctaHeaderConfig}>
|
||||
<BlogDetails post={blog} />
|
||||
</DefaultLayout>
|
||||
</>
|
||||
|
||||
@ -3,6 +3,10 @@ import { blogApi } from '../../lib/blog.api';
|
||||
import { BlogContainer } from '@nx/nx-dev/ui-blog';
|
||||
import { DefaultLayout } from '@nx/nx-dev/ui-common';
|
||||
import { Suspense } from 'react';
|
||||
import {
|
||||
requestFreeTrial,
|
||||
tryNxCloudForFree,
|
||||
} from '../../lib/components/headerCtaConfigs';
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: 'Nx Blog - Updates from the Nx & Nx Cloud team',
|
||||
@ -34,11 +38,13 @@ async function getBlogTags() {
|
||||
}
|
||||
|
||||
export default async function BlogIndex() {
|
||||
const ctaHeaderConfig = [tryNxCloudForFree];
|
||||
|
||||
const blogs = await getBlogs();
|
||||
const tags = await getBlogTags();
|
||||
return (
|
||||
<Suspense>
|
||||
<DefaultLayout>
|
||||
<DefaultLayout headerCTAConfig={ctaHeaderConfig}>
|
||||
<BlogContainer blogPosts={blogs} tags={tags} />
|
||||
</DefaultLayout>
|
||||
</Suspense>
|
||||
|
||||
@ -9,7 +9,11 @@ import {
|
||||
Statistics,
|
||||
} from '@nx/nx-dev/ui-cloud';
|
||||
|
||||
import { CallToAction, DefaultLayout } from '@nx/nx-dev/ui-common';
|
||||
import {
|
||||
ButtonLinkProps,
|
||||
CallToAction,
|
||||
DefaultLayout,
|
||||
} from '@nx/nx-dev/ui-common';
|
||||
|
||||
import type { Metadata } from 'next';
|
||||
|
||||
@ -37,8 +41,18 @@ export const metadata: Metadata = {
|
||||
};
|
||||
|
||||
export default function NxCloudPage(): JSX.Element {
|
||||
const headerCTAConfig: ButtonLinkProps[] = [
|
||||
{
|
||||
href: '/pricing',
|
||||
variant: 'primary',
|
||||
size: 'small',
|
||||
title: 'Get started for free',
|
||||
children: 'Get started for free',
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<DefaultLayout>
|
||||
<DefaultLayout headerCTAConfig={headerCTAConfig}>
|
||||
<Hero />
|
||||
<TrustedBy />
|
||||
|
||||
|
||||
@ -1,10 +1,11 @@
|
||||
import { DefaultLayout } from '@nx/nx-dev/ui-common';
|
||||
import { ButtonLinkProps, DefaultLayout } from '@nx/nx-dev/ui-common';
|
||||
import {
|
||||
CallToAction,
|
||||
GetStarted,
|
||||
Hero,
|
||||
PowerpackFeatures,
|
||||
} from '@nx/nx-dev/ui-powerpack';
|
||||
import { contactButton } from '../../lib/components/headerCtaConfigs';
|
||||
|
||||
import type { Metadata } from 'next';
|
||||
|
||||
@ -32,8 +33,18 @@ export const metadata: Metadata = {
|
||||
};
|
||||
|
||||
export default function NxPowerPackPage(): JSX.Element {
|
||||
const headerCTAConfig: ButtonLinkProps[] = [
|
||||
{
|
||||
href: 'https://cloud.nx.app/powerpack/purchase?licenseBusinessType=small&utm_source=nx.dev&utm_medium=referral&utm_campaign=nx-powerpackurl',
|
||||
variant: 'primary',
|
||||
size: 'small',
|
||||
title: 'Request a free trial',
|
||||
children: 'Request a free trial',
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<DefaultLayout>
|
||||
<DefaultLayout headerCTAConfig={headerCTAConfig}>
|
||||
<Hero />
|
||||
|
||||
<div className="mt-32 scroll-mt-32 lg:mt-56" id="features">
|
||||
|
||||
@ -12,6 +12,7 @@ import {
|
||||
Testimonials,
|
||||
TrustedBy,
|
||||
} from '@nx/nx-dev/ui-common';
|
||||
import { gotoAppButton } from '../../lib/components/headerCtaConfigs';
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: 'Nx Cloud - Available Plans',
|
||||
@ -38,7 +39,7 @@ export const metadata: Metadata = {
|
||||
|
||||
export default function PricingPage() {
|
||||
return (
|
||||
<DefaultLayout>
|
||||
<DefaultLayout headerCTAConfig={[gotoAppButton]}>
|
||||
<PlansDisplay />
|
||||
<div className="mt-18 lg:mt-32">
|
||||
<TrustedBy utmSource="pricingpage" utmCampaign="pricing" />
|
||||
|
||||
41
nx-dev/nx-dev/lib/components/headerCtaConfigs.tsx
Normal file
41
nx-dev/nx-dev/lib/components/headerCtaConfigs.tsx
Normal file
@ -0,0 +1,41 @@
|
||||
import { ButtonLinkProps } from '@nx/nx-dev/ui-common';
|
||||
import { NxCloudAnimatedIcon } from '@nx/nx-dev/ui-icons';
|
||||
|
||||
export const requestFreeTrial: ButtonLinkProps = {
|
||||
href: '/contact/sales',
|
||||
variant: 'primary',
|
||||
size: 'small',
|
||||
title: 'Request a free trial',
|
||||
children: 'Request a free trial',
|
||||
};
|
||||
|
||||
export const tryNxCloudForFree: ButtonLinkProps = {
|
||||
href: '/pricing',
|
||||
variant: 'primary',
|
||||
size: 'small',
|
||||
title: 'Try Nx Cloud for free',
|
||||
children: 'Try Nx Cloud for free',
|
||||
};
|
||||
|
||||
export const gotoAppButton: ButtonLinkProps = {
|
||||
href: 'https://nx.app/?utm_source=nx.dev&utm_medium=header-menu',
|
||||
variant: 'secondary',
|
||||
size: 'small',
|
||||
target: '_blank',
|
||||
title: 'Log in to your Nx Cloud Account',
|
||||
children: (
|
||||
<>
|
||||
<NxCloudAnimatedIcon className="h-4 w-4" aria-hidden="true" />
|
||||
<span>Go to app</span>
|
||||
</>
|
||||
),
|
||||
};
|
||||
|
||||
export const contactButton: ButtonLinkProps = {
|
||||
href: '/contact',
|
||||
variant: 'secondary',
|
||||
size: 'small',
|
||||
target: '_blank',
|
||||
title: 'Contact Us',
|
||||
children: <span>Contact</span>,
|
||||
};
|
||||
@ -6,6 +6,7 @@ import {
|
||||
Hero,
|
||||
OssProjects,
|
||||
} from '@nx/nx-dev/ui-customers';
|
||||
import { tryNxCloudForFree } from '../lib/components/headerCtaConfigs';
|
||||
|
||||
export function Customers(): JSX.Element {
|
||||
const router = useRouter();
|
||||
@ -33,7 +34,7 @@ export function Customers(): JSX.Element {
|
||||
type: 'website',
|
||||
}}
|
||||
/>
|
||||
<DefaultLayout>
|
||||
<DefaultLayout headerCTAConfig={[tryNxCloudForFree]}>
|
||||
<div>
|
||||
<Hero />
|
||||
</div>
|
||||
|
||||
@ -13,6 +13,7 @@ import {
|
||||
SolveYourCi,
|
||||
} from '@nx/nx-dev/ui-enterprise';
|
||||
import { TrialCallout } from '@nx/nx-dev/ui-pricing';
|
||||
import { requestFreeTrial } from '../lib/components/headerCtaConfigs';
|
||||
|
||||
export function Enterprise(): JSX.Element {
|
||||
const router = useRouter();
|
||||
@ -40,7 +41,7 @@ export function Enterprise(): JSX.Element {
|
||||
type: 'website',
|
||||
}}
|
||||
/>
|
||||
<DefaultLayout>
|
||||
<DefaultLayout headerCTAConfig={[requestFreeTrial]}>
|
||||
<div>
|
||||
<Hero />
|
||||
</div>
|
||||
|
||||
@ -8,8 +8,15 @@ import {
|
||||
TeamAndCommunity,
|
||||
WorkBetterAchieveMoreShipQuicker,
|
||||
} from '@nx/nx-dev/ui-home';
|
||||
import {
|
||||
requestFreeTrial,
|
||||
gotoAppButton,
|
||||
contactButton,
|
||||
} from '../lib/components/headerCtaConfigs';
|
||||
|
||||
export default function Index(): JSX.Element {
|
||||
const headerCTAConfig = [contactButton];
|
||||
|
||||
return (
|
||||
<>
|
||||
<NextSeo
|
||||
@ -34,7 +41,7 @@ export default function Index(): JSX.Element {
|
||||
}}
|
||||
/>
|
||||
<h1 className="sr-only">Build system with advanced CI capabilities.</h1>
|
||||
<DefaultLayout isHome>
|
||||
<DefaultLayout isHome headerCTAConfig={headerCTAConfig}>
|
||||
<Hero />
|
||||
<div className="mt-16 lg:-mt-32">
|
||||
<Statistics />
|
||||
|
||||
@ -7,6 +7,7 @@ import { ComponentProps, Fragment, useState } from 'react';
|
||||
import { ButtonLink, SectionHeading } from '@nx/nx-dev/ui-common';
|
||||
import { MovingBorder } from '@nx/nx-dev/ui-animations';
|
||||
import Image from 'next/image';
|
||||
import { NxCloudAnimatedIcon } from '@nx/nx-dev/ui-icons';
|
||||
|
||||
export function Hero(): JSX.Element {
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
@ -31,7 +32,8 @@ export function Hero(): JSX.Element {
|
||||
variant="primary"
|
||||
size="default"
|
||||
>
|
||||
Get started
|
||||
<NxCloudAnimatedIcon className="h-4 w-4" aria-hidden="true" />
|
||||
<span>Go to app</span>
|
||||
</ButtonLink>
|
||||
<ButtonLink
|
||||
href="/ci/intro/ci-with-nx"
|
||||
|
||||
@ -25,12 +25,12 @@ export * from './lib/square-dotted-pattern';
|
||||
export * from './lib/live-stream-notifier';
|
||||
|
||||
export { resourceMenuItems } from './lib/headers/menu-items';
|
||||
export { solutionsMenuItems } from './lib/headers/menu-items';
|
||||
export { productsMenuItems as solutionsMenuItems } from './lib/headers/menu-items';
|
||||
export { eventItems } from './lib/headers/menu-items';
|
||||
export { learnItems } from './lib/headers/menu-items';
|
||||
export { companyItems } from './lib/headers/menu-items';
|
||||
export type { MenuItem } from './lib/headers/menu-items';
|
||||
export { solutions as plans } from './lib/headers/menu-items';
|
||||
export { ossProducts as plans } from './lib/headers/menu-items';
|
||||
export { featuresItems } from './lib/headers/menu-items';
|
||||
export { DefaultMenuItem } from './lib/headers/default-menu-item';
|
||||
export { MobileMenuItem } from './lib/headers/mobile-menu-item';
|
||||
|
||||
@ -17,6 +17,12 @@ interface ButtonProps {
|
||||
children: ReactNode | ReactNode[];
|
||||
}
|
||||
|
||||
export type ButtonLinkProps = ButtonProps & {
|
||||
className?: string;
|
||||
href: string;
|
||||
title: string;
|
||||
} & AnchorHTMLAttributes<HTMLAnchorElement>;
|
||||
|
||||
const variantStyles: Record<AllowedVariants, string> = {
|
||||
primary:
|
||||
'bg-blue-500 dark:bg-sky-500 text-white group-hover:bg-blue-600 dark:group-hover:bg-sky-600 group-focus:ring-2 group-focus:ring-blue-500 dark:group-focus:ring-sky-500 focus:group-ring-offset-2',
|
||||
@ -99,11 +105,7 @@ export const ButtonLink = forwardRef(function (
|
||||
variant = 'primary',
|
||||
title = '',
|
||||
...props
|
||||
}: ButtonProps & {
|
||||
className?: string;
|
||||
href: string;
|
||||
title: string;
|
||||
} & AnchorHTMLAttributes<HTMLAnchorElement>,
|
||||
}: ButtonLinkProps,
|
||||
ref: ForwardedRef<HTMLAnchorElement>
|
||||
): JSX.Element {
|
||||
return (
|
||||
|
||||
@ -1,21 +1,23 @@
|
||||
import { Footer } from './footer';
|
||||
import { Header } from './headers/header';
|
||||
import { PropsWithChildren } from 'react';
|
||||
import cx from 'classnames';
|
||||
import { ButtonLinkProps } from './button';
|
||||
|
||||
export function DefaultLayout({
|
||||
isHome = false,
|
||||
children,
|
||||
hideHeader = false,
|
||||
hideFooter = false,
|
||||
headerCTAConfig,
|
||||
}: {
|
||||
isHome?: boolean;
|
||||
hideHeader?: boolean;
|
||||
hideFooter?: boolean;
|
||||
headerCTAConfig?: ButtonLinkProps[];
|
||||
} & PropsWithChildren): JSX.Element {
|
||||
return (
|
||||
<div className="w-full overflow-hidden dark:bg-slate-950">
|
||||
{!hideHeader && <Header />}
|
||||
{!hideHeader && <Header ctaButtons={headerCTAConfig} />}
|
||||
<div className="relative isolate">
|
||||
<div
|
||||
className="absolute inset-x-0 -top-40 -z-10 h-full transform-gpu overflow-hidden blur-3xl sm:-top-80"
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
'use client';
|
||||
import { Fragment, type JSX } from 'react';
|
||||
|
||||
import { GitHubIcon } from '@nx/nx-dev/ui-icons';
|
||||
import {
|
||||
Bars3Icon,
|
||||
ChevronDownIcon,
|
||||
@ -13,9 +15,13 @@ import { ButtonLink } from '../button';
|
||||
import { Popover, Transition } from '@headlessui/react';
|
||||
import { TwoColumnsMenu } from './two-columns-menu';
|
||||
import {
|
||||
companyItems,
|
||||
eventItems,
|
||||
featuresItems,
|
||||
learnItems,
|
||||
ossProducts,
|
||||
resourceMenuItems,
|
||||
solutionsMenuItems,
|
||||
productsMenuItems,
|
||||
} from './menu-items';
|
||||
import { SectionsMenu } from './sections-menu';
|
||||
import { DiscordIcon } from '../discord-icon';
|
||||
@ -224,103 +230,6 @@ export function DocumentationHeader({
|
||||
className="items-justified hidden justify-center space-x-2 text-sm lg:flex"
|
||||
>
|
||||
<h2 className="sr-only">Main navigation</h2>
|
||||
{/*FEATURES*/}
|
||||
<Popover className="relative">
|
||||
{({ open }) => (
|
||||
<>
|
||||
<Popover.Button
|
||||
className={cx(
|
||||
open ? 'text-blue-500 dark:text-sky-500' : '',
|
||||
'group inline-flex items-center gap-2 px-3 py-2 font-medium leading-tight outline-0 dark:text-slate-200'
|
||||
)}
|
||||
>
|
||||
<span
|
||||
className={cx(
|
||||
open ? 'text-blue-500 dark:text-sky-500' : '',
|
||||
'transition duration-150 ease-in-out group-hover:text-blue-500 dark:group-hover:text-sky-500'
|
||||
)}
|
||||
>
|
||||
Features
|
||||
</span>
|
||||
<ChevronDownIcon
|
||||
aria-hidden="true"
|
||||
className={cx(
|
||||
open
|
||||
? 'rotate-180 transform text-blue-500 dark:text-sky-500'
|
||||
: '',
|
||||
'h-3 w-3 transition duration-150 ease-in-out group-hover:text-blue-500 dark:group-hover:text-sky-500'
|
||||
)}
|
||||
/>
|
||||
</Popover.Button>
|
||||
<Transition
|
||||
as={Fragment}
|
||||
enter="transition ease-out duration-200"
|
||||
enterFrom="opacity-0 translate-y-1"
|
||||
enterTo="opacity-100 translate-y-0"
|
||||
leave="transition ease-in duration-150"
|
||||
leaveFrom="opacity-100 translate-y-0"
|
||||
leaveTo="opacity-0 translate-y-1"
|
||||
>
|
||||
<Popover.Panel className="absolute z-30 mt-3 w-max max-w-3xl xl:max-w-3xl">
|
||||
<SectionsMenu sections={featuresItems} />
|
||||
</Popover.Panel>
|
||||
</Transition>
|
||||
</>
|
||||
)}
|
||||
</Popover>
|
||||
{/*SOLUTIONS*/}
|
||||
<Popover className="relative">
|
||||
{({ open }) => (
|
||||
<>
|
||||
<Popover.Button
|
||||
className={cx(
|
||||
open ? 'text-blue-500 dark:text-sky-500' : '',
|
||||
'group inline-flex items-center px-3 py-2 font-medium leading-tight outline-0 dark:text-slate-200'
|
||||
)}
|
||||
>
|
||||
<span
|
||||
className={cx(
|
||||
open ? 'text-blue-500 dark:text-sky-500' : '',
|
||||
'transition duration-150 ease-in-out group-hover:text-blue-500 dark:group-hover:text-sky-500'
|
||||
)}
|
||||
>
|
||||
Solutions
|
||||
</span>
|
||||
<ChevronDownIcon
|
||||
className={cx(
|
||||
open
|
||||
? 'rotate-180 transform text-blue-500 dark:text-sky-500'
|
||||
: '',
|
||||
'ml-2 h-3 w-3 transition duration-150 ease-in-out group-hover:text-blue-500 dark:group-hover:text-sky-500'
|
||||
)}
|
||||
aria-hidden="true"
|
||||
/>
|
||||
</Popover.Button>
|
||||
|
||||
<Transition
|
||||
as={Fragment}
|
||||
enter="transition ease-out duration-200"
|
||||
enterFrom="opacity-0 translate-y-1"
|
||||
enterTo="opacity-100 translate-y-0"
|
||||
leave="transition ease-in duration-150"
|
||||
leaveFrom="opacity-100 translate-y-0"
|
||||
leaveTo="opacity-0 translate-y-1"
|
||||
>
|
||||
<Popover.Panel className="absolute z-30 mt-3 w-max max-w-2xl">
|
||||
<SectionsMenu sections={solutionsMenuItems} />
|
||||
</Popover.Panel>
|
||||
</Transition>
|
||||
</>
|
||||
)}
|
||||
</Popover>
|
||||
<Link
|
||||
href="/getting-started/intro"
|
||||
title="Documentation"
|
||||
className="hidden px-3 py-2 font-medium leading-tight hover:text-blue-500 md:inline-flex dark:text-slate-200 dark:hover:text-sky-500"
|
||||
prefetch={false}
|
||||
>
|
||||
Docs
|
||||
</Link>
|
||||
<Link
|
||||
href="/blog"
|
||||
title="Blog"
|
||||
@ -329,14 +238,6 @@ export function DocumentationHeader({
|
||||
>
|
||||
Blog
|
||||
</Link>
|
||||
<Link
|
||||
href="/pricing"
|
||||
title="Nx Cloud"
|
||||
className="hidden gap-2 px-3 py-2 font-medium leading-tight hover:text-blue-500 md:inline-flex dark:text-slate-200 dark:hover:text-sky-500"
|
||||
prefetch={false}
|
||||
>
|
||||
CI Pricing
|
||||
</Link>
|
||||
{/*RESOURCES*/}
|
||||
<Popover className="relative">
|
||||
{({ open }) => (
|
||||
@ -377,6 +278,40 @@ export function DocumentationHeader({
|
||||
</>
|
||||
)}
|
||||
</Popover>
|
||||
<div className="hidden h-6 w-px bg-slate-200 md:block dark:bg-slate-700" />
|
||||
<Link
|
||||
href="/nx-cloud"
|
||||
title="Nx Cloud"
|
||||
className="hidden gap-2 px-3 py-2 font-medium leading-tight hover:text-blue-500 md:inline-flex dark:text-slate-200 dark:hover:text-sky-500"
|
||||
prefetch={false}
|
||||
>
|
||||
Nx Cloud
|
||||
</Link>
|
||||
<Link
|
||||
href="/pricing"
|
||||
title="Pricing"
|
||||
className="hidden gap-2 px-3 py-2 font-medium leading-tight hover:text-blue-500 md:inline-flex dark:text-slate-200 dark:hover:text-sky-500"
|
||||
prefetch={false}
|
||||
>
|
||||
Pricing
|
||||
</Link>
|
||||
<div className="hidden h-6 w-px bg-slate-200 md:block dark:bg-slate-700" />
|
||||
<Link
|
||||
href="/powerpack"
|
||||
title="Nx Powerpack"
|
||||
className="hidden gap-2 px-3 py-2 font-medium leading-tight hover:text-blue-500 md:inline-flex dark:text-slate-200 dark:hover:text-sky-500"
|
||||
prefetch={false}
|
||||
>
|
||||
Powerpack
|
||||
</Link>
|
||||
<Link
|
||||
href="/enterprise"
|
||||
title="Nx Enterprise"
|
||||
className="hidden gap-2 px-3 py-2 font-medium leading-tight hover:text-blue-500 md:inline-flex dark:text-slate-200 dark:hover:text-sky-500"
|
||||
prefetch={false}
|
||||
>
|
||||
Enterprise
|
||||
</Link>
|
||||
</nav>
|
||||
</div>
|
||||
<div className="hidden flex-grow lg:flex">{/* SPACER */}</div>
|
||||
@ -385,22 +320,14 @@ export function DocumentationHeader({
|
||||
role="menu"
|
||||
className="items-justified hidden justify-center space-x-4 lg:flex"
|
||||
>
|
||||
<Link
|
||||
className="hidden cursor-pointer px-3 py-2 text-sm font-medium leading-tight hover:text-blue-500 md:inline-flex dark:text-slate-200 dark:hover:text-sky-500"
|
||||
title="Contact Us"
|
||||
href="/contact"
|
||||
prefetch={false}
|
||||
>
|
||||
Contact
|
||||
</Link>
|
||||
<ButtonLink
|
||||
href="https://nx.app/?utm_source=nx.dev&utm_medium=header-menu"
|
||||
title="Go to app"
|
||||
variant="secondary"
|
||||
href="/nx-cloud"
|
||||
title="Try Nx Cloud for free"
|
||||
variant="primary"
|
||||
size="small"
|
||||
>
|
||||
<NxCloudAnimatedIcon className="h-4 w-4" aria-hidden="true" />
|
||||
<span>Go to app</span>
|
||||
<span>Try Nx Cloud for free</span>
|
||||
</ButtonLink>
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
@ -8,15 +8,16 @@ import {
|
||||
import cx from 'classnames';
|
||||
import Link from 'next/link';
|
||||
import { Fragment, useEffect, useState } from 'react';
|
||||
import { ButtonLink } from '../button';
|
||||
import { ButtonLink, ButtonLinkProps } from '../button';
|
||||
import {
|
||||
companyItems,
|
||||
eventItems,
|
||||
featuresItems,
|
||||
learnItems,
|
||||
solutions,
|
||||
ossProducts,
|
||||
resourceMenuItems,
|
||||
solutionsMenuItems,
|
||||
productsMenuItems,
|
||||
enterpriseResourcesMenuItems,
|
||||
} from './menu-items';
|
||||
import { MobileMenuItem } from './mobile-menu-item';
|
||||
import { SectionsMenu } from './sections-menu';
|
||||
@ -24,7 +25,11 @@ import { TwoColumnsMenu } from './two-columns-menu';
|
||||
import { AlgoliaSearch } from '@nx/nx-dev/feature-search';
|
||||
import { GitHubIcon, NxCloudAnimatedIcon, NxIcon } from '@nx/nx-dev/ui-icons';
|
||||
|
||||
export function Header(): JSX.Element {
|
||||
interface HeaderProps {
|
||||
ctaButtons?: ButtonLinkProps[];
|
||||
}
|
||||
|
||||
export function Header({ ctaButtons }: HeaderProps): JSX.Element {
|
||||
let [isOpen, setIsOpen] = useState(false);
|
||||
|
||||
// We need to close the popover if the route changes or the window is resized to prevent the popover from being stuck open.
|
||||
@ -42,6 +47,19 @@ export function Header(): JSX.Element {
|
||||
};
|
||||
}, []);
|
||||
|
||||
const defaultCtaButtons: ButtonLinkProps[] = [
|
||||
{
|
||||
href: '/nx-cloud',
|
||||
variant: 'primary',
|
||||
size: 'small',
|
||||
target: '_blank',
|
||||
title: 'Try Nx Cloud for free',
|
||||
children: <span>Try Nx Cloud for free</span>,
|
||||
},
|
||||
];
|
||||
|
||||
const buttonsToRender = ctaButtons || defaultCtaButtons;
|
||||
|
||||
return (
|
||||
<div className="fixed inset-x-0 top-0 isolate z-[5] flex px-4 print:hidden">
|
||||
<div
|
||||
@ -69,95 +87,6 @@ export function Header(): JSX.Element {
|
||||
className="items-justified flex items-center justify-center space-x-2 py-0.5"
|
||||
>
|
||||
<h2 className="sr-only">Main navigation</h2>
|
||||
{/*FEATURES*/}
|
||||
<Popover className="relative">
|
||||
{({ open }) => (
|
||||
<>
|
||||
<Popover.Button
|
||||
className={cx(
|
||||
open ? 'text-blue-500 dark:text-sky-500' : '',
|
||||
'group inline-flex items-center gap-2 px-3 py-2 font-medium leading-tight outline-0 dark:text-slate-200'
|
||||
)}
|
||||
>
|
||||
<span
|
||||
className={cx(
|
||||
open ? 'text-blue-500 dark:text-sky-500' : '',
|
||||
'transition duration-150 ease-in-out group-hover:text-blue-500 dark:group-hover:text-sky-500'
|
||||
)}
|
||||
>
|
||||
Features
|
||||
</span>
|
||||
<ChevronDownIcon
|
||||
aria-hidden="true"
|
||||
className={cx(
|
||||
open
|
||||
? 'rotate-180 transform text-blue-500 dark:text-sky-500'
|
||||
: '',
|
||||
'h-3 w-3 transition duration-150 ease-in-out group-hover:text-blue-500 dark:group-hover:text-sky-500'
|
||||
)}
|
||||
/>
|
||||
</Popover.Button>
|
||||
<Transition
|
||||
as={Fragment}
|
||||
enter="transition ease-out duration-200"
|
||||
enterFrom="opacity-0 translate-y-1"
|
||||
enterTo="opacity-100 translate-y-0"
|
||||
leave="transition ease-in duration-150"
|
||||
leaveFrom="opacity-100 translate-y-0"
|
||||
leaveTo="opacity-0 translate-y-1"
|
||||
>
|
||||
<Popover.Panel className="absolute z-10 mt-3 w-max max-w-3xl xl:max-w-3xl">
|
||||
<SectionsMenu sections={featuresItems} />
|
||||
</Popover.Panel>
|
||||
</Transition>
|
||||
</>
|
||||
)}
|
||||
</Popover>
|
||||
{/*SOLUTIONS*/}
|
||||
<Popover className="relative">
|
||||
{({ open }) => (
|
||||
<>
|
||||
<Popover.Button
|
||||
className={cx(
|
||||
open ? 'text-blue-500 dark:text-sky-500' : '',
|
||||
'group inline-flex items-center px-3 py-2 font-medium leading-tight outline-0 dark:text-slate-200'
|
||||
)}
|
||||
>
|
||||
<span
|
||||
className={cx(
|
||||
open ? 'text-blue-500 dark:text-sky-500' : '',
|
||||
'transition duration-150 ease-in-out group-hover:text-blue-500 dark:group-hover:text-sky-500'
|
||||
)}
|
||||
>
|
||||
Solutions
|
||||
</span>
|
||||
<ChevronDownIcon
|
||||
className={cx(
|
||||
open
|
||||
? 'rotate-180 transform text-blue-500 dark:text-sky-500'
|
||||
: '',
|
||||
'ml-2 h-3 w-3 transition duration-150 ease-in-out group-hover:text-blue-500 dark:group-hover:text-sky-500'
|
||||
)}
|
||||
aria-hidden="true"
|
||||
/>
|
||||
</Popover.Button>
|
||||
|
||||
<Transition
|
||||
as={Fragment}
|
||||
enter="transition ease-out duration-200"
|
||||
enterFrom="opacity-0 translate-y-1"
|
||||
enterTo="opacity-100 translate-y-0"
|
||||
leave="transition ease-in duration-150"
|
||||
leaveFrom="opacity-100 translate-y-0"
|
||||
leaveTo="opacity-0 translate-y-1"
|
||||
>
|
||||
<Popover.Panel className="absolute z-10 mt-3 w-max max-w-2xl">
|
||||
<SectionsMenu sections={solutionsMenuItems} />
|
||||
</Popover.Panel>
|
||||
</Transition>
|
||||
</>
|
||||
)}
|
||||
</Popover>
|
||||
<Link
|
||||
href="/getting-started/intro"
|
||||
title="Documentation"
|
||||
@ -174,14 +103,6 @@ export function Header(): JSX.Element {
|
||||
>
|
||||
Blog
|
||||
</Link>
|
||||
<Link
|
||||
href="/pricing"
|
||||
title="Nx Cloud"
|
||||
className="hidden gap-2 px-3 py-2 font-medium leading-tight hover:text-blue-500 md:inline-flex dark:text-slate-200 dark:hover:text-sky-500"
|
||||
prefetch={false}
|
||||
>
|
||||
CI Pricing
|
||||
</Link>
|
||||
{/*RESOURCES*/}
|
||||
<Popover className="relative">
|
||||
{({ open }) => (
|
||||
@ -215,14 +136,49 @@ export function Header(): JSX.Element {
|
||||
leaveFrom="opacity-100 translate-y-0"
|
||||
leaveTo="opacity-0 translate-y-1"
|
||||
>
|
||||
<Popover.Panel className="absolute left-60 z-10 mt-3 w-max max-w-2xl -translate-x-1/2 transform lg:left-20">
|
||||
<Popover.Panel className="absolute left-60 z-30 mt-3 w-max max-w-2xl -translate-x-1/2 transform lg:left-20">
|
||||
<SectionsMenu sections={resourceMenuItems} />
|
||||
</Popover.Panel>
|
||||
</Transition>
|
||||
</>
|
||||
)}
|
||||
</Popover>
|
||||
<div className="opacity-50 hover:opacity-100">
|
||||
<div className="hidden h-6 w-px bg-slate-200 md:block dark:bg-slate-700" />
|
||||
<Link
|
||||
href="/nx-cloud"
|
||||
title="Nx Cloud"
|
||||
className="hidden gap-2 px-3 py-2 font-medium leading-tight hover:text-blue-500 md:inline-flex dark:text-slate-200 dark:hover:text-sky-500"
|
||||
prefetch={false}
|
||||
>
|
||||
Nx Cloud
|
||||
</Link>
|
||||
<Link
|
||||
href="/pricing"
|
||||
title="Pricing"
|
||||
className="hidden gap-2 px-3 py-2 font-medium leading-tight hover:text-blue-500 md:inline-flex dark:text-slate-200 dark:hover:text-sky-500"
|
||||
prefetch={false}
|
||||
>
|
||||
Pricing
|
||||
</Link>
|
||||
<div className="hidden h-6 w-px bg-slate-200 md:block dark:bg-slate-700" />
|
||||
<Link
|
||||
href="/powerpack"
|
||||
title="Nx Powerpack"
|
||||
className="hidden gap-2 px-3 py-2 font-medium leading-tight hover:text-blue-500 md:inline-flex dark:text-slate-200 dark:hover:text-sky-500"
|
||||
prefetch={false}
|
||||
>
|
||||
Powerpack
|
||||
</Link>
|
||||
<Link
|
||||
href="/enterprise"
|
||||
title="Nx Enterprise"
|
||||
className="hidden gap-2 px-3 py-2 font-medium leading-tight hover:text-blue-500 md:inline-flex dark:text-slate-200 dark:hover:text-sky-500"
|
||||
prefetch={false}
|
||||
>
|
||||
Enterprise
|
||||
</Link>
|
||||
<div className="hidden h-6 w-px bg-slate-200 md:block dark:bg-slate-700" />
|
||||
<div className="px-3 opacity-50 hover:opacity-100">
|
||||
<AlgoliaSearch tiny={true} />
|
||||
</div>
|
||||
</nav>
|
||||
@ -230,24 +186,9 @@ export function Header(): JSX.Element {
|
||||
{/*SECONDARY NAVIGATION*/}
|
||||
<div className="flex-shrink-0 text-sm">
|
||||
<nav className="flex items-center justify-center space-x-1">
|
||||
<Link
|
||||
className="hidden cursor-pointer px-3 py-2 font-medium leading-tight hover:text-blue-500 md:inline-flex dark:text-slate-200 dark:hover:text-sky-500"
|
||||
title="Contact Us"
|
||||
href="/contact"
|
||||
prefetch={false}
|
||||
>
|
||||
Contact
|
||||
</Link>
|
||||
<ButtonLink
|
||||
href="https://cloud.nx.app"
|
||||
variant="secondary"
|
||||
size="small"
|
||||
target="_blank"
|
||||
title="Log in to your Nx Cloud Account"
|
||||
>
|
||||
<NxCloudAnimatedIcon className="h-4 w-4" aria-hidden="true" />
|
||||
<span>Go to app</span>
|
||||
</ButtonLink>
|
||||
{buttonsToRender.map((buttonProps, index) => (
|
||||
<ButtonLink key={index} {...buttonProps} />
|
||||
))}
|
||||
<a
|
||||
title="Nx is open source, check the code on GitHub"
|
||||
href="https://github.com/nrwl/nx"
|
||||
@ -359,90 +300,17 @@ export function Header(): JSX.Element {
|
||||
</div>
|
||||
<div className="relative mt-6 flex-1 px-4 sm:px-6">
|
||||
<ButtonLink
|
||||
href="https://cloud.nx.app"
|
||||
href="/nx-cloud"
|
||||
variant="primary"
|
||||
size="small"
|
||||
target="_blank"
|
||||
title="Log in to your Nx Cloud Account"
|
||||
title="Try Nx Cloud for free"
|
||||
className="w-full"
|
||||
>
|
||||
Go to app
|
||||
Try Nx Cloud for free
|
||||
</ButtonLink>
|
||||
|
||||
<div className="mt-4 divide-y divide-slate-200 border-b border-slate-200 dark:divide-slate-800 dark:border-slate-800">
|
||||
{/*FEATURES*/}
|
||||
<Disclosure as="div">
|
||||
{({ open }) => (
|
||||
<>
|
||||
<Disclosure.Button
|
||||
className={cx(
|
||||
open
|
||||
? 'text-blue-500 dark:text-sky-500'
|
||||
: 'tex-slate-800 dark:text-slate-200',
|
||||
'flex w-full items-center justify-between py-4 text-left text-base font-medium focus:outline-none'
|
||||
)}
|
||||
>
|
||||
<span>Features</span>
|
||||
<ChevronDownIcon
|
||||
aria-hidden="true"
|
||||
className={cx(
|
||||
open
|
||||
? 'rotate-180 transform text-blue-500 dark:text-sky-500'
|
||||
: 'tex-slate-800 dark:text-slate-200',
|
||||
'h-3 w-3 transition duration-150 ease-in-out group-hover:text-blue-500 dark:group-hover:text-sky-500'
|
||||
)}
|
||||
/>
|
||||
</Disclosure.Button>
|
||||
<Disclosure.Panel
|
||||
as="ul"
|
||||
className="space-y-1 pb-2"
|
||||
>
|
||||
{Object.values(featuresItems)
|
||||
.flat()
|
||||
.map((item) => (
|
||||
<MobileMenuItem
|
||||
key={item.name}
|
||||
item={item}
|
||||
/>
|
||||
))}
|
||||
</Disclosure.Panel>
|
||||
</>
|
||||
)}
|
||||
</Disclosure>
|
||||
{/*SOLUTIONS*/}
|
||||
<Disclosure as="div">
|
||||
{({ open }) => (
|
||||
<>
|
||||
<Disclosure.Button
|
||||
className={cx(
|
||||
open
|
||||
? 'text-blue-500 dark:text-sky-500'
|
||||
: 'tex-slate-800 dark:text-slate-200',
|
||||
'flex w-full items-center justify-between py-4 text-left text-base font-medium focus:outline-none'
|
||||
)}
|
||||
>
|
||||
<span>Solutions</span>
|
||||
<ChevronDownIcon
|
||||
aria-hidden="true"
|
||||
className={cx(
|
||||
open
|
||||
? 'rotate-180 transform text-blue-500 dark:text-sky-500'
|
||||
: 'tex-slate-800 dark:text-slate-200',
|
||||
'h-3 w-3 transition duration-150 ease-in-out group-hover:text-blue-500 dark:group-hover:text-sky-500'
|
||||
)}
|
||||
/>
|
||||
</Disclosure.Button>
|
||||
<Disclosure.Panel as="ul" className="space-y-1">
|
||||
{solutions.map((item) => (
|
||||
<MobileMenuItem
|
||||
key={item.name}
|
||||
item={item}
|
||||
/>
|
||||
))}
|
||||
</Disclosure.Panel>
|
||||
</>
|
||||
)}
|
||||
</Disclosure>
|
||||
<Link
|
||||
href="/getting-started/intro"
|
||||
title="Documentation"
|
||||
@ -459,24 +327,16 @@ export function Header(): JSX.Element {
|
||||
>
|
||||
Blog
|
||||
</Link>
|
||||
<Link
|
||||
href="/pricing"
|
||||
title="Nx Cloud"
|
||||
className="flex w-full gap-2 py-4 font-medium leading-tight hover:text-blue-500 dark:text-slate-200 dark:hover:text-sky-500"
|
||||
prefetch={false}
|
||||
>
|
||||
CI Pricing
|
||||
</Link>
|
||||
{/*RESOURCES*/}
|
||||
{/*Resources*/}
|
||||
<Disclosure as="div">
|
||||
{({ open }) => (
|
||||
<>
|
||||
<Disclosure.Button
|
||||
className={cx(
|
||||
'flex w-full items-center justify-between py-4 text-left text-base font-medium focus:outline-none',
|
||||
open
|
||||
? 'text-blue-500 dark:text-sky-500'
|
||||
: 'tex-slate-800 dark:text-slate-200'
|
||||
: 'tex-slate-800 dark:text-slate-200',
|
||||
'flex w-full items-center justify-between py-4 text-left text-base font-medium focus:outline-none'
|
||||
)}
|
||||
>
|
||||
<span>Resources</span>
|
||||
@ -494,19 +354,9 @@ export function Header(): JSX.Element {
|
||||
as="ul"
|
||||
className="space-y-1 pb-2"
|
||||
>
|
||||
{learnItems.map((item) => (
|
||||
<MobileMenuItem
|
||||
key={item.name}
|
||||
item={item}
|
||||
/>
|
||||
))}
|
||||
{eventItems.map((item) => (
|
||||
<MobileMenuItem
|
||||
key={item.name}
|
||||
item={item}
|
||||
/>
|
||||
))}
|
||||
{companyItems.map((item) => (
|
||||
{Object.values(resourceMenuItems)
|
||||
.flat()
|
||||
.map((item) => (
|
||||
<MobileMenuItem
|
||||
key={item.name}
|
||||
item={item}
|
||||
@ -516,6 +366,38 @@ export function Header(): JSX.Element {
|
||||
</>
|
||||
)}
|
||||
</Disclosure>
|
||||
<Link
|
||||
href="/nx-cloud"
|
||||
title="Nx Cloud"
|
||||
className="flex w-full gap-2 py-4 font-medium leading-tight hover:text-blue-500 dark:text-slate-200 dark:hover:text-sky-500"
|
||||
prefetch={false}
|
||||
>
|
||||
Nx Cloud
|
||||
</Link>
|
||||
<Link
|
||||
href="/pricing"
|
||||
title="Pricing"
|
||||
className="flex w-full gap-2 py-4 font-medium leading-tight hover:text-blue-500 dark:text-slate-200 dark:hover:text-sky-500"
|
||||
prefetch={false}
|
||||
>
|
||||
Pricing
|
||||
</Link>
|
||||
<Link
|
||||
href="/powerpack"
|
||||
title="Powerpack"
|
||||
className="flex w-full gap-2 py-4 font-medium leading-tight hover:text-blue-500 dark:text-slate-200 dark:hover:text-sky-500"
|
||||
prefetch={false}
|
||||
>
|
||||
Powerpack
|
||||
</Link>
|
||||
<Link
|
||||
href="/enterprise"
|
||||
title="Enterprise"
|
||||
className="flex w-full gap-2 py-4 font-medium leading-tight hover:text-blue-500 dark:text-slate-200 dark:hover:text-sky-500"
|
||||
prefetch={false}
|
||||
>
|
||||
Enterprise
|
||||
</Link>
|
||||
<Link
|
||||
href="/contact"
|
||||
title="Contact"
|
||||
|
||||
@ -16,6 +16,7 @@ import {
|
||||
MicrophoneIcon,
|
||||
VideoCameraIcon,
|
||||
CheckBadgeIcon,
|
||||
BookOpenIcon,
|
||||
} from '@heroicons/react/24/outline';
|
||||
import { FC, SVGProps } from 'react';
|
||||
import { DiscordIcon } from '../discord-icon';
|
||||
@ -126,11 +127,30 @@ export const featuresItems: Record<string, MenuItem[]> = {
|
||||
},
|
||||
],
|
||||
};
|
||||
export const solutions: MenuItem[] = [
|
||||
export const ossProducts: MenuItem[] = [
|
||||
{
|
||||
name: 'Nx',
|
||||
description: 'Smart Monorepos - Fast CI',
|
||||
href: '/getting-started/intro',
|
||||
icon: null,
|
||||
isNew: false,
|
||||
isHighlight: false,
|
||||
},
|
||||
{
|
||||
name: 'Nx Console',
|
||||
description: 'Editor integration for VSCode, Cursor and IntelliJ IDEs',
|
||||
href: '/getting-started/editor-setup',
|
||||
icon: null,
|
||||
isNew: false,
|
||||
isHighlight: false,
|
||||
},
|
||||
];
|
||||
|
||||
export const enterpriseProducts: MenuItem[] = [
|
||||
{
|
||||
name: 'Nx Cloud',
|
||||
description:
|
||||
'End-to-end solution for smart, efficient and maintainable CI.',
|
||||
'Nx Cloud is the end-to-end solution for smart, efficient and maintainable CI',
|
||||
href: '/nx-cloud',
|
||||
icon: null,
|
||||
isNew: false,
|
||||
@ -148,7 +168,7 @@ export const solutions: MenuItem[] = [
|
||||
{
|
||||
name: 'Nx Enterprise',
|
||||
description:
|
||||
'The ultimate Nx & Nx Cloud toolchain, tailored to your needs.',
|
||||
"Accelerate your organization's journey to tighter collaboration, better developer experience, and speed…lots of speed.",
|
||||
href: '/enterprise',
|
||||
icon: null,
|
||||
isNew: false,
|
||||
@ -258,10 +278,7 @@ export const companyItems: MenuItem[] = [
|
||||
isHighlight: false,
|
||||
},
|
||||
];
|
||||
export const solutionsMenuItems = {
|
||||
'Helping you grow': solutions,
|
||||
// 'Use cases': useCaseItems
|
||||
};
|
||||
|
||||
export const resourceMenuItems = {
|
||||
Learn: learnItems,
|
||||
Events: eventItems,
|
||||
|
||||
@ -208,16 +208,16 @@ export function SidebarMobile({
|
||||
general: [
|
||||
{ name: 'Home', href: '/', current: false },
|
||||
{ name: 'Blog', href: '/blog', current: false },
|
||||
{ name: 'Community', href: '/community', current: false },
|
||||
{ name: 'Launch Nx', href: '/launch-nx', current: false },
|
||||
{ name: 'Resources', href: '/resources', current: false },
|
||||
{ name: 'Nx Cloud', href: '/nx-cloud', current: false },
|
||||
{
|
||||
name: 'Contact',
|
||||
href: '/contact',
|
||||
name: 'Powerpack',
|
||||
href: '/powerpack',
|
||||
current: false,
|
||||
},
|
||||
{
|
||||
name: 'Go to app',
|
||||
href: 'https://cloud.nx.app',
|
||||
name: 'Enterprise',
|
||||
href: '/enterprise',
|
||||
current: false,
|
||||
},
|
||||
],
|
||||
|
||||
@ -20,9 +20,9 @@ export function Hero(): JSX.Element {
|
||||
href="/contact"
|
||||
variant="contrast"
|
||||
size="default"
|
||||
title="Join us"
|
||||
title="Contact us"
|
||||
>
|
||||
Reach out
|
||||
Contact us
|
||||
</ButtonLink>
|
||||
|
||||
<a
|
||||
|
||||
@ -17,26 +17,25 @@ export function Hero(): JSX.Element {
|
||||
Accelerate your organization's journey to tighter collaboration,
|
||||
better developer experience, and speed…lots of speed.
|
||||
</SectionHeading>
|
||||
<div className="mt-10">
|
||||
<div className="mt-10 items-center justify-center gap-x-6">
|
||||
<ButtonLink
|
||||
href="/contact/engineering"
|
||||
title="Talk to the engineering team"
|
||||
href="/contact/sales"
|
||||
title="Request a free trial"
|
||||
variant="primary"
|
||||
size="default"
|
||||
>
|
||||
Talk to engineering
|
||||
Request a free trial
|
||||
</ButtonLink>
|
||||
<p className="mt-6 italic">
|
||||
Ready to talk terms?{' '}
|
||||
Got questions?{' '}
|
||||
<Link
|
||||
href="/contact/sales"
|
||||
href="/contact/engineering"
|
||||
title="Talk to the sales team"
|
||||
className="font-semibold underline"
|
||||
prefetch={false}
|
||||
>
|
||||
Speak directly to sales
|
||||
Talk to an engineer.
|
||||
</Link>
|
||||
.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -4,14 +4,8 @@ import { ShaderGradient, ShaderGradientCanvas } from 'shadergradient';
|
||||
import { BlurFade, usePrefersReducedMotion } from '@nx/nx-dev/ui-animations';
|
||||
import { Theme, useTheme } from '@nx/nx-dev/ui-theme';
|
||||
import { useState } from 'react';
|
||||
import Link from 'next/link';
|
||||
import { useIsomorphicLayoutEffect } from '@nx/nx-dev/ui-primitives';
|
||||
import {
|
||||
MonorepoWorldIcon,
|
||||
RustIcon,
|
||||
TypeScriptIcon,
|
||||
} from '@nx/nx-dev/ui-icons';
|
||||
import { motion, MotionConfig } from 'framer-motion';
|
||||
import { RustIcon, TypeScriptIcon } from '@nx/nx-dev/ui-icons';
|
||||
|
||||
export function Hero(): JSX.Element {
|
||||
return (
|
||||
@ -76,12 +70,12 @@ export function Hero(): JSX.Element {
|
||||
Learn about Nx on CI
|
||||
</ButtonLink>
|
||||
<ButtonLink
|
||||
href="/contact?utm_medium=website&utm_campaign=homepage_links&utm_content=cta_hero_get_started"
|
||||
title="Get started"
|
||||
href="/nx-cloud"
|
||||
title="Try Nx Cloud for free"
|
||||
variant="secondary"
|
||||
size="default"
|
||||
>
|
||||
Contact us
|
||||
Try Nx Cloud for free
|
||||
</ButtonLink>
|
||||
</div>
|
||||
|
||||
|
||||
@ -18,6 +18,16 @@ export function PlansDisplay(): ReactElement {
|
||||
<SectionHeading as="p" variant="subtitle" className="mt-6">
|
||||
Level up your CI with Nx Cloud
|
||||
</SectionHeading>
|
||||
<div className="mt-10 flex items-center justify-center gap-x-6">
|
||||
<ButtonLink
|
||||
href="/contact/engineering"
|
||||
title="Talk to the engineering team"
|
||||
variant="secondary"
|
||||
size="default"
|
||||
>
|
||||
Got questions? Talk to our team
|
||||
</ButtonLink>
|
||||
</div>
|
||||
</header>
|
||||
<div className="mt-20 flow-root">
|
||||
<div className="isolate -mt-16 grid max-w-full grid-cols-1 gap-6 sm:mx-auto lg:mt-0 lg:grid-cols-3 xl:-mx-4 xl:gap-8">
|
||||
@ -57,7 +67,7 @@ export function PlansDisplay(): ReactElement {
|
||||
}
|
||||
className="w-full"
|
||||
>
|
||||
Get started
|
||||
Start now
|
||||
</ButtonLink>
|
||||
</div>
|
||||
<ul className="mt-4 divide-y divide-slate-200 text-sm dark:divide-slate-800">
|
||||
@ -161,7 +171,7 @@ export function PlansDisplay(): ReactElement {
|
||||
}
|
||||
className="w-full"
|
||||
>
|
||||
Get started
|
||||
Free to start
|
||||
</ButtonLink>
|
||||
</div>
|
||||
<ul className="mt-4 divide-y divide-slate-200 text-sm dark:divide-slate-800">
|
||||
@ -266,21 +276,21 @@ export function PlansDisplay(): ReactElement {
|
||||
</p>
|
||||
<div className="my-12">
|
||||
<ButtonLink
|
||||
href="/enterprise"
|
||||
href="/contact/sales"
|
||||
aria-describedby="enterprise-plan"
|
||||
title="Enterprise"
|
||||
size="default"
|
||||
variant="secondary"
|
||||
onClick={() =>
|
||||
sendCustomEvent(
|
||||
'learn-enterprise-click',
|
||||
'request-enterprise-trial',
|
||||
'plans-table',
|
||||
'pricing-plans'
|
||||
)
|
||||
}
|
||||
className="w-full"
|
||||
>
|
||||
Learn more
|
||||
Request a trial
|
||||
</ButtonLink>
|
||||
</div>
|
||||
<ul className="mt-4 divide-y divide-slate-200 text-sm dark:divide-slate-800">
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user