docs(nx-dev): add click tracking on pricing plans (#28902)
This commit is contained in:
parent
06af0ee53b
commit
f3d5787f97
@ -1,5 +1,11 @@
|
||||
import type { Metadata } from 'next';
|
||||
import { Faq, Oss, ResourceClasses, PlansDisplay } from '@nx/nx-dev/ui-pricing';
|
||||
import {
|
||||
Faq,
|
||||
Oss,
|
||||
ResourceClasses,
|
||||
PlansDisplay,
|
||||
TrialCallout,
|
||||
} from '@nx/nx-dev/ui-pricing';
|
||||
import {
|
||||
CallToAction,
|
||||
DefaultLayout,
|
||||
@ -30,13 +36,16 @@ export const metadata: Metadata = {
|
||||
},
|
||||
};
|
||||
|
||||
export default function PricingPageV2() {
|
||||
export default function PricingPage() {
|
||||
return (
|
||||
<DefaultLayout>
|
||||
<PlansDisplay />
|
||||
<div className="mt-18 lg:mt-32">
|
||||
<TrustedBy utmSource="pricingpage" utmCampaign="pricing" />
|
||||
</div>
|
||||
<div className="mt-32 lg:mt-56">
|
||||
<TrialCallout pageId="pricing" />
|
||||
</div>
|
||||
<div className="mt-32 lg:mt-56">
|
||||
<ResourceClasses />
|
||||
</div>
|
||||
|
||||
@ -12,6 +12,7 @@ import {
|
||||
TrustedBy,
|
||||
SolveYourCi,
|
||||
} from '@nx/nx-dev/ui-enterprise';
|
||||
import { TrialCallout } from '@nx/nx-dev/ui-pricing';
|
||||
|
||||
export function Enterprise(): JSX.Element {
|
||||
const router = useRouter();
|
||||
@ -46,6 +47,9 @@ export function Enterprise(): JSX.Element {
|
||||
<div className="mt-32 lg:mt-40">
|
||||
<MetricsAndCustomers />
|
||||
</div>
|
||||
<div className="mt-32 lg:mt-40">
|
||||
<TrialCallout pageId="enterprise" />
|
||||
</div>
|
||||
<div className="mt-32 lg:mt-56">
|
||||
<ScaleYourPeople />
|
||||
</div>
|
||||
|
||||
@ -86,7 +86,10 @@ export function AgentNumberOverTime(): JSX.Element {
|
||||
};
|
||||
|
||||
return (
|
||||
<section id="agent-number-over-time" className="overflow-hidden">
|
||||
<section
|
||||
id="agent-number-over-time"
|
||||
className="scroll-mt-24 overflow-hidden"
|
||||
>
|
||||
<div className="mx-auto max-w-7xl md:px-6 lg:px-8">
|
||||
<div className="mx-auto max-w-2xl text-center">
|
||||
<SectionHeading
|
||||
|
||||
@ -48,7 +48,7 @@ export function AutomatedAgentsManagement(): JSX.Element {
|
||||
};
|
||||
|
||||
return (
|
||||
<section id="competitive-compute" className="overflow-hidden">
|
||||
<section id="competitive-compute" className="scroll-mt-24 overflow-hidden">
|
||||
<div className="mx-auto max-w-7xl md:px-6 lg:px-8">
|
||||
<div className="grid grid-cols-1 gap-x-8 gap-y-16 sm:gap-y-20 lg:grid-cols-2 lg:items-start">
|
||||
<div className="px-6 md:px-0 lg:pr-4 lg:pt-4">
|
||||
|
||||
@ -6,6 +6,7 @@ import {
|
||||
} from '@heroicons/react/24/outline';
|
||||
import { SectionHeading } from '@nx/nx-dev/ui-common';
|
||||
import Link from 'next/link';
|
||||
import { ReactElement } from 'react';
|
||||
|
||||
const features = [
|
||||
{
|
||||
@ -41,9 +42,9 @@ const features = [
|
||||
},
|
||||
];
|
||||
|
||||
export function EnhancedWithAi(): JSX.Element {
|
||||
export function EnhancedWithAi(): ReactElement {
|
||||
return (
|
||||
<section id="ai-for-your-ci">
|
||||
<section id="ai-for-your-ci" className="scroll-mt-24">
|
||||
<div className="mx-auto max-w-7xl px-6 lg:px-8">
|
||||
<div className="mx-auto max-w-3xl text-center">
|
||||
<SectionHeading as="h2" variant="title" id="deep-understanding">
|
||||
|
||||
@ -1,9 +1,10 @@
|
||||
'use client';
|
||||
import { Variants, motion } from 'framer-motion';
|
||||
import { motion, Variants } from 'framer-motion';
|
||||
import { Spotlight } from './elements/spotlight';
|
||||
import { AnimateValue } from '@nx/nx-dev/ui-animations';
|
||||
import { ReactElement } from 'react';
|
||||
|
||||
export function FasterAndCheaper(): JSX.Element {
|
||||
export function FasterAndCheaper(): ReactElement {
|
||||
const spotlight: Variants = {
|
||||
offscreen: {
|
||||
display: 'none',
|
||||
@ -14,7 +15,7 @@ export function FasterAndCheaper(): JSX.Element {
|
||||
};
|
||||
|
||||
return (
|
||||
<section>
|
||||
<section id="faster-and-cheaper" className="scroll-mt-24">
|
||||
<motion.div
|
||||
initial="offscreen"
|
||||
whileInView="onscreen"
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
'use client';
|
||||
import { motion } from 'framer-motion';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { ReactElement, useEffect, useState } from 'react';
|
||||
import { SectionHeading } from '@nx/nx-dev/ui-common';
|
||||
import { usePrefersReducedMotion } from '@nx/nx-dev/ui-animations';
|
||||
|
||||
@ -71,7 +71,7 @@ const stats = [
|
||||
{ id: 4, name: 'Runs daily', value: 100, suffix: 'k+' },
|
||||
];
|
||||
|
||||
export function Statistics(): JSX.Element {
|
||||
export function Statistics(): ReactElement {
|
||||
const shouldReduceMotion = usePrefersReducedMotion();
|
||||
|
||||
const variants = {
|
||||
|
||||
@ -8,9 +8,11 @@ import {
|
||||
StorybookIcon,
|
||||
VmwareIcon,
|
||||
} from '@nx/nx-dev/ui-icons';
|
||||
export function TrustedBy(): JSX.Element {
|
||||
import { ReactElement } from 'react';
|
||||
|
||||
export function TrustedBy(): ReactElement {
|
||||
return (
|
||||
<section className="">
|
||||
<section id="trust" className="scroll-mt-24">
|
||||
<div className="mx-auto max-w-7xl px-4 pb-12 sm:px-6 lg:px-8 lg:pb-16">
|
||||
<h2 className="text-center text-lg font-medium leading-8 text-slate-400">
|
||||
Startups and Fortune 500 companies trust Nx Cloud
|
||||
|
||||
@ -13,15 +13,15 @@ import { SectionHeading } from '@nx/nx-dev/ui-common';
|
||||
import { BentoGrid, BentoGridItem } from './elements/bento-grid';
|
||||
import { cx } from '@nx/nx-dev/ui-primitives';
|
||||
import { animate, motion, useMotionValue, useTransform } from 'framer-motion';
|
||||
import { useEffect } from 'react';
|
||||
import { ReactElement, useEffect } from 'react';
|
||||
import { usePrefersReducedMotion } from '@nx/nx-dev/ui-animations';
|
||||
|
||||
export function UnderstandWorkspace(): JSX.Element {
|
||||
export function UnderstandWorkspace(): ReactElement {
|
||||
return (
|
||||
<section>
|
||||
<section id="deep-understanding" className="scroll-mt-24">
|
||||
<div className="mx-auto max-w-7xl px-6 lg:px-8">
|
||||
<div className="mx-auto max-w-2xl text-center">
|
||||
<SectionHeading as="h2" variant="title" id="deep-understanding">
|
||||
<SectionHeading as="h2" variant="title">
|
||||
Deep understanding of your workspace
|
||||
</SectionHeading>
|
||||
<SectionHeading as="p" variant="subtitle" className="mt-6">
|
||||
|
||||
@ -4,6 +4,7 @@ import { ChevronDownIcon } from '@heroicons/react/24/outline';
|
||||
import { SectionHeading } from '@nx/nx-dev/ui-common';
|
||||
import { cx } from '@nx/nx-dev/ui-primitives';
|
||||
import { FAQPageJsonLd } from 'next-seo';
|
||||
import Link from 'next/link';
|
||||
import { ReactElement } from 'react';
|
||||
|
||||
export function Faq(): ReactElement {
|
||||
@ -89,11 +90,11 @@ export function Faq(): ReactElement {
|
||||
{
|
||||
question: 'What if I need help picking the right plan?',
|
||||
answer:
|
||||
'We have a helpful comparison above. If you have additional questions, or these plans don’t fit your needs please reach out to cloud-support@nrwl.io and we will do our best to help.',
|
||||
'We have a helpful comparison above. If you have additional questions, or these plans don’t fit your needs please reach out to https://nx.dev/contact/sales and we will do our best to help.',
|
||||
},
|
||||
{
|
||||
question: 'What if I need more than 70 active contributors?',
|
||||
answer: 'Please reach out to cloud-support@nrwl.io.',
|
||||
answer: 'Please reach out to https://nx.dev/contact/sales',
|
||||
},
|
||||
{
|
||||
question: 'What payment methods do you accept?',
|
||||
@ -108,22 +109,20 @@ export function Faq(): ReactElement {
|
||||
<div className="lg:grid lg:grid-cols-3 lg:gap-8">
|
||||
<header>
|
||||
<SectionHeading as="h2" variant="title">
|
||||
Not sure yet? <br /> Have questions?
|
||||
Have questions?
|
||||
</SectionHeading>
|
||||
<SectionHeading as="p" variant="subtitle" className="mt-6">
|
||||
Here are the most asked question we condensed for your to get you
|
||||
setup quickly.
|
||||
Check out our most commonly asked questions.
|
||||
</SectionHeading>
|
||||
|
||||
<p className="text-md mt-4 text-slate-400 dark:text-slate-600">
|
||||
Can’t find the answer you’re looking for? Reach out to our{' '}
|
||||
<a
|
||||
href="mailto:cloud-support@nrwl.io"
|
||||
className="font-medium underline"
|
||||
<Link
|
||||
href="/contact"
|
||||
title="Reach out to the team"
|
||||
className="font-semibold"
|
||||
>
|
||||
customer support
|
||||
</a>{' '}
|
||||
team.
|
||||
Can’t find the answer you’re looking for?
|
||||
</Link>
|
||||
</p>
|
||||
</header>
|
||||
<FAQPageJsonLd
|
||||
|
||||
@ -1,13 +1,14 @@
|
||||
'use client';
|
||||
import { ReactElement } from 'react';
|
||||
import { PlusIcon } from '@heroicons/react/24/outline';
|
||||
import { CheckCircleIcon } from '@heroicons/react/24/solid';
|
||||
import { ButtonLink, SectionHeading } from '@nx/nx-dev/ui-common';
|
||||
import { TrialCallout } from './trial-callout';
|
||||
import Link from 'next/link';
|
||||
import { sendCustomEvent } from '@nx/nx-dev/feature-analytics';
|
||||
|
||||
export function PlansDisplay(): ReactElement {
|
||||
return (
|
||||
<section>
|
||||
<section id="plans" className="scroll-mt-24">
|
||||
<div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
|
||||
<header className="mx-auto max-w-4xl text-center">
|
||||
<SectionHeading as="h2" variant="display">
|
||||
@ -19,7 +20,7 @@ export function PlansDisplay(): ReactElement {
|
||||
</SectionHeading>
|
||||
</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-12">
|
||||
<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">
|
||||
{/*HOBBY*/}
|
||||
<div>
|
||||
<div className="rounded-lg border-2 border-blue-500 bg-white p-6 dark:border-sky-500 dark:bg-slate-950">
|
||||
@ -47,6 +48,13 @@ export function PlansDisplay(): ReactElement {
|
||||
title="Start now"
|
||||
size="default"
|
||||
variant="primary"
|
||||
onClick={() =>
|
||||
sendCustomEvent(
|
||||
'start-hobby-plan-click',
|
||||
'plans-table',
|
||||
'pricing-plans'
|
||||
)
|
||||
}
|
||||
className="w-full"
|
||||
>
|
||||
Get started
|
||||
@ -74,6 +82,13 @@ export function PlansDisplay(): ReactElement {
|
||||
href="/ci/features/remote-cache"
|
||||
target="_blank"
|
||||
title="Learn how Nx Replay easily reduces CI execution time"
|
||||
onClick={() =>
|
||||
sendCustomEvent(
|
||||
'learn-nx-replay-click',
|
||||
'plans-table',
|
||||
'pricing-plans'
|
||||
)
|
||||
}
|
||||
className="font-medium underline decoration-dotted"
|
||||
>
|
||||
Nx Replay
|
||||
@ -91,6 +106,13 @@ export function PlansDisplay(): ReactElement {
|
||||
href="/ci/features/distribute-task-execution"
|
||||
target="_blank"
|
||||
title="Learn how Nx Agents easily scale your CI pipelines"
|
||||
onClick={() =>
|
||||
sendCustomEvent(
|
||||
'learn-nx-agents-click',
|
||||
'plans-table',
|
||||
'pricing-plans'
|
||||
)
|
||||
}
|
||||
className="font-medium underline decoration-dotted"
|
||||
>
|
||||
Nx Agents
|
||||
@ -109,14 +131,16 @@ export function PlansDisplay(): ReactElement {
|
||||
</h4>
|
||||
</div>
|
||||
<p className="mt-2 text-sm">
|
||||
Scales with your team's needs. Billed on the first of each
|
||||
month.
|
||||
Start free, pay as you grow. Billed on the first of each month.
|
||||
</p>
|
||||
<p className="mt-4 leading-5">
|
||||
<span className="text-3xl font-semibold text-slate-950 dark:text-white">
|
||||
$19
|
||||
</span>
|
||||
<span className="text-lg"> per Active Contributor¹</span>
|
||||
<span className="text-lg"> per Active Contributor¹</span>{' '}
|
||||
<span className="text-sm font-semibold italic">
|
||||
(first 5 free)
|
||||
</span>
|
||||
<br />
|
||||
<span className="text-sm">+ usage overages</span>
|
||||
</p>
|
||||
@ -128,6 +152,13 @@ export function PlansDisplay(): ReactElement {
|
||||
title="Get started"
|
||||
size="default"
|
||||
variant="secondary"
|
||||
onClick={() =>
|
||||
sendCustomEvent(
|
||||
'start-team-plan-click',
|
||||
'plans-table',
|
||||
'pricing-plans'
|
||||
)
|
||||
}
|
||||
className="w-full"
|
||||
>
|
||||
Get started
|
||||
@ -167,6 +198,13 @@ export function PlansDisplay(): ReactElement {
|
||||
href="/nx-cloud#ai-for-your-ci"
|
||||
target="_blank"
|
||||
title="Check our AI integrations and how to use them"
|
||||
onClick={() =>
|
||||
sendCustomEvent(
|
||||
'learn-ai-integrations-click',
|
||||
'plans-table',
|
||||
'pricing-plans'
|
||||
)
|
||||
}
|
||||
className="font-medium underline decoration-dotted"
|
||||
>
|
||||
AI integrations
|
||||
@ -218,8 +256,8 @@ export function PlansDisplay(): ReactElement {
|
||||
</h4>
|
||||
</div>
|
||||
<p className="mt-2 text-sm">
|
||||
The ultimate Nx toolchain, tailored to your needs of speed.
|
||||
Flexible billing & payment options available.
|
||||
The ultimate Nx toolchain, tailored for speed. Flexible billing
|
||||
& payment options available.
|
||||
</p>
|
||||
<p className="mt-4 pb-5 leading-5">
|
||||
<span className="text-3xl font-semibold text-slate-950 dark:text-white">
|
||||
@ -233,6 +271,13 @@ export function PlansDisplay(): ReactElement {
|
||||
title="Enterprise"
|
||||
size="default"
|
||||
variant="secondary"
|
||||
onClick={() =>
|
||||
sendCustomEvent(
|
||||
'learn-enterprise-click',
|
||||
'plans-table',
|
||||
'pricing-plans'
|
||||
)
|
||||
}
|
||||
className="w-full"
|
||||
>
|
||||
Learn more
|
||||
@ -266,6 +311,13 @@ export function PlansDisplay(): ReactElement {
|
||||
href="/powerpack"
|
||||
target="_blank"
|
||||
title="Check our AI integrations and how to use them"
|
||||
onClick={() =>
|
||||
sendCustomEvent(
|
||||
'learn-nx-powerpack-click',
|
||||
'plans-table',
|
||||
'pricing-plans'
|
||||
)
|
||||
}
|
||||
className="font-medium underline decoration-dotted"
|
||||
>
|
||||
Nx Powerpack
|
||||
@ -317,10 +369,6 @@ export function PlansDisplay(): ReactElement {
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mt-20">
|
||||
<TrialCallout />
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
|
||||
@ -17,7 +17,7 @@ const linuxAmd64 = [
|
||||
},
|
||||
{
|
||||
icon: <LinuxIcon aria-hidden="true" className="size-6" />,
|
||||
name: 'Medium plus',
|
||||
name: 'Medium +',
|
||||
description: '3 vCPU, 6GB RAM',
|
||||
creditCost: 15,
|
||||
},
|
||||
|
||||
@ -1,37 +1,96 @@
|
||||
import { ButtonLink } from '@nx/nx-dev/ui-common';
|
||||
'use client';
|
||||
import { ReactElement } from 'react';
|
||||
import Image from 'next/image';
|
||||
import { ButtonLink } from '@nx/nx-dev/ui-common';
|
||||
import Link from 'next/link';
|
||||
import { sendCustomEvent } from '@nx/nx-dev/feature-analytics';
|
||||
|
||||
export function TrialCallout(): ReactElement {
|
||||
export function TrialCallout({
|
||||
pageId,
|
||||
}: {
|
||||
pageId: 'enterprise' | 'pricing';
|
||||
}): ReactElement {
|
||||
return (
|
||||
<section id="trial" className="isolate mx-auto max-w-xl">
|
||||
<div className="border border-slate-100 bg-white shadow-lg sm:rounded-lg dark:border-slate-800/60 dark:bg-slate-950">
|
||||
<div className="px-4 py-5 sm:p-6">
|
||||
<h3 className="text-base font-semibold leading-6 text-slate-900 dark:text-slate-100">
|
||||
Looking for a trial?
|
||||
</h3>
|
||||
<div className="mt-2 sm:flex sm:items-start sm:justify-between">
|
||||
<div className="max-w-xl text-sm">
|
||||
<p>
|
||||
<section id="start-trial" className="scroll-mt-24">
|
||||
<div className="mx-auto max-w-7xl sm:px-6 lg:px-8">
|
||||
<div className="relative isolate overflow-hidden bg-white px-6 pt-16 shadow-2xl ring-1 ring-slate-200 sm:rounded-3xl sm:px-16 md:pt-24 lg:flex lg:gap-x-20 lg:px-24 lg:pt-0 dark:bg-slate-900 dark:ring-slate-800">
|
||||
<svg
|
||||
viewBox="0 0 1024 1024"
|
||||
aria-hidden="true"
|
||||
className="absolute left-1/2 top-1/2 -z-10 h-[64rem] w-[64rem] -translate-y-1/2 [mask-image:radial-gradient(closest-side,white,transparent)] sm:left-full sm:-ml-80 lg:left-1/2 lg:ml-0 lg:-translate-x-1/2 lg:translate-y-0"
|
||||
>
|
||||
<circle
|
||||
r={512}
|
||||
cx={512}
|
||||
cy={512}
|
||||
fill="url(#1e3c1415-dh10-454c-aa3c-9a8019d0ap09d)"
|
||||
fillOpacity="0.7"
|
||||
/>
|
||||
<defs>
|
||||
<radialGradient id="1e3c1415-dh10-454c-aa3c-9a8019d0ap09d">
|
||||
<stop stopColor="#9333ea" />
|
||||
<stop offset={1} stopColor="#3b82f6" />
|
||||
</radialGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
<div className="mx-auto max-w-md text-center lg:mx-0 lg:flex-auto lg:py-32 lg:text-left">
|
||||
<h2 className="texxt-slate-950 text-balance text-3xl font-semibold tracking-tight sm:text-4xl dark:text-white">
|
||||
Start a Trial
|
||||
</h2>
|
||||
<p className="mt-6 text-pretty text-lg/8">
|
||||
Start with our Hobby Plan - free forever for teams of any size.
|
||||
Perfect for proof of concept testing with up to 50,000 credits
|
||||
per month.
|
||||
Perfect for proof of concept testing with up to 50,000 credits per
|
||||
month.
|
||||
</p>
|
||||
</div>
|
||||
<div className="mt-5 sm:ml-6 sm:mt-0 sm:flex sm:flex-shrink-0 sm:items-center">
|
||||
<div className="mt-4 flex items-center justify-center gap-x-6 lg:justify-start">
|
||||
<ButtonLink
|
||||
href="https://cloud.nx.app"
|
||||
title="Start with Hobby"
|
||||
variant="primary"
|
||||
target="_blank"
|
||||
size="default"
|
||||
title="Start free trial"
|
||||
onClick={() =>
|
||||
sendCustomEvent(
|
||||
'start-trial-click',
|
||||
'trial-callout-' + pageId,
|
||||
'trial-callout'
|
||||
)
|
||||
}
|
||||
>
|
||||
Start for free
|
||||
</ButtonLink>
|
||||
</div>
|
||||
<p className="mt-8 text-pretty text-base/8 leading-normal">
|
||||
Need a bit more? For larger teams we offer personalized support,{' '}
|
||||
<Link
|
||||
href="/contact-us/sales"
|
||||
title="Reach out to us"
|
||||
onClick={() =>
|
||||
sendCustomEvent(
|
||||
'contact-click',
|
||||
'trial-callout-' + pageId,
|
||||
'trial-callout'
|
||||
)
|
||||
}
|
||||
className="font-semibold text-blue-500 dark:text-sky-500"
|
||||
>
|
||||
reach out to us and we'll help you get started with a trial
|
||||
</Link>{' '}
|
||||
that suites your team's needs.{' '}
|
||||
</p>
|
||||
</div>
|
||||
<div className="relative mt-16 h-80 lg:mt-8">
|
||||
<Image
|
||||
src="/images/cloud/nrwl-ocean.avif"
|
||||
alt="App screenshot: overview"
|
||||
width={2550}
|
||||
height={1622}
|
||||
loading="eager"
|
||||
priority
|
||||
className="absolute left-0 top-0 w-[57rem] max-w-none rounded-md bg-white/5 ring-1 ring-slate-950/10"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/*</motion.div>*/}
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user