Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update landing page CTA #1144

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions apps/landing/components/Alert.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { XCircleIcon, XIcon } from '@heroicons/react/solid';
import { XCircleIcon, XMarkIcon } from '@heroicons/react/20/solid';
import classNames from 'classnames';
import { useEffect, useState } from 'react';

Expand Down Expand Up @@ -62,7 +62,7 @@ export default function Alert({ message, type = 'error', dismissable }: AlertPro
onClick={() => setDismissed(true)}
>
<span className="sr-only">Dismiss</span>
<XIcon aria-hidden="true" className="h-5 w-5" />
<XMarkIcon aria-hidden="true" className="h-5 w-5" />
</button>
</div>
</div>
Expand Down
4 changes: 2 additions & 2 deletions apps/landing/components/Modal.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Dialog, Transition } from '@headlessui/react';
import { XIcon } from '@heroicons/react/outline';
import { Bars3Icon } from '@heroicons/react/24/outline';
import { Fragment } from 'react';

export interface ModalProps {
Expand Down Expand Up @@ -54,7 +54,7 @@ export const Modal = ({
onClick={() => onClose()}
>
<span className="sr-only">Close</span>
<XIcon className="h-6 w-6" aria-hidden="true" />
<Bars3Icon className="h-6 w-6" aria-hidden="true" />
</button>
</div>
{children}
Expand Down
7 changes: 3 additions & 4 deletions apps/landing/components/Navigation.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
/* eslint-disable @next/next/no-img-element */
import { Popover, Transition } from '@headlessui/react';
import { MenuIcon, XIcon } from '@heroicons/react/outline';
import { Bars3Icon, XMarkIcon } from '@heroicons/react/20/solid';
import classNames from 'classnames';
import Link from 'next/link';
import { Fragment } from 'react';
Expand Down Expand Up @@ -52,7 +51,7 @@ export const Navigation = ({ className, inverse, omitLinks = [], userProfile }:
)}
>
<span className="sr-only">Open main menu</span>
<MenuIcon className="h-6 w-6" aria-hidden="true" />
<Bars3Icon className="h-6 w-6" aria-hidden="true" />
</Popover.Button>
</div>
</div>
Expand Down Expand Up @@ -152,7 +151,7 @@ export const Navigation = ({ className, inverse, omitLinks = [], userProfile }:
<div className="-mr-2">
<Popover.Button className="bg-white rounded-md p-2 inline-flex items-center justify-center text-gray-400 hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-inset focus:ring-cyan-600">
<span className="sr-only">Close menu</span>
<XIcon className="h-6 w-6" aria-hidden="true" />
<XMarkIcon className="h-6 w-6" aria-hidden="true" />
</Popover.Button>
</div>
</div>
Expand Down
4 changes: 1 addition & 3 deletions apps/landing/components/blog-post-renderers.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
/* eslint-disable react/display-name */
import { documentToReactComponents, NodeRenderer, Options } from '@contentful/rich-text-react-renderer';
import { BLOCKS, Document, MARKS } from '@contentful/rich-text-types';
import { LinkIcon } from '@heroicons/react/24/outline';
import { Asset } from 'contentful';
import isString from 'lodash/isString';
import { Fragment, ReactNode } from 'react';
// import FigureImg from './FigureImg';
import { LinkIcon } from '@heroicons/react/outline';
import FigureImgWithViewFullScreen from './FigureImgWithViewFullScreen';
const NON_URL_CHARACTERS = /[^a-zA-Z0-9-]/g;

Expand Down
2 changes: 1 addition & 1 deletion apps/landing/components/form/Input.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ExclamationCircleIcon } from '@heroicons/react/solid';
import { ExclamationCircleIcon } from '@heroicons/react/20/solid';
import classNames from 'classnames';
import { DetailedHTMLProps, HTMLAttributes, InputHTMLAttributes, LabelHTMLAttributes, ReactNode, useId } from 'react';

Expand Down
2 changes: 1 addition & 1 deletion apps/landing/components/landing/AnalyticsSummary.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { AnalyticStat } from '@jetstream/types';

export default function AnalyticsSummary({ stats }: { stats: AnalyticStat[] }) {
return (
<div className="bg-gray-900 pt-4 pb-24 sm:pt-36 sm:pb-32 lg:pt-4">
<div className="bg-gray-900 mt-32 pt-4 pb-24 sm:pt-36 sm:pb-32 lg:pt-4">
<div className="mx-auto max-w-7xl px-6 lg:px-8">
<div className="mx-auto max-w-2xl lg:max-w-none">
<div className="text-center">
Expand Down
48 changes: 48 additions & 0 deletions apps/landing/components/landing/FooterCta.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import Link from 'next/link';
import { ROUTES } from '../../utils/environment';

export const FooterCta = () => (
<div className="relative isolate px-6 py-32 sm:py-40 lg:px-8">
<svg
aria-hidden="true"
className="absolute inset-0 -z-10 size-full stroke-white/10 [mask-image:radial-gradient(100%_100%_at_top_right,white,transparent)]"
>
<defs>
<pattern x="50%" y={0} id="1d4240dd-898f-445f-932d-e2872fd12de3" width={200} height={200} patternUnits="userSpaceOnUse">
<path d="M.5 200V.5H200" fill="none" />
</pattern>
</defs>
<svg x="50%" y={0} className="overflow-visible fill-gray-800/20">
<path d="M-200 0h201v201h-201Z M600 0h201v201h-201Z M-400 600h201v201h-201Z M200 800h201v201h-201Z" strokeWidth={0} />
</svg>
<rect fill="url(#1d4240dd-898f-445f-932d-e2872fd12de3)" width="100%" height="100%" strokeWidth={0} />
</svg>
<div aria-hidden="true" className="absolute inset-x-0 top-10 -z-10 flex transform-gpu justify-center overflow-hidden blur-3xl">
<div
style={{
clipPath:
'polygon(73.6% 51.7%, 91.7% 11.8%, 100% 46.4%, 97.4% 82.2%, 92.5% 84.9%, 75.7% 64%, 55.3% 47.5%, 46.5% 49.4%, 45% 62.9%, 50.3% 87.2%, 21.3% 64.1%, 0.1% 100%, 5.4% 51.1%, 21.4% 63.9%, 58.9% 0.2%, 73.6% 51.7%)',
}}
className="aspect-[1108/632] w-[69.25rem] flex-none bg-gradient-to-r from-[#80caff] to-[#4f46e5] opacity-20"
/>
</div>
<div className="mx-auto max-w-2xl text-center">
<h2 className="text-balance text-4xl font-semibold tracking-tight text-white sm:text-5xl">
Boost your productivity. Start using Jetstream today.
</h2>
<p className="mx-auto mt-6 max-w-xl text-lg/8 text-gray-300">
Become a Salesforce power user with Jetstream. Manage your data and metadata with ease and get more done in less time.
</p>
<div className="mt-10 flex items-center justify-center gap-x-6">
<Link
href={ROUTES.AUTH.signup}
className="py-3 px-4 rounded-md shadow bg-gradient-to-r from-teal-500 to-cyan-600 text-white font-medium hover:from-teal-600 hover:to-cyan-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-cyan-400 focus:ring-offset-gray-900"
>
Get started for free
</Link>
</div>
</div>
</div>
);

export default FooterCta;
100 changes: 47 additions & 53 deletions apps/landing/components/landing/HeaderCta.tsx
Original file line number Diff line number Diff line change
@@ -1,62 +1,56 @@
/* eslint-disable @next/next/no-img-element */
import { HeartIcon } from '@heroicons/react/solid';
import Link from 'next/link';
import { ROUTES } from '../../utils/environment';

export const HeaderCta = () => (
<div className="pt-10 bg-gray-900 sm:pt-16 lg:pt-8 lg:pb-14 lg:overflow-hidden pb-8">
<div className="mx-auto max-w-7xl lg:px-8">
<div className="lg:grid lg:grid-cols-2 lg:gap-8">
<div className="mx-auto max-w-md px-4 sm:max-w-2xl sm:px-6 sm:text-center lg:px-0 lg:text-left lg:flex lg:items-center">
<div className="lg:py-24" data-testid="home-hero-container">
<span className="px-3 py-0.5 text-white text-xs font-semibold leading-5 uppercase tracking-wide">
Jetstream is community supported and free to use
</span>
<h1 className="mt-4 text-4xl tracking-tight font-extrabold text-white sm:mt-5 sm:text-6xl lg:mt-6 xl:text-6xl">
<span className="block">A better way to</span>
<span className="pb-3 block bg-clip-text text-transparent bg-gradient-to-r from-teal-200 to-cyan-400 sm:pb-5">
work on Salesforce
</span>
</h1>
<p className="text-base text-gray-300 sm:text-xl lg:text-lg xl:text-xl">
The Jetstream platform makes managing your Salesforce instances a breeze. Use Jetstream to work with your data and metadata to
get your work done faster.
</p>
<div className="mt-6">
<Link
href={ROUTES.AUTH.signup}
className="py-3 px-4 rounded-md shadow bg-gradient-to-r from-teal-500 to-cyan-600 text-white font-medium hover:from-teal-600 hover:to-cyan-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-cyan-400 focus:ring-offset-gray-900"
>
Sign up for a free account
</Link>
</div>
<div className="mt-7">
<p className="text-base text-gray-300 sm:text-xl lg:text-lg xl:text-xl">
Jetstream is <span className="underline">free to use</span> thanks to the support of our community.
</p>
<>
<a
href={ROUTES.EXTERNAL.GITHUB_SPONSOR}
className="mt-6 inline-flex items-center py-3 px-4 rounded-md shadow bg-cyan-600 text-white font-medium hover:from-teal-600 hover:bg-cyan-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-cyan-400 focus:ring-offset-gray-900"
target="_blank"
rel="noreferrer"
>
<HeartIcon className="-ml-0.5 mr-2 h-4 w-4" aria-hidden="true" />
Become a financial sponsor
</a>
</>
</div>
<div data-testid="home-hero-container" className="relative isolate overflow-hidden bg-gray-900 pb-16 pt-14 sm:pb-20">
<svg
aria-hidden="true"
className="absolute inset-0 -z-10 size-full stroke-white/10 [mask-image:radial-gradient(100%_100%_at_top_right,white,transparent)]"
>
<defs>
<pattern x="50%" y={-1} id="header-cta-pattern" width={200} height={200} patternUnits="userSpaceOnUse">
<path d="M.5 200V.5H200" fill="none" />
</pattern>
</defs>
<svg x="50%" y={-1} className="overflow-visible fill-gray-800/20">
<path d="M-200 0h201v201h-201Z M600 0h201v201h-201Z M-400 600h201v201h-201Z M200 800h201v201h-201Z" strokeWidth={0} />
</svg>
<rect fill="url(#header-cta-pattern)" width="100%" height="100%" strokeWidth={0} />
</svg>
<div
aria-hidden="true"
className="absolute left-[calc(50%-4rem)] top-10 -z-10 transform-gpu blur-3xl sm:left-[calc(50%-18rem)] lg:left-48 lg:top-[calc(50%-30rem)] xl:left-[calc(50%-24rem)]"
>
<div
style={{
clipPath:
'polygon(73.6% 51.7%, 91.7% 11.8%, 100% 46.4%, 97.4% 82.2%, 92.5% 84.9%, 75.7% 64%, 55.3% 47.5%, 46.5% 49.4%, 45% 62.9%, 50.3% 87.2%, 21.3% 64.1%, 0.1% 100%, 5.4% 51.1%, 21.4% 63.9%, 58.9% 0.2%, 73.6% 51.7%)',
}}
className="aspect-[1108/632] w-[69.25rem] bg-gradient-to-r from-[#80caff] to-[#4f46e5] opacity-20"
/>
</div>
<div className="mx-auto max-w-2xl py-32 sm:py-48 lg:py-56">
<div className="text-center">
<div className="hidden sm:mb-8 sm:flex sm:justify-center">
<div className="relative rounded-full px-3 py-1 text-sm/6 text-gray-400 ring-1 ring-white/10 hover:ring-white/20">
Announcing the launch of additional plans.{' '}
<Link href={ROUTES.blogPost('paid-plans')} className="font-semibold text-white ml-2">
<span aria-hidden="true" className="absolute inset-0" />
Read more <span aria-hidden="true">&rarr;</span>
</Link>
</div>
</div>
<div className="mt-12 -mb-16 sm:-mb-48 lg:m-0 lg:relative">
<div className="mx-auto max-w-md px-4 sm:max-w-2xl sm:px-6 lg:max-w-none lg:px-0 hidden lg:block">
{/* Illustration taken from Lucid Illustrations: https://lucid.pixsellz.io/ */}
<img
className="w-full lg:absolute lg:inset-y-0 lg:left-0 lg:h-full lg:w-auto lg:max-w-none"
src="https://res.cloudinary.com/getjetstream/image/upload/v1634606599/public/website/cloud-illustration-teal-cyan.svg"
alt=""
/>
</div>
<h1 className="text-balance text-5xl font-semibold tracking-tight text-white sm:text-7xl">A simpler way to build on Salesforce</h1>
<p className="mt-8 text-pretty text-lg font-medium text-gray-400 sm:text-xl/8">
Streamline Salesforce management and speed up your day-to-day workflow with Jetstream.
</p>
<div className="mt-10 flex items-center justify-center gap-x-6">
<Link
href={ROUTES.AUTH.signup}
className="py-3 px-4 rounded-md shadow bg-gradient-to-r from-teal-500 to-cyan-600 text-white font-medium hover:from-teal-600 hover:to-cyan-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-cyan-400 focus:ring-offset-gray-900"
>
Get started for free
</Link>
</div>
</div>
</div>
Expand Down
28 changes: 16 additions & 12 deletions apps/landing/components/landing/LandingPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,26 @@ import AnalyticsSummary from './AnalyticsSummary';
import ConnectWithTeam from './ConnectWithTeam';
import FeatureGrid from './FeatureGrid';
import FeatureScreenshot from './FeatureScreenshot';
import HeaderCta from './HeaderCta';
import FooterCta from './FooterCta';
import { HeaderCta } from './HeaderCta';
import Learn from './Learn';
import SupportCta from './SupportCta';
import PersonaFeatures from './PersonaFeatures';
import Testimonial from './Testimonial';

export const LandingPage = ({ stats }: { stats: AnalyticStat[] }) => (
<main>
<HeaderCta />
<AnalyticsSummary stats={stats} />
<ConnectWithTeam />
<FeatureScreenshot />
<FeatureGrid />
<Testimonial />
<Learn />
<SupportCta />
</main>
<div className="bg-gray-900">
<main>
<HeaderCta />
<PersonaFeatures />
<AnalyticsSummary stats={stats} />
<ConnectWithTeam />
<FeatureScreenshot />
<FeatureGrid />
<Testimonial />
<Learn />
<FooterCta />
</main>
</div>
);

export default LandingPage;
73 changes: 73 additions & 0 deletions apps/landing/components/landing/PersonaFeatures.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import {
ArchiveBoxIcon,
ArrowTrendingUpIcon,
BugAntIcon,
BuildingOfficeIcon,
CommandLineIcon,
ShieldCheckIcon,
} from '@heroicons/react/20/solid';

const personas = [
{
name: 'Administrators',
description:
'Manage records, create fields, update permissions, and easily manage automation. Jetstream is the perfect tool for Salesforce Admins.',
icon: ShieldCheckIcon,
},
{
name: 'Developers',
description:
'Build SOQL queries, explore your data model, run Apex, subscribe and publish to Platform Events, and work with the Salesforce API.',
icon: CommandLineIcon,
},
{
name: 'QA Engineers',
description: 'Quickly view, edit, and load records to test system functionality.',
icon: BugAntIcon,
},
{
name: 'Architects',
description: 'Jetstream simplifies data-model exploration. Design solutions faster than ever.',
icon: BuildingOfficeIcon,
},
{
name: 'Deployment Managers',
description: 'Compare metadata, deploy changes, and manage your Salesforce orgs without hassle.',
icon: ArchiveBoxIcon,
},
{
name: 'Revenue Operations',
description:
'If you handle both rev-ops and admin tasks, Jetstream provides quick access to data—no tedious Salesforce reports required.',
icon: ArrowTrendingUpIcon,
},
];

export default function PersonaFeatures() {
return (
<div className="bg-gray-900 mt-32 pt-4 pb-24 sm:pt-36 sm:pb-32 lg:pt-4">
<div className="mx-auto max-w-7xl px-6 lg:px-8">
<div className="mx-auto max-w-2xl lg:max-w-none">
<div className="text-center">
<h2 className="text-3xl font-bold tracking-tight text-white sm:text-4xl">
Features for anyone administering or configuring Salesforce
</h2>
</div>

<dl className="mt-16 mx-auto grid max-w-2xl grid-cols-1 gap-x-6 gap-y-10 text-base/7 text-gray-300 sm:grid-cols-2 lg:mx-0 lg:max-w-none lg:grid-cols-3 lg:gap-x-8 lg:gap-y-16">
{personas.map((feature) => (
<div key={feature.name} className="relative pl-9">
<dt className="inline font-semibold text-white">
<feature.icon aria-hidden="true" className="absolute left-1 top-1 size-5 text-cyan-400" />
{feature.name}
</dt>
{': '}
<dd className="inline">{feature.description}</dd>
</div>
))}
</dl>
</div>
</div>
</div>
);
}
11 changes: 5 additions & 6 deletions apps/landing/pages/pricing/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { RadioGroup } from '@headlessui/react';
import { CheckIcon } from '@heroicons/react/solid';
import { CheckIcon } from '@heroicons/react/20/solid';
import classNames from 'classnames';
import Link from 'next/link';
import { useState } from 'react';
Expand All @@ -25,7 +25,7 @@ const tiers = [
},
description: 'Access to all core features.',
features: [
'10 Salesforce Org Connections',
'Unlimited Salesforce Org Connections',
'Query Builder',
'Data Loader',
'Metadata Tools',
Expand All @@ -43,10 +43,10 @@ const tiers = [
description: 'Get the most out of Jetstream.',
features: [
'Everything in Free plan',
'Unlimited Salesforce Org Connections',
'Chrome Extension',
'Save history across devices',
'Google Drive integration',
'Save downloads to Google Drive',
'Load data from Google Drive',
],
mostPopular: true,
comingSoon: false,
Expand All @@ -56,12 +56,11 @@ const tiers = [
id: 'tier-team',
href: '#',
price: { monthly: { price: 'Coming Soon', suffix: null }, annually: { price: 'Coming Soon', suffix: null } },
description: 'Get more features and save per user.',
description: `Manage your team's access for your enterprise.`,
features: [
'Everything in Professional plan',
'Team management',
'Access Control',
'25 Users Included',
'Priority support',
'Audit Logs',
'SOC II Compliance',
Expand Down
Loading
Loading