docs(nx-dev): add Nx Labs page (#31679)

Created a new contact page for Nx Labs to highlight services and provide a form for inquiries. Updated the professional services section in the header menu to include a link to this page.
This commit is contained in:
Benjamin Cabanes 2025-06-23 15:09:01 -04:00 committed by GitHub
parent a8cd1c77e3
commit a74bbaf32c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 193 additions and 6 deletions

View File

@ -0,0 +1,43 @@
import { useRouter } from 'next/router';
import { NextSeo } from 'next-seo';
import { Footer, Header } from '@nx/nx-dev/ui-common';
import { NxLabsContact } from '@nx/nx-dev/ui-contact';
import { type ReactElement } from 'react';
export function ContactNxLabs(): ReactElement {
const router = useRouter();
return (
<>
<NextSeo
title="Contact Nx Labs"
description="Accelerate Your Nx Adoption with Expert Guidance"
openGraph={{
url: 'https://nx.dev' + router.asPath,
title: 'Contact Nx Labs',
description: 'Accelerate Your Nx Adoption with Expert Guidance',
images: [
{
url: 'https://nx.dev/socials/nx-media.png',
width: 800,
height: 421,
alt: 'Nx: Smart Repos · Fast Builds',
type: 'image/jpeg',
},
],
siteName: 'Nx',
type: 'website',
}}
/>
<Header />
<main id="main" role="main" className="py-24 lg:py-32">
<div>
<NxLabsContact />
</div>
</main>
<Footer />
</>
);
}
export default ContactNxLabs;

View File

@ -1,11 +1,6 @@
import { useRouter } from 'next/router'; import { useRouter } from 'next/router';
import { NextSeo } from 'next-seo'; import { NextSeo } from 'next-seo';
import { import { ButtonLinkProps, DefaultLayout } from '@nx/nx-dev/ui-common';
ButtonLinkProps,
DefaultLayout,
Footer,
Header,
} from '@nx/nx-dev/ui-common';
import { import {
BuiltForEnterprise, BuiltForEnterprise,
CachePoisoningProtection, CachePoisoningProtection,

View File

@ -27,6 +27,7 @@ import {
import { ButtonLink, ButtonLinkProps } from '../button'; import { ButtonLink, ButtonLinkProps } from '../button';
import { import {
enterpriseItems, enterpriseItems,
professionalServicesItems,
resourceMenuItems, resourceMenuItems,
solutionsItems, solutionsItems,
} from './menu-items'; } from './menu-items';
@ -162,6 +163,7 @@ export function Header({ ctaButtons }: HeaderProps): ReactElement {
sections={{ sections={{
'By roles': solutionsItems, 'By roles': solutionsItems,
'For enterprises': enterpriseItems, 'For enterprises': enterpriseItems,
'Professional services': professionalServicesItems,
}} }}
/> />
</Popover.Panel> </Popover.Panel>
@ -434,6 +436,9 @@ export function Header({ ctaButtons }: HeaderProps): ReactElement {
{[ {[
...Object.values(solutionsItems).flat(), ...Object.values(solutionsItems).flat(),
...Object.values(enterpriseItems).flat(), ...Object.values(enterpriseItems).flat(),
...Object.values(
professionalServicesItems
).flat(),
].map((item) => ( ].map((item) => (
<MobileMenuItem <MobileMenuItem
key={item.name} key={item.name}

View File

@ -22,6 +22,7 @@ import {
ServerStackIcon, ServerStackIcon,
ArrowTrendingUpIcon, ArrowTrendingUpIcon,
CommandLineIcon, CommandLineIcon,
UsersIcon,
} from '@heroicons/react/24/outline'; } from '@heroicons/react/24/outline';
import { FC, SVGProps } from 'react'; import { FC, SVGProps } from 'react';
import { DiscordIcon } from '../discord-icon'; import { DiscordIcon } from '../discord-icon';
@ -320,6 +321,17 @@ export const enterpriseItems: MenuItem[] = [
isHighlight: false, isHighlight: false,
}, },
]; ];
export const professionalServicesItems: MenuItem[] = [
{
name: 'Nx Labs',
description:
'From expert training to hands-on engineering support, we meet teams where they are and help them move forward with confidence.',
href: '/contact/labs',
icon: UsersIcon,
isNew: false,
isHighlight: false,
},
];
export const resourceMenuItems = { export const resourceMenuItems = {
Learn: learnItems, Learn: learnItems,

View File

@ -2,3 +2,4 @@ export * from './lib/contact-links';
export * from './lib/how-can-we-help'; export * from './lib/how-can-we-help';
export * from './lib/talk-to-our-team'; export * from './lib/talk-to-our-team';
export * from './lib/talk-to-our-engineering-team'; export * from './lib/talk-to-our-engineering-team';
export * from './lib/nx-labs';

View File

@ -0,0 +1,128 @@
import {
SectionHeading,
HubspotForm,
Strong,
SectionDescription,
} from '@nx/nx-dev/ui-common';
import { type ReactElement } from 'react';
import {
BillIcon,
CapitalOneIcon,
CaterpillarIcon,
ManIcon,
RedwoodJsIcon,
RoyalBankOfCanadaIcon,
ShopifyIcon,
SiriusxmAlternateIcon,
StorybookIcon,
VmwareIcon,
ZipariIcon,
} from '@nx/nx-dev/ui-icons';
export function NxLabsContact(): ReactElement {
return (
<section id="contact-sales">
<div className="mx-auto max-w-7xl px-6 lg:px-8">
<div className="mx-auto max-w-3xl text-center">
<SectionHeading as="h1" variant="display" id="how-can-we-help">
Accelerate Your Nx Adoption with Expert Guidance
</SectionHeading>
</div>
<div className="mx-auto mt-16 flex max-w-5xl flex-col gap-12 md:flex-row lg:gap-8">
<section className="mt-4 flex-1">
<SectionHeading
as="p"
variant="subtitle"
className="mx-auto mt-6 max-w-3xl lg:pr-20"
>
Nx Labs: Service built for outcomes
</SectionHeading>
<SectionDescription as="p" className="mt-6">
Whether you're just getting started with Nx or looking to unlock
its full potential, our{' '}
<Strong>
team of experts delivers tailored solutions that actually work
</Strong>
. From initial setup to advanced optimization, we offer workspace
assessments, hands-on team training, embedded engineering support,
and on-demand expertiseall designed to make your team
self-sufficient.
</SectionDescription>
<SectionDescription as="p" className="mt-4">
Unlike traditional consultants, we believe in planned
obsolescencenothing makes us prouder than seeing more Nx experts
out in the wild.
</SectionDescription>
<SectionDescription as="p" className="mt-4">
Ready to see what a truly optimized workspace looks like? Reach
out and let us know what you need.
</SectionDescription>
<figure className="mt-12 border-l border-slate-200 pl-8 dark:border-slate-800">
<blockquote className="text-base/7">
<p>
Nxs professional services team was instrumental in helping
us modernize our development workflow. The team is extremely
personable and knowledgeable. It is a pleasure to work with
them to get the most out of our investment.
</p>
</blockquote>
<figcaption className="mt-6 flex items-center gap-x-4 text-sm/6">
<img
alt="Wayne Kaskie"
src="https://avatars.githubusercontent.com/u/14349014?v=4"
className="size-8 flex-none rounded-full"
/>
<div>
<div className="font-semibold">Wayne Kaskie</div>
<div className="text-slate-500">
Front End Architect, Zipari
</div>
</div>
<ZipariIcon
aria-hidden="true"
className="ml-auto size-10 text-[#E31E39]"
/>
</figcaption>
</figure>
<div className="mx-auto mt-12 grid w-full grid-cols-4 gap-2 md:grid-cols-4 lg:mt-12">
<div className="col-span-1 flex h-14 items-center justify-center lg:h-28">
<RoyalBankOfCanadaIcon
aria-hidden="true"
className="size-12 text-black dark:text-white"
/>
</div>
<div className="col-span-1 flex h-14 items-center justify-center lg:h-28">
<VmwareIcon
aria-hidden="true"
className="size-28 text-black dark:text-white"
/>
</div>
<div className="col-span-1 flex h-14 items-center justify-center lg:h-28">
<BillIcon
aria-hidden="true"
className="size-14 text-black dark:text-white"
/>
</div>
<div className="col-span-1 flex h-14 items-center justify-center lg:h-28">
<CapitalOneIcon
aria-hidden="true"
className="size-28 text-black dark:text-white"
/>
</div>
</div>
</section>
<section className="flex-1 self-start rounded-xl border border-slate-200 bg-white p-8 dark:border-slate-800/40">
<HubspotForm
region="na1"
portalId="2757427"
formId="d5710d48-85de-4b17-ab97-4c22c25a8f02"
noScript={true}
loading={<div>Loading...</div>}
/>
</section>
</div>
</div>
</section>
);
}

View File

@ -1,5 +1,8 @@
import { FC, SVGProps } from 'react'; import { FC, SVGProps } from 'react';
/**
* Use `#E31E39` for a colored version.
*/
export const ZipariIcon: FC<SVGProps<SVGSVGElement>> = (props) => ( export const ZipariIcon: FC<SVGProps<SVGSVGElement>> = (props) => (
<svg <svg
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"