B2B-88: cleans front page
This commit is contained in:
@@ -1,24 +1,13 @@
|
|||||||
import Image from 'next/image';
|
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
|
|
||||||
import { ArrowRightIcon, LayoutDashboard } from 'lucide-react';
|
import { ArrowRightIcon } from 'lucide-react';
|
||||||
|
|
||||||
import { PricingTable } from '@kit/billing-gateway/marketing';
|
|
||||||
import {
|
import {
|
||||||
CtaButton,
|
CtaButton,
|
||||||
FeatureCard,
|
|
||||||
FeatureGrid,
|
|
||||||
FeatureShowcase,
|
|
||||||
FeatureShowcaseIconContainer,
|
|
||||||
Hero,
|
Hero,
|
||||||
Pill,
|
|
||||||
PillActionButton,
|
|
||||||
SecondaryHero,
|
|
||||||
} from '@kit/ui/marketing';
|
} from '@kit/ui/marketing';
|
||||||
import { Trans } from '@kit/ui/trans';
|
import { Trans } from '@kit/ui/trans';
|
||||||
|
|
||||||
import billingConfig from '~/config/billing.config';
|
|
||||||
import pathsConfig from '~/config/paths.config';
|
|
||||||
import { withI18n } from '~/lib/i18n/with-i18n';
|
import { withI18n } from '~/lib/i18n/with-i18n';
|
||||||
|
|
||||||
function Home() {
|
function Home() {
|
||||||
@@ -26,126 +15,20 @@ function Home() {
|
|||||||
<div className={'mt-4 flex flex-col space-y-24 py-14'}>
|
<div className={'mt-4 flex flex-col space-y-24 py-14'}>
|
||||||
<div className={'container mx-auto'}>
|
<div className={'container mx-auto'}>
|
||||||
<Hero
|
<Hero
|
||||||
pill={
|
|
||||||
<Pill label={'New'}>
|
|
||||||
<span>The SaaS Starter Kit for ambitious developers</span>
|
|
||||||
<PillActionButton asChild>
|
|
||||||
<Link href={'/auth/sign-up'}>
|
|
||||||
<ArrowRightIcon className={'h-4 w-4'} />
|
|
||||||
</Link>
|
|
||||||
</PillActionButton>
|
|
||||||
</Pill>
|
|
||||||
}
|
|
||||||
title={
|
title={
|
||||||
<>
|
<>
|
||||||
<span>The ultimate SaaS Starter</span>
|
<span>Med Report</span>
|
||||||
<span>for your next project</span>
|
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
subtitle={
|
subtitle={
|
||||||
<span>
|
<span>
|
||||||
Build and Ship a SaaS faster than ever before with the next-gen
|
Lihtne, mugav ja kiire ülevaade Sinu tervise seisundist
|
||||||
SaaS Starter Kit. Ship your SaaS in days, not months.
|
|
||||||
</span>
|
</span>
|
||||||
}
|
}
|
||||||
cta={<MainCallToActionButton />}
|
cta={<MainCallToActionButton />}
|
||||||
image={
|
|
||||||
<Image
|
|
||||||
priority
|
|
||||||
className={
|
|
||||||
'dark:border-primary/10 rounded-xl border border-gray-200'
|
|
||||||
}
|
|
||||||
width={3558}
|
|
||||||
height={2222}
|
|
||||||
src={`/images/dashboard.webp`}
|
|
||||||
alt={`App Image`}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className={'container 2 mx-auto'}>
|
|
||||||
<div
|
|
||||||
className={'flex flex-col space-y-16 xl:space-y-32 2xl:space-y-36'}
|
|
||||||
>
|
|
||||||
<FeatureShowcase
|
|
||||||
heading={
|
|
||||||
<>
|
|
||||||
<b className="font-medium tracking-tighter dark:text-white">
|
|
||||||
The ultimate SaaS Starter Kit
|
|
||||||
</b>
|
|
||||||
.{' '}
|
|
||||||
<span className="text-muted-foreground font-normal tracking-tighter">
|
|
||||||
Unleash your creativity and build your SaaS faster than ever
|
|
||||||
with Makerkit.
|
|
||||||
</span>
|
|
||||||
</>
|
|
||||||
}
|
|
||||||
icon={
|
|
||||||
<FeatureShowcaseIconContainer>
|
|
||||||
<LayoutDashboard className="h-5" />
|
|
||||||
<span>All-in-one solution</span>
|
|
||||||
</FeatureShowcaseIconContainer>
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<FeatureGrid>
|
|
||||||
<FeatureCard
|
|
||||||
className={'relative col-span-1 overflow-hidden'}
|
|
||||||
label={'Beautiful Dashboard'}
|
|
||||||
description={`Makerkit provides a beautiful dashboard to manage your SaaS business.`}
|
|
||||||
></FeatureCard>
|
|
||||||
|
|
||||||
<FeatureCard
|
|
||||||
className={'relative col-span-1 w-full overflow-hidden'}
|
|
||||||
label={'Authentication'}
|
|
||||||
description={`Makerkit provides a variety of providers to allow your users to sign in.`}
|
|
||||||
></FeatureCard>
|
|
||||||
|
|
||||||
<FeatureCard
|
|
||||||
className={'relative col-span-1 overflow-hidden'}
|
|
||||||
label={'Multi Tenancy'}
|
|
||||||
description={`Multi tenant memberships for your SaaS business.`}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FeatureCard
|
|
||||||
className={'relative col-span-1 overflow-hidden md:col-span-2'}
|
|
||||||
label={'Billing'}
|
|
||||||
description={`Makerkit supports multiple payment gateways to charge your customers.`}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FeatureCard
|
|
||||||
className={'relative col-span-1 overflow-hidden'}
|
|
||||||
label={'Plugins'}
|
|
||||||
description={`Extend your SaaS with plugins that you can install using the CLI.`}
|
|
||||||
/>
|
|
||||||
</FeatureGrid>
|
|
||||||
</FeatureShowcase>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className={'container mx-auto'}>
|
|
||||||
<div
|
|
||||||
className={
|
|
||||||
'flex flex-col items-center justify-center space-y-16 py-16'
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<SecondaryHero
|
|
||||||
pill={<Pill label="Start for free">No credit card required.</Pill>}
|
|
||||||
heading="Fair pricing for all types of businesses"
|
|
||||||
subheading="Get started on our free plan and upgrade when you are ready."
|
|
||||||
/>
|
|
||||||
|
|
||||||
<div className={'w-full'}>
|
|
||||||
<PricingTable
|
|
||||||
config={billingConfig}
|
|
||||||
paths={{
|
|
||||||
signUp: pathsConfig.auth.signUp,
|
|
||||||
return: pathsConfig.app.home,
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,28 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
|
|
||||||
import { cn } from '../../lib/utils';
|
|
||||||
import { CardDescription, CardHeader, CardTitle } from '../../shadcn/card';
|
|
||||||
|
|
||||||
interface FeatureCardProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
||||||
label: string;
|
|
||||||
description: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const FeatureCard: React.FC<FeatureCardProps> = ({
|
|
||||||
className,
|
|
||||||
label,
|
|
||||||
description,
|
|
||||||
...props
|
|
||||||
}) => {
|
|
||||||
return (
|
|
||||||
<div className={cn('rounded-xl border p-4', className)} {...props}>
|
|
||||||
<CardHeader>
|
|
||||||
<CardTitle className="text-xl font-medium">{label}</CardTitle>
|
|
||||||
|
|
||||||
<CardDescription className="text-muted-foreground max-w-xs text-sm font-normal">
|
|
||||||
{description}
|
|
||||||
</CardDescription>
|
|
||||||
</CardHeader>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
|
|
||||||
import { cn } from '../../lib/utils';
|
|
||||||
|
|
||||||
export const FeatureGrid: React.FC<React.HTMLAttributes<HTMLDivElement>> =
|
|
||||||
function FeatureGridComponent({ className, children, ...props }) {
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
className={cn(
|
|
||||||
'mt-2 grid w-full grid-cols-1 gap-4 md:mt-6 md:grid-cols-2 md:grid-cols-3 lg:grid-cols-3',
|
|
||||||
className,
|
|
||||||
)}
|
|
||||||
{...props}
|
|
||||||
>
|
|
||||||
{children}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
|
|
||||||
import { cn } from '../../lib/utils';
|
|
||||||
|
|
||||||
interface FeatureShowcaseProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
||||||
heading: React.ReactNode;
|
|
||||||
icon?: React.ReactNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const FeatureShowcase: React.FC<FeatureShowcaseProps> =
|
|
||||||
function FeatureShowcaseComponent({
|
|
||||||
className,
|
|
||||||
heading,
|
|
||||||
icon,
|
|
||||||
children,
|
|
||||||
...props
|
|
||||||
}) {
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
className={cn('flex flex-col justify-between space-y-8', className)}
|
|
||||||
{...props}
|
|
||||||
>
|
|
||||||
<div className="flex w-full max-w-5xl flex-col gap-y-4">
|
|
||||||
{icon && <div className="flex">{icon}</div>}
|
|
||||||
<h3 className="text-3xl font-normal tracking-tight xl:text-5xl">
|
|
||||||
{heading}
|
|
||||||
</h3>
|
|
||||||
</div>
|
|
||||||
{children}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export function FeatureShowcaseIconContainer(
|
|
||||||
props: React.PropsWithChildren<{
|
|
||||||
className?: string;
|
|
||||||
}>,
|
|
||||||
) {
|
|
||||||
return (
|
|
||||||
<div className={'flex'}>
|
|
||||||
<div
|
|
||||||
className={cn(
|
|
||||||
'flex items-center justify-center space-x-4 rounded-lg p-3 font-medium',
|
|
||||||
props.className,
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
{props.children}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,15 +1,10 @@
|
|||||||
export * from './hero-title';
|
export * from './hero-title';
|
||||||
export * from './pill';
|
|
||||||
export * from './gradient-secondary-text';
|
export * from './gradient-secondary-text';
|
||||||
export * from './gradient-text';
|
export * from './gradient-text';
|
||||||
export * from './hero';
|
export * from './hero';
|
||||||
export * from './secondary-hero';
|
|
||||||
export * from './cta-button';
|
export * from './cta-button';
|
||||||
export * from './header';
|
export * from './header';
|
||||||
export * from './footer';
|
export * from './footer';
|
||||||
export * from './feature-showcase';
|
|
||||||
export * from './feature-grid';
|
|
||||||
export * from './feature-card';
|
|
||||||
export * from './newsletter-signup';
|
export * from './newsletter-signup';
|
||||||
export * from './newsletter-signup-container';
|
export * from './newsletter-signup-container';
|
||||||
export * from './coming-soon';
|
export * from './coming-soon';
|
||||||
|
|||||||
@@ -1,59 +0,0 @@
|
|||||||
import { Slot, Slottable } from '@radix-ui/react-slot';
|
|
||||||
|
|
||||||
import { cn } from '../../lib/utils';
|
|
||||||
import { GradientSecondaryText } from './gradient-secondary-text';
|
|
||||||
|
|
||||||
export const Pill: React.FC<
|
|
||||||
React.HTMLAttributes<HTMLHeadingElement> & {
|
|
||||||
label?: React.ReactNode;
|
|
||||||
asChild?: boolean;
|
|
||||||
}
|
|
||||||
> = function PillComponent({ className, asChild, ...props }) {
|
|
||||||
const Comp = asChild ? Slot : 'h3';
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Comp
|
|
||||||
className={cn(
|
|
||||||
'bg-muted/50 flex items-center gap-x-1.5 rounded-full border px-2 py-1 pr-2 text-center text-sm font-medium text-transparent',
|
|
||||||
className,
|
|
||||||
)}
|
|
||||||
{...props}
|
|
||||||
>
|
|
||||||
{props.label && (
|
|
||||||
<span
|
|
||||||
className={
|
|
||||||
'text-primary-foreground bg-primary rounded-2xl border px-1.5 py-0.5 text-xs font-bold tracking-tight'
|
|
||||||
}
|
|
||||||
>
|
|
||||||
{props.label}
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
<Slottable>
|
|
||||||
<GradientSecondaryText
|
|
||||||
className={'flex items-center gap-x-2 font-semibold tracking-tight'}
|
|
||||||
>
|
|
||||||
{props.children}
|
|
||||||
</GradientSecondaryText>
|
|
||||||
</Slottable>
|
|
||||||
</Comp>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const PillActionButton: React.FC<
|
|
||||||
React.HTMLAttributes<HTMLButtonElement> & {
|
|
||||||
asChild?: boolean;
|
|
||||||
}
|
|
||||||
> = ({ asChild, ...props }) => {
|
|
||||||
const Comp = asChild ? Slot : 'button';
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Comp
|
|
||||||
{...props}
|
|
||||||
className={
|
|
||||||
'text-secondary-foreground bg-input active:bg-primary active:text-primary-foreground hover:ring-muted-foreground/50 rounded-full px-1.5 py-1.5 text-center text-sm font-medium ring ring-transparent transition-colors'
|
|
||||||
}
|
|
||||||
>
|
|
||||||
{props.children}
|
|
||||||
</Comp>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
import { cn } from '../../lib/utils';
|
|
||||||
import { Heading } from '../../shadcn/heading';
|
|
||||||
|
|
||||||
interface SecondaryHeroProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
||||||
pill?: React.ReactNode;
|
|
||||||
heading: React.ReactNode;
|
|
||||||
subheading: React.ReactNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const SecondaryHero: React.FC<SecondaryHeroProps> =
|
|
||||||
function SecondaryHeroComponent({
|
|
||||||
className,
|
|
||||||
pill,
|
|
||||||
heading,
|
|
||||||
subheading,
|
|
||||||
children,
|
|
||||||
...props
|
|
||||||
}) {
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
className={cn(
|
|
||||||
'flex flex-col items-center space-y-6 text-center',
|
|
||||||
className,
|
|
||||||
)}
|
|
||||||
{...props}
|
|
||||||
>
|
|
||||||
{pill}
|
|
||||||
|
|
||||||
<div className="flex flex-col">
|
|
||||||
<Heading level={2} className="tracking-tighter">
|
|
||||||
{heading}
|
|
||||||
</Heading>
|
|
||||||
|
|
||||||
<h3 className="text-muted-foreground font-sans text-xl font-normal tracking-tight">
|
|
||||||
{subheading}
|
|
||||||
</h3>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{children}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
Reference in New Issue
Block a user