B2B-99: add package comparison modal (#27)
* B2B-99: add pacakge comparison modal * B2B-99: add package comparison modal --------- Co-authored-by: Helena <helena@Helenas-MacBook-Pro.local>
This commit is contained in:
204
app/home/(user)/_components/compare-packages-modal.tsx
Normal file
204
app/home/(user)/_components/compare-packages-modal.tsx
Normal file
@@ -0,0 +1,204 @@
|
|||||||
|
import { JSX } from 'react';
|
||||||
|
|
||||||
|
import { QuestionMarkCircledIcon } from '@radix-ui/react-icons';
|
||||||
|
import { VisuallyHidden } from '@radix-ui/react-visually-hidden';
|
||||||
|
import { Check, X } from 'lucide-react';
|
||||||
|
|
||||||
|
import {
|
||||||
|
Dialog,
|
||||||
|
DialogContent,
|
||||||
|
DialogTitle,
|
||||||
|
DialogTrigger,
|
||||||
|
} from '@kit/ui/dialog';
|
||||||
|
import {
|
||||||
|
Table,
|
||||||
|
TableBody,
|
||||||
|
TableCell,
|
||||||
|
TableHead,
|
||||||
|
TableHeader,
|
||||||
|
TableRow,
|
||||||
|
} from '@kit/ui/table';
|
||||||
|
|
||||||
|
import { createI18nServerInstance } from '~/lib/i18n/i18n.server';
|
||||||
|
import { withI18n } from '~/lib/i18n/with-i18n';
|
||||||
|
|
||||||
|
import { PackageHeader } from '../../../../components/package-header';
|
||||||
|
import { InfoTooltip } from '../../../../components/ui/info-tooltip';
|
||||||
|
|
||||||
|
const dummyCards = [
|
||||||
|
{
|
||||||
|
titleKey: 'product:standard.label',
|
||||||
|
price: 40,
|
||||||
|
nrOfAnalyses: 4,
|
||||||
|
tagColor: 'bg-cyan',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
titleKey: 'product:standardPlus.label',
|
||||||
|
price: 85,
|
||||||
|
nrOfAnalyses: 10,
|
||||||
|
tagColor: 'bg-warning',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
titleKey: 'product:premium.label',
|
||||||
|
price: 140,
|
||||||
|
nrOfAnalyses: '12+',
|
||||||
|
tagColor: 'bg-purple',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const dummyRows = [
|
||||||
|
{
|
||||||
|
analysisNameKey: 'product:clinicalBloodDraw.label',
|
||||||
|
tooltipContentKey: 'product:clinicalBloodDraw.description',
|
||||||
|
includedInStandard: 1,
|
||||||
|
includedInStandardPlus: 1,
|
||||||
|
includedInPremium: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
analysisNameKey: 'product:crp.label',
|
||||||
|
tooltipContentKey: 'product:crp.description',
|
||||||
|
includedInStandard: 1,
|
||||||
|
includedInStandardPlus: 1,
|
||||||
|
includedInPremium: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
analysisNameKey: 'product:ferritin.label',
|
||||||
|
tooltipContentKey: 'product:ferritin.description',
|
||||||
|
includedInStandard: 0,
|
||||||
|
includedInStandardPlus: 1,
|
||||||
|
includedInPremium: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
analysisNameKey: 'product:vitaminD.label',
|
||||||
|
tooltipContentKey: 'product:vitaminD.description',
|
||||||
|
includedInStandard: 0,
|
||||||
|
includedInStandardPlus: 1,
|
||||||
|
includedInPremium: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
analysisNameKey: 'product:glucose.label',
|
||||||
|
tooltipContentKey: 'product:glucose.description',
|
||||||
|
includedInStandard: 1,
|
||||||
|
includedInStandardPlus: 1,
|
||||||
|
includedInPremium: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
analysisNameKey: 'product:alat.label',
|
||||||
|
tooltipContentKey: 'product:alat.description',
|
||||||
|
includedInStandard: 1,
|
||||||
|
includedInStandardPlus: 1,
|
||||||
|
includedInPremium: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
analysisNameKey: 'product:ast.label',
|
||||||
|
tooltipContentKey: 'product:ast.description',
|
||||||
|
includedInStandard: 1,
|
||||||
|
includedInStandardPlus: 1,
|
||||||
|
includedInPremium: 1,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const CheckWithBackground = () => {
|
||||||
|
return (
|
||||||
|
<div className="bg-primary w-min rounded-full p-1 text-white">
|
||||||
|
<Check className="size-3 stroke-2" />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const ComparePackagesModal = async ({
|
||||||
|
triggerElement,
|
||||||
|
}: {
|
||||||
|
triggerElement: JSX.Element;
|
||||||
|
}) => {
|
||||||
|
const { t, language } = await createI18nServerInstance();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Dialog>
|
||||||
|
<DialogTrigger asChild>{triggerElement}</DialogTrigger>
|
||||||
|
<DialogContent
|
||||||
|
className="min-h-screen max-w-fit min-w-screen"
|
||||||
|
customClose={
|
||||||
|
<div className="inline-flex place-items-center-safe gap-1 align-middle">
|
||||||
|
<p className="text-sm font-medium text-black">
|
||||||
|
{t('common:close')}
|
||||||
|
</p>
|
||||||
|
<X className="text-black" />
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
preventAutoFocus
|
||||||
|
>
|
||||||
|
<VisuallyHidden>
|
||||||
|
<DialogTitle>{t('common:comparePackages')}</DialogTitle>
|
||||||
|
</VisuallyHidden>
|
||||||
|
<div className="m-auto">
|
||||||
|
<div className="space-y-6 text-center">
|
||||||
|
<h3>{t('product:healthPackageComparison.label')}</h3>
|
||||||
|
<p className="text-muted-foreground mx-auto w-3/5 text-sm">
|
||||||
|
{t('product:healthPackageComparison.description')}
|
||||||
|
</p>
|
||||||
|
<div className="rounded-md border">
|
||||||
|
<Table>
|
||||||
|
<TableHeader>
|
||||||
|
<TableRow>
|
||||||
|
<TableHead></TableHead>
|
||||||
|
{dummyCards.map(
|
||||||
|
({ titleKey, price, nrOfAnalyses, tagColor }) => (
|
||||||
|
<TableHead key={titleKey} className="py-2">
|
||||||
|
<PackageHeader
|
||||||
|
title={t(titleKey)}
|
||||||
|
tagColor={tagColor}
|
||||||
|
analysesNr={t('product:nrOfAnalyses', {
|
||||||
|
nr: nrOfAnalyses,
|
||||||
|
})}
|
||||||
|
language={language}
|
||||||
|
price={price}
|
||||||
|
/>
|
||||||
|
</TableHead>
|
||||||
|
),
|
||||||
|
)}
|
||||||
|
</TableRow>
|
||||||
|
</TableHeader>
|
||||||
|
<TableBody>
|
||||||
|
{dummyRows.map(
|
||||||
|
(
|
||||||
|
{
|
||||||
|
analysisNameKey,
|
||||||
|
tooltipContentKey,
|
||||||
|
includedInStandard,
|
||||||
|
includedInStandardPlus,
|
||||||
|
includedInPremium,
|
||||||
|
},
|
||||||
|
index,
|
||||||
|
) => (
|
||||||
|
<TableRow key={index}>
|
||||||
|
<TableCell className="py-6">
|
||||||
|
{t(analysisNameKey)}{' '}
|
||||||
|
<InfoTooltip
|
||||||
|
content={t(tooltipContentKey)}
|
||||||
|
icon={<QuestionMarkCircledIcon />}
|
||||||
|
/>
|
||||||
|
</TableCell>
|
||||||
|
<TableCell align="center" className="py-6">
|
||||||
|
{!!includedInStandard && <CheckWithBackground />}
|
||||||
|
</TableCell>
|
||||||
|
<TableCell align="center" className="py-6">
|
||||||
|
{!!includedInStandardPlus && <CheckWithBackground />}
|
||||||
|
</TableCell>
|
||||||
|
<TableCell align="center" className="py-6">
|
||||||
|
{!!includedInPremium && <CheckWithBackground />}
|
||||||
|
</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
),
|
||||||
|
)}
|
||||||
|
</TableBody>
|
||||||
|
</Table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</DialogContent>
|
||||||
|
</Dialog>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default withI18n(ComparePackagesModal);
|
||||||
@@ -20,6 +20,7 @@ import { MedReportLogo } from '../../components/med-report-logo';
|
|||||||
import { PackageHeader } from '../../components/package-header';
|
import { PackageHeader } from '../../components/package-header';
|
||||||
import { ButtonTooltip } from '../../components/ui/button-tooltip';
|
import { ButtonTooltip } from '../../components/ui/button-tooltip';
|
||||||
import pathsConfig from '../../config/paths.config';
|
import pathsConfig from '../../config/paths.config';
|
||||||
|
import ComparePackagesModal from '../home/(user)/_components/compare-packages-modal';
|
||||||
|
|
||||||
export const generateMetadata = async () => {
|
export const generateMetadata = async () => {
|
||||||
const { t } = await createI18nServerInstance();
|
const { t } = await createI18nServerInstance();
|
||||||
@@ -63,10 +64,14 @@ async function SelectPackagePage() {
|
|||||||
<MedReportLogo />
|
<MedReportLogo />
|
||||||
<div className="space-y-3 text-center">
|
<div className="space-y-3 text-center">
|
||||||
<h3>{t('marketing:selectPackage')}</h3>
|
<h3>{t('marketing:selectPackage')}</h3>
|
||||||
<Button variant="secondary" className="gap-2">
|
<ComparePackagesModal
|
||||||
{t('marketing:comparePackages')}
|
triggerElement={
|
||||||
<Scale className="size-4 stroke-[1.5px]" />
|
<Button variant="secondary" className="gap-2">
|
||||||
</Button>
|
{t('marketing:comparePackages')}
|
||||||
|
<Scale className="size-4 stroke-[1.5px]" />
|
||||||
|
</Button>
|
||||||
|
}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="grid grid-cols-3 gap-6">
|
<div className="grid grid-cols-3 gap-6">
|
||||||
{dummyCards.map(
|
{dummyCards.map(
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { formatCurrency } from "@kit/shared/utils";
|
import { formatCurrency } from '@kit/shared/utils';
|
||||||
import { Badge } from "@kit/ui/badge";
|
import { Badge } from '@kit/ui/badge';
|
||||||
import { cn } from "@kit/ui/utils";
|
import { cn } from '@kit/ui/utils';
|
||||||
|
|
||||||
export const PackageHeader = ({
|
export const PackageHeader = ({
|
||||||
title,
|
title,
|
||||||
@@ -18,7 +18,6 @@ export const PackageHeader = ({
|
|||||||
return (
|
return (
|
||||||
<div className="space-y-1 text-center">
|
<div className="space-y-1 text-center">
|
||||||
<p className="font-medium">{title}</p>
|
<p className="font-medium">{title}</p>
|
||||||
<Badge className={cn('text-xs', tagColor)}>{analysesNr}</Badge>
|
|
||||||
<h2>
|
<h2>
|
||||||
{formatCurrency({
|
{formatCurrency({
|
||||||
currencyCode: 'eur',
|
currencyCode: 'eur',
|
||||||
@@ -26,6 +25,7 @@ export const PackageHeader = ({
|
|||||||
value: price,
|
value: price,
|
||||||
})}
|
})}
|
||||||
</h2>
|
</h2>
|
||||||
|
<Badge className={cn('text-xs', tagColor)}>{analysesNr}</Badge>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@@ -1,13 +1,27 @@
|
|||||||
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@kit/ui/tooltip";
|
import { JSX } from 'react';
|
||||||
import { Info } from "lucide-react";
|
|
||||||
|
|
||||||
export function InfoTooltip({ content }: { content?: string }) {
|
import { Info } from 'lucide-react';
|
||||||
|
|
||||||
|
import {
|
||||||
|
Tooltip,
|
||||||
|
TooltipContent,
|
||||||
|
TooltipProvider,
|
||||||
|
TooltipTrigger,
|
||||||
|
} from '@kit/ui/tooltip';
|
||||||
|
|
||||||
|
export function InfoTooltip({
|
||||||
|
content,
|
||||||
|
icon,
|
||||||
|
}: {
|
||||||
|
content?: string;
|
||||||
|
icon?: JSX.Element;
|
||||||
|
}) {
|
||||||
if (!content) return null;
|
if (!content) return null;
|
||||||
return (
|
return (
|
||||||
<TooltipProvider>
|
<TooltipProvider>
|
||||||
<Tooltip>
|
<Tooltip>
|
||||||
<TooltipTrigger>
|
<TooltipTrigger>
|
||||||
<Info className="size-4 cursor-pointer" />
|
{icon || <Info className="size-4 cursor-pointer" />}
|
||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
<TooltipContent>{content}</TooltipContent>
|
<TooltipContent>{content}</TooltipContent>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
|||||||
@@ -56,6 +56,7 @@
|
|||||||
"@marsidev/react-turnstile": "^1.1.0",
|
"@marsidev/react-turnstile": "^1.1.0",
|
||||||
"@nosecone/next": "1.0.0-beta.7",
|
"@nosecone/next": "1.0.0-beta.7",
|
||||||
"@radix-ui/react-icons": "^1.3.2",
|
"@radix-ui/react-icons": "^1.3.2",
|
||||||
|
"@radix-ui/react-visually-hidden": "^1.2.3",
|
||||||
"@supabase/ssr": "^0.6.1",
|
"@supabase/ssr": "^0.6.1",
|
||||||
"@supabase/supabase-js": "2.49.4",
|
"@supabase/supabase-js": "2.49.4",
|
||||||
"@tanstack/react-query": "5.76.1",
|
"@tanstack/react-query": "5.76.1",
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ function PageWithHeader(props: PageProps) {
|
|||||||
const { Navigation, Children, MobileNavigation } = getSlotsFromPage(props);
|
const { Navigation, Children, MobileNavigation } = getSlotsFromPage(props);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={cn('flex h-screen flex-1 flex-col z-1000', props.className)}>
|
<div className={cn('flex h-screen flex-1 flex-col z-900', props.className)}>
|
||||||
<div
|
<div
|
||||||
className={
|
className={
|
||||||
props.contentContainerClassName ?? 'flex flex-1 flex-col space-y-4'
|
props.contentContainerClassName ?? 'flex flex-1 flex-col space-y-4'
|
||||||
|
|||||||
@@ -7,12 +7,12 @@ import type { VariantProps } from 'class-variance-authority';
|
|||||||
import { cn } from '../lib/utils';
|
import { cn } from '../lib/utils';
|
||||||
|
|
||||||
const buttonVariants = cva(
|
const buttonVariants = cva(
|
||||||
'focus-visible:ring-ring gap-1 inline-flex items-center justify-center rounded-md text-sm font-medium whitespace-nowrap transition-colors focus-visible:ring-1 focus-visible:outline-hidden disabled:pointer-events-none disabled:opacity-50',
|
'inline-flex items-center justify-center gap-1 rounded-md text-sm font-medium whitespace-nowrap transition-colors focus-visible:outline-hidden disabled:pointer-events-none disabled:opacity-50',
|
||||||
{
|
{
|
||||||
variants: {
|
variants: {
|
||||||
variant: {
|
variant: {
|
||||||
default:
|
default:
|
||||||
'bg-primary text-primary-foreground font-medium hover:bg-primary/90 shadow-xs',
|
'bg-primary text-primary-foreground hover:bg-primary/90 font-medium shadow-xs',
|
||||||
destructive:
|
destructive:
|
||||||
'bg-destructive text-destructive-foreground hover:bg-destructive/90 shadow-xs',
|
'bg-destructive text-destructive-foreground hover:bg-destructive/90 shadow-xs',
|
||||||
outline:
|
outline:
|
||||||
@@ -23,7 +23,7 @@ const buttonVariants = cva(
|
|||||||
link: 'decoration-primary underline-offset-4 hover:underline',
|
link: 'decoration-primary underline-offset-4 hover:underline',
|
||||||
},
|
},
|
||||||
size: {
|
size: {
|
||||||
default: 'h-10 mt-0 py-2 px-8',
|
default: 'mt-0 h-10 px-8 py-2',
|
||||||
sm: 'h-8 rounded-md px-3 text-xs',
|
sm: 'h-8 rounded-md px-3 text-xs',
|
||||||
lg: 'h-10 rounded-md px-8',
|
lg: 'h-10 rounded-md px-8',
|
||||||
icon: 'h-9 w-9',
|
icon: 'h-9 w-9',
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ const DialogOverlay: React.FC<
|
|||||||
> = ({ className, ...props }) => (
|
> = ({ className, ...props }) => (
|
||||||
<DialogPrimitive.Overlay
|
<DialogPrimitive.Overlay
|
||||||
className={cn(
|
className={cn(
|
||||||
'data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/30',
|
'data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-1000 bg-black/30',
|
||||||
className,
|
className,
|
||||||
)}
|
)}
|
||||||
{...props}
|
{...props}
|
||||||
@@ -29,25 +29,39 @@ const DialogOverlay: React.FC<
|
|||||||
DialogOverlay.displayName = DialogPrimitive.Overlay.displayName;
|
DialogOverlay.displayName = DialogPrimitive.Overlay.displayName;
|
||||||
|
|
||||||
const DialogContent: React.FC<
|
const DialogContent: React.FC<
|
||||||
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content>
|
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content> & {
|
||||||
> = ({ className, children, ...props }) => (
|
customClose?: React.JSX.Element;
|
||||||
|
preventAutoFocus?: boolean;
|
||||||
|
}
|
||||||
|
> = ({ className, children, customClose, preventAutoFocus, ...props }) => (
|
||||||
<DialogPortal>
|
<DialogPortal>
|
||||||
<DialogOverlay />
|
<DialogOverlay />
|
||||||
<DialogPrimitive.Content
|
<DialogPrimitive.Content
|
||||||
className={cn(
|
className={cn(
|
||||||
'bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border p-6 shadow-lg duration-200 sm:rounded-lg',
|
'bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-1000 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border p-6 shadow-lg duration-200 sm:rounded-lg',
|
||||||
className,
|
className,
|
||||||
)}
|
)}
|
||||||
|
onOpenAutoFocus={
|
||||||
|
preventAutoFocus ? (e) => e.preventDefault() : props.onOpenAutoFocus
|
||||||
|
}
|
||||||
|
onCloseAutoFocus={
|
||||||
|
preventAutoFocus ? (e) => e.preventDefault() : props.onOpenAutoFocus
|
||||||
|
}
|
||||||
{...props}
|
{...props}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
<DialogPrimitive.Close className="ring-offset-background focus:ring-ring data-[state=open]:bg-accent data-[state=open]:text-muted-foreground absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none">
|
<DialogPrimitive.Close className="ring-offset-background focus:ring-ring data-[state=open]:bg-accent data-[state=open]:text-muted-foreground absolute top-4 right-4 rounded-xs transition-opacity hover:opacity-70 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none">
|
||||||
<Cross2Icon className="h-4 w-4" />
|
{customClose || (
|
||||||
<span className="sr-only">Close</span>
|
<>
|
||||||
|
<Cross2Icon className="h-4 w-4" />
|
||||||
|
<span className="sr-only">Close</span>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</DialogPrimitive.Close>
|
</DialogPrimitive.Close>
|
||||||
</DialogPrimitive.Content>
|
</DialogPrimitive.Content>
|
||||||
</DialogPortal>
|
</DialogPortal>
|
||||||
);
|
);
|
||||||
|
|
||||||
DialogContent.displayName = DialogPrimitive.Content.displayName;
|
DialogContent.displayName = DialogPrimitive.Content.displayName;
|
||||||
|
|
||||||
const DialogHeader = ({
|
const DialogHeader = ({
|
||||||
|
|||||||
@@ -6,8 +6,18 @@ import * as TooltipPrimitive from '@radix-ui/react-tooltip';
|
|||||||
|
|
||||||
import { cn } from '../lib/utils';
|
import { cn } from '../lib/utils';
|
||||||
|
|
||||||
const TooltipProvider = TooltipPrimitive.Provider;
|
function TooltipProvider({
|
||||||
|
delayDuration = 0,
|
||||||
|
...props
|
||||||
|
}: React.ComponentProps<typeof TooltipPrimitive.Provider>) {
|
||||||
|
return (
|
||||||
|
<TooltipPrimitive.Provider
|
||||||
|
data-slot="tooltip-provider"
|
||||||
|
delayDuration={delayDuration}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
const Tooltip = TooltipPrimitive.Root;
|
const Tooltip = TooltipPrimitive.Root;
|
||||||
|
|
||||||
const TooltipTrigger = TooltipPrimitive.Trigger;
|
const TooltipTrigger = TooltipPrimitive.Trigger;
|
||||||
|
|||||||
5
pnpm-lock.yaml
generated
5
pnpm-lock.yaml
generated
@@ -83,6 +83,9 @@ importers:
|
|||||||
'@radix-ui/react-icons':
|
'@radix-ui/react-icons':
|
||||||
specifier: ^1.3.2
|
specifier: ^1.3.2
|
||||||
version: 1.3.2(react@19.1.0)
|
version: 1.3.2(react@19.1.0)
|
||||||
|
'@radix-ui/react-visually-hidden':
|
||||||
|
specifier: ^1.2.3
|
||||||
|
version: 1.2.3(@types/react-dom@19.1.5(@types/react@19.1.4))(@types/react@19.1.4)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
|
||||||
'@supabase/ssr':
|
'@supabase/ssr':
|
||||||
specifier: ^0.6.1
|
specifier: ^0.6.1
|
||||||
version: 0.6.1(@supabase/supabase-js@2.49.4)
|
version: 0.6.1(@supabase/supabase-js@2.49.4)
|
||||||
@@ -13116,7 +13119,7 @@ snapshots:
|
|||||||
|
|
||||||
jest-worker@27.5.1:
|
jest-worker@27.5.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/node': 24.0.3
|
'@types/node': 22.15.32
|
||||||
merge-stream: 2.0.0
|
merge-stream: 2.0.0
|
||||||
supports-color: 8.1.1
|
supports-color: 8.1.1
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
"imageInputLabel": "Click here to upload an image",
|
"imageInputLabel": "Click here to upload an image",
|
||||||
"cancel": "Cancel",
|
"cancel": "Cancel",
|
||||||
"clear": "Clear",
|
"clear": "Clear",
|
||||||
|
"close": "Close",
|
||||||
"notFound": "Not Found",
|
"notFound": "Not Found",
|
||||||
"backToHomePage": "Back to Home Page",
|
"backToHomePage": "Back to Home Page",
|
||||||
"goBack": "Go Back",
|
"goBack": "Go Back",
|
||||||
@@ -59,6 +60,10 @@
|
|||||||
"shoppingCart": "Shopping cart",
|
"shoppingCart": "Shopping cart",
|
||||||
"search": "Search{{end}}",
|
"search": "Search{{end}}",
|
||||||
"myActions": "My actions",
|
"myActions": "My actions",
|
||||||
|
"healthPackageComparison": {
|
||||||
|
"label": "Health package comparison",
|
||||||
|
"description": "Alljärgnevalt on antud eelinfo (sugu, vanus ja kehamassiindeksi) põhjal tehtud personalne terviseauditi valik. Tabelis on võimalik soovitatud terviseuuringute paketile lisada üksikuid uuringuid juurde."
|
||||||
|
},
|
||||||
"routes": {
|
"routes": {
|
||||||
"home": "Home",
|
"home": "Home",
|
||||||
"overview": "Overview",
|
"overview": "Overview",
|
||||||
|
|||||||
@@ -11,5 +11,33 @@
|
|||||||
"label": "Premium",
|
"label": "Premium",
|
||||||
"description": "Sobib, kui soovid lisaks peamistele tervisenäitajatele ülevaadet, kas organismis on olulisemaid vitamiine ja mineraalaineid piisavalt."
|
"description": "Sobib, kui soovid lisaks peamistele tervisenäitajatele ülevaadet, kas organismis on olulisemaid vitamiine ja mineraalaineid piisavalt."
|
||||||
},
|
},
|
||||||
"nrOfAnalyses": "{{nr}} analyses"
|
"nrOfAnalyses": "{{nr}} analyses",
|
||||||
|
"clinicalBloodDraw": {
|
||||||
|
"label": "Kliiniline vereanalüüs",
|
||||||
|
"description": "Pending"
|
||||||
|
},
|
||||||
|
"crp": {
|
||||||
|
"label": "C-reaktiivne valk (CRP)",
|
||||||
|
"description": "Pending"
|
||||||
|
},
|
||||||
|
"ferritin": {
|
||||||
|
"label": "Ferritiin",
|
||||||
|
"description": "Pending"
|
||||||
|
},
|
||||||
|
"vitaminD": {
|
||||||
|
"label": "D-vitamiin",
|
||||||
|
"description": "Pending"
|
||||||
|
},
|
||||||
|
"glucose": {
|
||||||
|
"label": "Glükoos",
|
||||||
|
"description": "Pending"
|
||||||
|
},
|
||||||
|
"alat": {
|
||||||
|
"label": "Alaniini aminotransferaas",
|
||||||
|
"description": "Pending"
|
||||||
|
},
|
||||||
|
"ast": {
|
||||||
|
"label": "Aspartaadi aminotransferaas",
|
||||||
|
"description": "Pending"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -17,6 +17,7 @@
|
|||||||
"imageInputLabel": "Click here to upload an image",
|
"imageInputLabel": "Click here to upload an image",
|
||||||
"cancel": "Cancel",
|
"cancel": "Cancel",
|
||||||
"clear": "Clear",
|
"clear": "Clear",
|
||||||
|
"close": "Sulge",
|
||||||
"notFound": "Not Found",
|
"notFound": "Not Found",
|
||||||
"backToHomePage": "Back to Home Page",
|
"backToHomePage": "Back to Home Page",
|
||||||
"goBack": "Tagasi",
|
"goBack": "Tagasi",
|
||||||
@@ -59,6 +60,10 @@
|
|||||||
"shoppingCart": "Ostukorv",
|
"shoppingCart": "Ostukorv",
|
||||||
"search": "Otsi{{end}}",
|
"search": "Otsi{{end}}",
|
||||||
"myActions": "Minu toimingud",
|
"myActions": "Minu toimingud",
|
||||||
|
"healthPackageComparison": {
|
||||||
|
"label": "Tervisepakketide võrdlus",
|
||||||
|
"description": "Alljärgnevalt on antud eelinfo (sugu, vanus ja kehamassiindeksi) põhjal tehtud personalne terviseauditi valik. Tabelis on võimalik soovitatud terviseuuringute paketile lisada üksikuid uuringuid juurde."
|
||||||
|
},
|
||||||
"routes": {
|
"routes": {
|
||||||
"home": "Home",
|
"home": "Home",
|
||||||
"overview": "Ülevaade",
|
"overview": "Ülevaade",
|
||||||
|
|||||||
@@ -11,5 +11,33 @@
|
|||||||
"label": "Premium",
|
"label": "Premium",
|
||||||
"description": "Sobib, kui soovid lisaks peamistele tervisenäitajatele ülevaadet, kas organismis on olulisemaid vitamiine ja mineraalaineid piisavalt."
|
"description": "Sobib, kui soovid lisaks peamistele tervisenäitajatele ülevaadet, kas organismis on olulisemaid vitamiine ja mineraalaineid piisavalt."
|
||||||
},
|
},
|
||||||
"nrOfAnalyses": "{{nr}} analüüsi"
|
"nrOfAnalyses": "{{nr}} analüüsi",
|
||||||
|
"clinicalBloodDraw": {
|
||||||
|
"label": "Kliiniline vereanalüüs",
|
||||||
|
"description": "Pending"
|
||||||
|
},
|
||||||
|
"crp": {
|
||||||
|
"label": "C-reaktiivne valk (CRP)",
|
||||||
|
"description": "Pending"
|
||||||
|
},
|
||||||
|
"ferritin": {
|
||||||
|
"label": "Ferritiin",
|
||||||
|
"description": "Pending"
|
||||||
|
},
|
||||||
|
"vitaminD": {
|
||||||
|
"label": "D-vitamiin",
|
||||||
|
"description": "Pending"
|
||||||
|
},
|
||||||
|
"glucose": {
|
||||||
|
"label": "Glükoos",
|
||||||
|
"description": "Pending"
|
||||||
|
},
|
||||||
|
"alat": {
|
||||||
|
"label": "Alaniini aminotransferaas",
|
||||||
|
"description": "Pending"
|
||||||
|
},
|
||||||
|
"ast": {
|
||||||
|
"label": "Aspartaadi aminotransferaas",
|
||||||
|
"description": "Pending"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -17,6 +17,7 @@
|
|||||||
"imageInputLabel": "Click here to upload an image",
|
"imageInputLabel": "Click here to upload an image",
|
||||||
"cancel": "Cancel",
|
"cancel": "Cancel",
|
||||||
"clear": "Clear",
|
"clear": "Clear",
|
||||||
|
"close": "Close",
|
||||||
"notFound": "Not Found",
|
"notFound": "Not Found",
|
||||||
"backToHomePage": "Back to Home Page",
|
"backToHomePage": "Back to Home Page",
|
||||||
"goBack": "Go Back",
|
"goBack": "Go Back",
|
||||||
@@ -59,6 +60,10 @@
|
|||||||
"shoppingCart": "Shopping cart",
|
"shoppingCart": "Shopping cart",
|
||||||
"search": "Search{{end}}",
|
"search": "Search{{end}}",
|
||||||
"myActions": "My actions",
|
"myActions": "My actions",
|
||||||
|
"healthPackageComparison": {
|
||||||
|
"label": "Health package comparison",
|
||||||
|
"description": "Alljärgnevalt on antud eelinfo (sugu, vanus ja kehamassiindeksi) põhjal tehtud personalne terviseauditi valik. Tabelis on võimalik soovitatud terviseuuringute paketile lisada üksikuid uuringuid juurde."
|
||||||
|
},
|
||||||
"routes": {
|
"routes": {
|
||||||
"home": "Home",
|
"home": "Home",
|
||||||
"overview": "Overview",
|
"overview": "Overview",
|
||||||
|
|||||||
@@ -11,5 +11,33 @@
|
|||||||
"label": "Premium",
|
"label": "Premium",
|
||||||
"description": "Sobib, kui soovid lisaks peamistele tervisenäitajatele ülevaadet, kas organismis on olulisemaid vitamiine ja mineraalaineid piisavalt."
|
"description": "Sobib, kui soovid lisaks peamistele tervisenäitajatele ülevaadet, kas organismis on olulisemaid vitamiine ja mineraalaineid piisavalt."
|
||||||
},
|
},
|
||||||
"nrOfAnalyses": "{{nr}} analyses"
|
"nrOfAnalyses": "{{nr}} analyses",
|
||||||
|
"clinicalBloodDraw": {
|
||||||
|
"label": "Kliiniline vereanalüüs",
|
||||||
|
"description": "Pending"
|
||||||
|
},
|
||||||
|
"crp": {
|
||||||
|
"label": "C-reaktiivne valk (CRP)",
|
||||||
|
"description": "Pending"
|
||||||
|
},
|
||||||
|
"ferritin": {
|
||||||
|
"label": "Ferritiin",
|
||||||
|
"description": "Pending"
|
||||||
|
},
|
||||||
|
"vitaminD": {
|
||||||
|
"label": "D-vitamiin",
|
||||||
|
"description": "Pending"
|
||||||
|
},
|
||||||
|
"glucose": {
|
||||||
|
"label": "Glükoos",
|
||||||
|
"description": "Pending"
|
||||||
|
},
|
||||||
|
"alat": {
|
||||||
|
"label": "Alaniini aminotransferaas",
|
||||||
|
"description": "Pending"
|
||||||
|
},
|
||||||
|
"ast": {
|
||||||
|
"label": "Aspartaadi aminotransferaas",
|
||||||
|
"description": "Pending"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user