B2B-98: add package selection page (#26)

* B2B-98: add packages

* B2B-98: add packages

* rename page

* use config path instead of hardcoded

* add link to successful registration

---------

Co-authored-by: Helena <helena@Helenas-MacBook-Pro.local>
This commit is contained in:
Helena
2025-07-02 15:00:03 +03:00
committed by GitHub
parent 297dd7c221
commit 04e0bc8069
17 changed files with 260 additions and 568 deletions

View File

@@ -1,39 +0,0 @@
import { PricingTable } from '@kit/billing-gateway/marketing';
import { SitePageHeader } from '~/(marketing)/_components/site-page-header';
import billingConfig from '~/config/billing.config';
import pathsConfig from '~/config/paths.config';
import { createI18nServerInstance } from '~/lib/i18n/i18n.server';
import { withI18n } from '~/lib/i18n/with-i18n';
export const generateMetadata = async () => {
const { t } = await createI18nServerInstance();
return {
title: t('marketing:pricing'),
};
};
const paths = {
signUp: pathsConfig.auth.signUp,
return: pathsConfig.app.home,
};
async function PricingPage() {
const { t } = await createI18nServerInstance();
return (
<div className={'flex flex-col space-y-12'}>
<SitePageHeader
title={t('marketing:pricing')}
subtitle={t('marketing:pricingSubtitle')}
/>
<div className={'container mx-auto pb-8 xl:pb-16'}>
<PricingTable paths={paths} config={billingConfig} />
</div>
</div>
);
}
export default withI18n(PricingPage);

View File

@@ -2,7 +2,6 @@ import { ShoppingCart } from 'lucide-react';
import { Button } from '@kit/ui/button';
import { Trans } from '@kit/ui/trans';
import { cn } from '@kit/ui/utils';
import { AppLogo } from '~/components/app-logo';
import { ProfileAccountDropdownContainer } from '~/components/personal-account-dropdown-container';
@@ -18,7 +17,7 @@ export function HomeMenuNavigation(props: { workspace: UserWorkspace }) {
return (
<div className={'flex w-full flex-1 items-center justify-between gap-3'}>
<div className={cn('flex items-center', `w-[${SIDEBAR_WIDTH}]`)}>
<div className={`flex items-center w-[${SIDEBAR_WIDTH}]`}>
<AppLogo />
</div>
<Search

126
app/select-package/page.tsx Normal file
View File

@@ -0,0 +1,126 @@
import Image from 'next/image';
import Link from 'next/link';
import { CaretRightIcon } from '@radix-ui/react-icons';
import { Scale } from 'lucide-react';
import { Button } from '@kit/ui/button';
import {
Card,
CardContent,
CardDescription,
CardFooter,
CardHeader,
} from '@kit/ui/card';
import { createI18nServerInstance } from '~/lib/i18n/i18n.server';
import { withI18n } from '~/lib/i18n/with-i18n';
import { MedReportLogo } from '../../components/med-report-logo';
import { PackageHeader } from '../../components/package-header';
import { ButtonTooltip } from '../../components/ui/button-tooltip';
import pathsConfig from '../../config/paths.config';
export const generateMetadata = async () => {
const { t } = await createI18nServerInstance();
return {
title: t('marketing:pricing'),
};
};
const dummyCards = [
{
titleKey: 'product:standard.label',
price: 40,
nrOfAnalyses: 4,
tagColor: 'bg-cyan',
descriptionKey: 'marketing:standard.description',
},
{
titleKey: 'product:standardPlus.label',
price: 85,
nrOfAnalyses: 10,
tagColor: 'bg-warning',
descriptionKey: 'product:standardPlus.description',
},
{
titleKey: 'product:premium.label',
price: 140,
nrOfAnalyses: '12+',
tagColor: 'bg-purple',
descriptionKey: 'product:premium.description',
},
];
async function SelectPackagePage() {
const { t, language } = await createI18nServerInstance();
return (
<div className="container mx-auto my-24 flex flex-col items-center space-y-12">
<MedReportLogo />
<div className="space-y-3 text-center">
<h3>{t('marketing:selectPackage')}</h3>
<Button variant="secondary" className="gap-2">
{t('marketing:comparePackages')}
<Scale className="size-4 stroke-[1.5px]" />
</Button>
</div>
<div className="grid grid-cols-3 gap-6">
{dummyCards.map(
(
{ titleKey, price, nrOfAnalyses, tagColor, descriptionKey },
index,
) => {
return (
<Card key={index}>
<CardHeader className="relative">
<ButtonTooltip
content="Content pending"
className="absolute top-5 right-5 z-10"
/>
<Image
src="/assets/card-image.png"
alt="background"
width={326}
height={195}
className="max-h-48 w-full opacity-10"
/>
</CardHeader>
<CardContent className="space-y-1 text-center">
<PackageHeader
title={t(titleKey)}
tagColor={tagColor}
analysesNr={t('product:nrOfAnalyses', { nr: nrOfAnalyses })}
language={language}
price={price}
/>
<CardDescription>{t(descriptionKey)}</CardDescription>
</CardContent>
<CardFooter>
<Button className="w-full">
{t('marketing:selectThisPackage')}
</Button>
</CardFooter>
</Card>
);
},
)}
<div className="col-span-3 grid grid-cols-subgrid">
<div className="col-start-2 justify-self-center-safe">
<Link href={pathsConfig.app.home}>
<Button variant="secondary" className="align-center">
{t('marketing:notInterestedInAudit')}{' '}
<CaretRightIcon className="size-4" />
</Button>
</Link>
</div>
</div>
</div>
</div>
);
}
export default withI18n(SelectPackagePage);