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 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 {
|
import {
|
||||||
CallToAction,
|
CallToAction,
|
||||||
DefaultLayout,
|
DefaultLayout,
|
||||||
@ -30,13 +36,16 @@ export const metadata: Metadata = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function PricingPageV2() {
|
export default function PricingPage() {
|
||||||
return (
|
return (
|
||||||
<DefaultLayout>
|
<DefaultLayout>
|
||||||
<PlansDisplay />
|
<PlansDisplay />
|
||||||
<div className="mt-18 lg:mt-32">
|
<div className="mt-18 lg:mt-32">
|
||||||
<TrustedBy utmSource="pricingpage" utmCampaign="pricing" />
|
<TrustedBy utmSource="pricingpage" utmCampaign="pricing" />
|
||||||
</div>
|
</div>
|
||||||
|
<div className="mt-32 lg:mt-56">
|
||||||
|
<TrialCallout pageId="pricing" />
|
||||||
|
</div>
|
||||||
<div className="mt-32 lg:mt-56">
|
<div className="mt-32 lg:mt-56">
|
||||||
<ResourceClasses />
|
<ResourceClasses />
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -12,6 +12,7 @@ import {
|
|||||||
TrustedBy,
|
TrustedBy,
|
||||||
SolveYourCi,
|
SolveYourCi,
|
||||||
} from '@nx/nx-dev/ui-enterprise';
|
} from '@nx/nx-dev/ui-enterprise';
|
||||||
|
import { TrialCallout } from '@nx/nx-dev/ui-pricing';
|
||||||
|
|
||||||
export function Enterprise(): JSX.Element {
|
export function Enterprise(): JSX.Element {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
@ -46,6 +47,9 @@ export function Enterprise(): JSX.Element {
|
|||||||
<div className="mt-32 lg:mt-40">
|
<div className="mt-32 lg:mt-40">
|
||||||
<MetricsAndCustomers />
|
<MetricsAndCustomers />
|
||||||
</div>
|
</div>
|
||||||
|
<div className="mt-32 lg:mt-40">
|
||||||
|
<TrialCallout pageId="enterprise" />
|
||||||
|
</div>
|
||||||
<div className="mt-32 lg:mt-56">
|
<div className="mt-32 lg:mt-56">
|
||||||
<ScaleYourPeople />
|
<ScaleYourPeople />
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -86,7 +86,10 @@ export function AgentNumberOverTime(): JSX.Element {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
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-7xl md:px-6 lg:px-8">
|
||||||
<div className="mx-auto max-w-2xl text-center">
|
<div className="mx-auto max-w-2xl text-center">
|
||||||
<SectionHeading
|
<SectionHeading
|
||||||
|
|||||||
@ -48,7 +48,7 @@ export function AutomatedAgentsManagement(): JSX.Element {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
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="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="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">
|
<div className="px-6 md:px-0 lg:pr-4 lg:pt-4">
|
||||||
|
|||||||
@ -6,6 +6,7 @@ import {
|
|||||||
} from '@heroicons/react/24/outline';
|
} from '@heroicons/react/24/outline';
|
||||||
import { SectionHeading } from '@nx/nx-dev/ui-common';
|
import { SectionHeading } from '@nx/nx-dev/ui-common';
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
|
import { ReactElement } from 'react';
|
||||||
|
|
||||||
const features = [
|
const features = [
|
||||||
{
|
{
|
||||||
@ -41,9 +42,9 @@ const features = [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
export function EnhancedWithAi(): JSX.Element {
|
export function EnhancedWithAi(): ReactElement {
|
||||||
return (
|
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-7xl px-6 lg:px-8">
|
||||||
<div className="mx-auto max-w-3xl text-center">
|
<div className="mx-auto max-w-3xl text-center">
|
||||||
<SectionHeading as="h2" variant="title" id="deep-understanding">
|
<SectionHeading as="h2" variant="title" id="deep-understanding">
|
||||||
|
|||||||
@ -1,9 +1,10 @@
|
|||||||
'use client';
|
'use client';
|
||||||
import { Variants, motion } from 'framer-motion';
|
import { motion, Variants } from 'framer-motion';
|
||||||
import { Spotlight } from './elements/spotlight';
|
import { Spotlight } from './elements/spotlight';
|
||||||
import { AnimateValue } from '@nx/nx-dev/ui-animations';
|
import { AnimateValue } from '@nx/nx-dev/ui-animations';
|
||||||
|
import { ReactElement } from 'react';
|
||||||
|
|
||||||
export function FasterAndCheaper(): JSX.Element {
|
export function FasterAndCheaper(): ReactElement {
|
||||||
const spotlight: Variants = {
|
const spotlight: Variants = {
|
||||||
offscreen: {
|
offscreen: {
|
||||||
display: 'none',
|
display: 'none',
|
||||||
@ -14,7 +15,7 @@ export function FasterAndCheaper(): JSX.Element {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section>
|
<section id="faster-and-cheaper" className="scroll-mt-24">
|
||||||
<motion.div
|
<motion.div
|
||||||
initial="offscreen"
|
initial="offscreen"
|
||||||
whileInView="onscreen"
|
whileInView="onscreen"
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
'use client';
|
'use client';
|
||||||
import { motion } from 'framer-motion';
|
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 { SectionHeading } from '@nx/nx-dev/ui-common';
|
||||||
import { usePrefersReducedMotion } from '@nx/nx-dev/ui-animations';
|
import { usePrefersReducedMotion } from '@nx/nx-dev/ui-animations';
|
||||||
|
|
||||||
@ -71,7 +71,7 @@ const stats = [
|
|||||||
{ id: 4, name: 'Runs daily', value: 100, suffix: 'k+' },
|
{ id: 4, name: 'Runs daily', value: 100, suffix: 'k+' },
|
||||||
];
|
];
|
||||||
|
|
||||||
export function Statistics(): JSX.Element {
|
export function Statistics(): ReactElement {
|
||||||
const shouldReduceMotion = usePrefersReducedMotion();
|
const shouldReduceMotion = usePrefersReducedMotion();
|
||||||
|
|
||||||
const variants = {
|
const variants = {
|
||||||
|
|||||||
@ -8,9 +8,11 @@ import {
|
|||||||
StorybookIcon,
|
StorybookIcon,
|
||||||
VmwareIcon,
|
VmwareIcon,
|
||||||
} from '@nx/nx-dev/ui-icons';
|
} from '@nx/nx-dev/ui-icons';
|
||||||
export function TrustedBy(): JSX.Element {
|
import { ReactElement } from 'react';
|
||||||
|
|
||||||
|
export function TrustedBy(): ReactElement {
|
||||||
return (
|
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">
|
<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">
|
<h2 className="text-center text-lg font-medium leading-8 text-slate-400">
|
||||||
Startups and Fortune 500 companies trust Nx Cloud
|
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 { BentoGrid, BentoGridItem } from './elements/bento-grid';
|
||||||
import { cx } from '@nx/nx-dev/ui-primitives';
|
import { cx } from '@nx/nx-dev/ui-primitives';
|
||||||
import { animate, motion, useMotionValue, useTransform } from 'framer-motion';
|
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';
|
import { usePrefersReducedMotion } from '@nx/nx-dev/ui-animations';
|
||||||
|
|
||||||
export function UnderstandWorkspace(): JSX.Element {
|
export function UnderstandWorkspace(): ReactElement {
|
||||||
return (
|
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-7xl px-6 lg:px-8">
|
||||||
<div className="mx-auto max-w-2xl text-center">
|
<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
|
Deep understanding of your workspace
|
||||||
</SectionHeading>
|
</SectionHeading>
|
||||||
<SectionHeading as="p" variant="subtitle" className="mt-6">
|
<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 { SectionHeading } from '@nx/nx-dev/ui-common';
|
||||||
import { cx } from '@nx/nx-dev/ui-primitives';
|
import { cx } from '@nx/nx-dev/ui-primitives';
|
||||||
import { FAQPageJsonLd } from 'next-seo';
|
import { FAQPageJsonLd } from 'next-seo';
|
||||||
|
import Link from 'next/link';
|
||||||
import { ReactElement } from 'react';
|
import { ReactElement } from 'react';
|
||||||
|
|
||||||
export function Faq(): ReactElement {
|
export function Faq(): ReactElement {
|
||||||
@ -89,11 +90,11 @@ export function Faq(): ReactElement {
|
|||||||
{
|
{
|
||||||
question: 'What if I need help picking the right plan?',
|
question: 'What if I need help picking the right plan?',
|
||||||
answer:
|
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?',
|
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?',
|
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">
|
<div className="lg:grid lg:grid-cols-3 lg:gap-8">
|
||||||
<header>
|
<header>
|
||||||
<SectionHeading as="h2" variant="title">
|
<SectionHeading as="h2" variant="title">
|
||||||
Not sure yet? <br /> Have questions?
|
Have questions?
|
||||||
</SectionHeading>
|
</SectionHeading>
|
||||||
<SectionHeading as="p" variant="subtitle" className="mt-6">
|
<SectionHeading as="p" variant="subtitle" className="mt-6">
|
||||||
Here are the most asked question we condensed for your to get you
|
Check out our most commonly asked questions.
|
||||||
setup quickly.
|
|
||||||
</SectionHeading>
|
</SectionHeading>
|
||||||
|
|
||||||
<p className="text-md mt-4 text-slate-400 dark:text-slate-600">
|
<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{' '}
|
<Link
|
||||||
<a
|
href="/contact"
|
||||||
href="mailto:cloud-support@nrwl.io"
|
title="Reach out to the team"
|
||||||
className="font-medium underline"
|
className="font-semibold"
|
||||||
>
|
>
|
||||||
customer support
|
Can’t find the answer you’re looking for?
|
||||||
</a>{' '}
|
</Link>
|
||||||
team.
|
|
||||||
</p>
|
</p>
|
||||||
</header>
|
</header>
|
||||||
<FAQPageJsonLd
|
<FAQPageJsonLd
|
||||||
|
|||||||
@ -1,13 +1,14 @@
|
|||||||
|
'use client';
|
||||||
import { ReactElement } from 'react';
|
import { ReactElement } from 'react';
|
||||||
import { PlusIcon } from '@heroicons/react/24/outline';
|
import { PlusIcon } from '@heroicons/react/24/outline';
|
||||||
import { CheckCircleIcon } from '@heroicons/react/24/solid';
|
import { CheckCircleIcon } from '@heroicons/react/24/solid';
|
||||||
import { ButtonLink, SectionHeading } from '@nx/nx-dev/ui-common';
|
import { ButtonLink, SectionHeading } from '@nx/nx-dev/ui-common';
|
||||||
import { TrialCallout } from './trial-callout';
|
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
|
import { sendCustomEvent } from '@nx/nx-dev/feature-analytics';
|
||||||
|
|
||||||
export function PlansDisplay(): ReactElement {
|
export function PlansDisplay(): ReactElement {
|
||||||
return (
|
return (
|
||||||
<section>
|
<section id="plans" className="scroll-mt-24">
|
||||||
<div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
|
<div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
|
||||||
<header className="mx-auto max-w-4xl text-center">
|
<header className="mx-auto max-w-4xl text-center">
|
||||||
<SectionHeading as="h2" variant="display">
|
<SectionHeading as="h2" variant="display">
|
||||||
@ -19,7 +20,7 @@ export function PlansDisplay(): ReactElement {
|
|||||||
</SectionHeading>
|
</SectionHeading>
|
||||||
</header>
|
</header>
|
||||||
<div className="mt-20 flow-root">
|
<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*/}
|
{/*HOBBY*/}
|
||||||
<div>
|
<div>
|
||||||
<div className="rounded-lg border-2 border-blue-500 bg-white p-6 dark:border-sky-500 dark:bg-slate-950">
|
<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"
|
title="Start now"
|
||||||
size="default"
|
size="default"
|
||||||
variant="primary"
|
variant="primary"
|
||||||
|
onClick={() =>
|
||||||
|
sendCustomEvent(
|
||||||
|
'start-hobby-plan-click',
|
||||||
|
'plans-table',
|
||||||
|
'pricing-plans'
|
||||||
|
)
|
||||||
|
}
|
||||||
className="w-full"
|
className="w-full"
|
||||||
>
|
>
|
||||||
Get started
|
Get started
|
||||||
@ -74,6 +82,13 @@ export function PlansDisplay(): ReactElement {
|
|||||||
href="/ci/features/remote-cache"
|
href="/ci/features/remote-cache"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
title="Learn how Nx Replay easily reduces CI execution time"
|
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"
|
className="font-medium underline decoration-dotted"
|
||||||
>
|
>
|
||||||
Nx Replay
|
Nx Replay
|
||||||
@ -91,6 +106,13 @@ export function PlansDisplay(): ReactElement {
|
|||||||
href="/ci/features/distribute-task-execution"
|
href="/ci/features/distribute-task-execution"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
title="Learn how Nx Agents easily scale your CI pipelines"
|
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"
|
className="font-medium underline decoration-dotted"
|
||||||
>
|
>
|
||||||
Nx Agents
|
Nx Agents
|
||||||
@ -109,14 +131,16 @@ export function PlansDisplay(): ReactElement {
|
|||||||
</h4>
|
</h4>
|
||||||
</div>
|
</div>
|
||||||
<p className="mt-2 text-sm">
|
<p className="mt-2 text-sm">
|
||||||
Scales with your team's needs. Billed on the first of each
|
Start free, pay as you grow. Billed on the first of each month.
|
||||||
month.
|
|
||||||
</p>
|
</p>
|
||||||
<p className="mt-4 leading-5">
|
<p className="mt-4 leading-5">
|
||||||
<span className="text-3xl font-semibold text-slate-950 dark:text-white">
|
<span className="text-3xl font-semibold text-slate-950 dark:text-white">
|
||||||
$19
|
$19
|
||||||
</span>
|
</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 />
|
<br />
|
||||||
<span className="text-sm">+ usage overages</span>
|
<span className="text-sm">+ usage overages</span>
|
||||||
</p>
|
</p>
|
||||||
@ -128,6 +152,13 @@ export function PlansDisplay(): ReactElement {
|
|||||||
title="Get started"
|
title="Get started"
|
||||||
size="default"
|
size="default"
|
||||||
variant="secondary"
|
variant="secondary"
|
||||||
|
onClick={() =>
|
||||||
|
sendCustomEvent(
|
||||||
|
'start-team-plan-click',
|
||||||
|
'plans-table',
|
||||||
|
'pricing-plans'
|
||||||
|
)
|
||||||
|
}
|
||||||
className="w-full"
|
className="w-full"
|
||||||
>
|
>
|
||||||
Get started
|
Get started
|
||||||
@ -167,6 +198,13 @@ export function PlansDisplay(): ReactElement {
|
|||||||
href="/nx-cloud#ai-for-your-ci"
|
href="/nx-cloud#ai-for-your-ci"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
title="Check our AI integrations and how to use them"
|
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"
|
className="font-medium underline decoration-dotted"
|
||||||
>
|
>
|
||||||
AI integrations
|
AI integrations
|
||||||
@ -218,8 +256,8 @@ export function PlansDisplay(): ReactElement {
|
|||||||
</h4>
|
</h4>
|
||||||
</div>
|
</div>
|
||||||
<p className="mt-2 text-sm">
|
<p className="mt-2 text-sm">
|
||||||
The ultimate Nx toolchain, tailored to your needs of speed.
|
The ultimate Nx toolchain, tailored for speed. Flexible billing
|
||||||
Flexible billing & payment options available.
|
& payment options available.
|
||||||
</p>
|
</p>
|
||||||
<p className="mt-4 pb-5 leading-5">
|
<p className="mt-4 pb-5 leading-5">
|
||||||
<span className="text-3xl font-semibold text-slate-950 dark:text-white">
|
<span className="text-3xl font-semibold text-slate-950 dark:text-white">
|
||||||
@ -233,6 +271,13 @@ export function PlansDisplay(): ReactElement {
|
|||||||
title="Enterprise"
|
title="Enterprise"
|
||||||
size="default"
|
size="default"
|
||||||
variant="secondary"
|
variant="secondary"
|
||||||
|
onClick={() =>
|
||||||
|
sendCustomEvent(
|
||||||
|
'learn-enterprise-click',
|
||||||
|
'plans-table',
|
||||||
|
'pricing-plans'
|
||||||
|
)
|
||||||
|
}
|
||||||
className="w-full"
|
className="w-full"
|
||||||
>
|
>
|
||||||
Learn more
|
Learn more
|
||||||
@ -266,6 +311,13 @@ export function PlansDisplay(): ReactElement {
|
|||||||
href="/powerpack"
|
href="/powerpack"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
title="Check our AI integrations and how to use them"
|
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"
|
className="font-medium underline decoration-dotted"
|
||||||
>
|
>
|
||||||
Nx Powerpack
|
Nx Powerpack
|
||||||
@ -317,10 +369,6 @@ export function PlansDisplay(): ReactElement {
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="mt-20">
|
|
||||||
<TrialCallout />
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -17,7 +17,7 @@ const linuxAmd64 = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
icon: <LinuxIcon aria-hidden="true" className="size-6" />,
|
icon: <LinuxIcon aria-hidden="true" className="size-6" />,
|
||||||
name: 'Medium plus',
|
name: 'Medium +',
|
||||||
description: '3 vCPU, 6GB RAM',
|
description: '3 vCPU, 6GB RAM',
|
||||||
creditCost: 15,
|
creditCost: 15,
|
||||||
},
|
},
|
||||||
|
|||||||
@ -1,37 +1,96 @@
|
|||||||
import { ButtonLink } from '@nx/nx-dev/ui-common';
|
'use client';
|
||||||
import { ReactElement } from 'react';
|
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 (
|
return (
|
||||||
<section id="trial" className="isolate mx-auto max-w-xl">
|
<section id="start-trial" className="scroll-mt-24">
|
||||||
<div className="border border-slate-100 bg-white shadow-lg sm:rounded-lg dark:border-slate-800/60 dark:bg-slate-950">
|
<div className="mx-auto max-w-7xl sm:px-6 lg:px-8">
|
||||||
<div className="px-4 py-5 sm:p-6">
|
<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">
|
||||||
<h3 className="text-base font-semibold leading-6 text-slate-900 dark:text-slate-100">
|
<svg
|
||||||
Looking for a trial?
|
viewBox="0 0 1024 1024"
|
||||||
</h3>
|
aria-hidden="true"
|
||||||
<div className="mt-2 sm:flex sm:items-start sm:justify-between">
|
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"
|
||||||
<div className="max-w-xl text-sm">
|
>
|
||||||
<p>
|
<circle
|
||||||
Start with our Hobby Plan - free forever for teams of any size.
|
r={512}
|
||||||
Perfect for proof of concept testing with up to 50,000 credits
|
cx={512}
|
||||||
per month.
|
cy={512}
|
||||||
</p>
|
fill="url(#1e3c1415-dh10-454c-aa3c-9a8019d0ap09d)"
|
||||||
</div>
|
fillOpacity="0.7"
|
||||||
<div className="mt-5 sm:ml-6 sm:mt-0 sm:flex sm:flex-shrink-0 sm:items-center">
|
/>
|
||||||
|
<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.
|
||||||
|
</p>
|
||||||
|
<div className="mt-4 flex items-center justify-center gap-x-6 lg:justify-start">
|
||||||
<ButtonLink
|
<ButtonLink
|
||||||
href="https://cloud.nx.app"
|
href="https://cloud.nx.app"
|
||||||
title="Start with Hobby"
|
|
||||||
variant="primary"
|
variant="primary"
|
||||||
target="_blank"
|
|
||||||
size="default"
|
size="default"
|
||||||
|
title="Start free trial"
|
||||||
|
onClick={() =>
|
||||||
|
sendCustomEvent(
|
||||||
|
'start-trial-click',
|
||||||
|
'trial-callout-' + pageId,
|
||||||
|
'trial-callout'
|
||||||
|
)
|
||||||
|
}
|
||||||
>
|
>
|
||||||
Start for free
|
Start for free
|
||||||
</ButtonLink>
|
</ButtonLink>
|
||||||
</div>
|
</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>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{/*</motion.div>*/}
|
|
||||||
</section>
|
</section>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user