275 lines
7.3 KiB
TypeScript
275 lines
7.3 KiB
TypeScript
'use client';
|
|
|
|
import Link from 'next/link';
|
|
|
|
import { InfoTooltip } from '@/components/ui/info-tooltip';
|
|
import type { AccountWithParams } from '@/packages/features/accounts/src/server/api';
|
|
import { BlendingModeIcon, RulerHorizontalIcon } from '@radix-ui/react-icons';
|
|
import Isikukood from 'isikukood';
|
|
import {
|
|
Activity,
|
|
ChevronRight,
|
|
Clock9,
|
|
Droplets,
|
|
LineChart,
|
|
Pill,
|
|
Scale,
|
|
TrendingUp,
|
|
User,
|
|
} from 'lucide-react';
|
|
|
|
import { Button } from '@kit/ui/button';
|
|
import {
|
|
Card,
|
|
CardContent,
|
|
CardDescription,
|
|
CardFooter,
|
|
CardHeader,
|
|
CardProps,
|
|
} from '@kit/ui/card';
|
|
import { Trans } from '@kit/ui/trans';
|
|
import { cn } from '@kit/ui/utils';
|
|
|
|
const cards = ({
|
|
gender,
|
|
age,
|
|
height,
|
|
weight,
|
|
}: {
|
|
gender?: string;
|
|
age?: number;
|
|
height?: number | null;
|
|
weight?: number | null;
|
|
}) => {
|
|
const heightInMeters = height ? height / 100 : null;
|
|
const bmi =
|
|
heightInMeters && weight
|
|
? (weight / (heightInMeters * heightInMeters)).toFixed(1)
|
|
: null;
|
|
return [
|
|
{
|
|
title: 'dashboard:gender',
|
|
description: gender ?? 'dashboard:male',
|
|
icon: <User />,
|
|
iconBg: 'bg-success',
|
|
},
|
|
{
|
|
title: 'dashboard:age',
|
|
description: age ? `${age}` : '-',
|
|
icon: <Clock9 />,
|
|
iconBg: 'bg-success',
|
|
},
|
|
{
|
|
title: 'dashboard:height',
|
|
description: height ? `${height}cm` : '-',
|
|
icon: <RulerHorizontalIcon className="size-4" />,
|
|
iconBg: 'bg-success',
|
|
},
|
|
{
|
|
title: 'dashboard:weight',
|
|
description: weight ? `${weight}kg` : '-',
|
|
icon: <Scale />,
|
|
iconBg: 'bg-success',
|
|
},
|
|
{
|
|
title: 'dashboard:bmi',
|
|
description: bmi,
|
|
icon: <TrendingUp />,
|
|
iconBg: 'bg-success',
|
|
},
|
|
{
|
|
title: 'dashboard:bloodPressure',
|
|
description: '-',
|
|
icon: <Activity />,
|
|
iconBg: 'bg-warning',
|
|
},
|
|
{
|
|
title: 'dashboard:cholesterol',
|
|
description: '-',
|
|
icon: <BlendingModeIcon className="size-4" />,
|
|
iconBg: 'bg-destructive',
|
|
},
|
|
{
|
|
title: 'dashboard:ldlCholesterol',
|
|
description: '-',
|
|
icon: <Pill />,
|
|
iconBg: 'bg-warning',
|
|
},
|
|
// {
|
|
// title: 'Score 2',
|
|
// description: 'Normis',
|
|
// icon: <LineChart />,
|
|
// iconBg: 'bg-success',
|
|
// },
|
|
// {
|
|
// title: 'dashboard:smoking',
|
|
// description: 'dashboard:respondToQuestion',
|
|
// descriptionColor: 'text-primary',
|
|
// icon: (
|
|
// <Button size="icon" variant="outline" className="px-2 text-black">
|
|
// <ChevronRight className="size-4 stroke-2" />
|
|
// </Button>
|
|
// ),
|
|
// cardVariant: 'gradient-success' as CardProps['variant'],
|
|
// },
|
|
];
|
|
};
|
|
|
|
const dummyRecommendations = [
|
|
{
|
|
icon: <BlendingModeIcon className="size-4" />,
|
|
color: 'bg-cyan/10 text-cyan',
|
|
title: 'Kolesterooli kontroll',
|
|
description: 'HDL-kolestrool',
|
|
tooltipContent: 'Selgitus',
|
|
price: '20,00 €',
|
|
buttonText: 'Telli',
|
|
href: '/home/booking',
|
|
},
|
|
{
|
|
icon: <BlendingModeIcon className="size-4" />,
|
|
color: 'bg-primary/10 text-primary',
|
|
title: 'Kolesterooli kontroll',
|
|
tooltipContent: 'Selgitus',
|
|
description: 'LDL-Kolesterool',
|
|
buttonText: 'Broneeri',
|
|
href: '/home/booking',
|
|
},
|
|
{
|
|
icon: <Droplets />,
|
|
color: 'bg-destructive/10 text-destructive',
|
|
title: 'Vererõhu kontroll',
|
|
tooltipContent: 'Selgitus',
|
|
description: 'Score-Risk 2',
|
|
price: '20,00 €',
|
|
buttonText: 'Telli',
|
|
href: '/home/booking',
|
|
},
|
|
];
|
|
|
|
const getPersonParameters = (personalCode: string) => {
|
|
try {
|
|
const person = new Isikukood(personalCode);
|
|
return {
|
|
gender: person.getGender(),
|
|
age: person.getAge(),
|
|
};
|
|
} catch (error) {
|
|
console.error(error);
|
|
return null;
|
|
}
|
|
};
|
|
|
|
export default function Dashboard({ account }: { account: AccountWithParams }) {
|
|
const params = getPersonParameters(account.personal_code!);
|
|
|
|
return (
|
|
<>
|
|
<div className="grid auto-rows-fr grid-cols-2 gap-3 sm:grid-cols-4 lg:grid-cols-5">
|
|
{cards({
|
|
gender: params?.gender,
|
|
age: params?.age,
|
|
height: account.account_params?.[0]?.height,
|
|
weight: account.account_params?.[0]?.weight,
|
|
}).map(
|
|
({
|
|
title,
|
|
description,
|
|
icon,
|
|
iconBg,
|
|
cardVariant,
|
|
descriptionColor,
|
|
}) => (
|
|
<Card
|
|
key={title}
|
|
variant={cardVariant}
|
|
className="flex flex-col justify-between"
|
|
>
|
|
<CardHeader className="items-end-safe">
|
|
<div
|
|
className={cn(
|
|
'flex size-8 items-center-safe justify-center-safe rounded-full text-white',
|
|
iconBg,
|
|
)}
|
|
>
|
|
{icon}
|
|
</div>
|
|
</CardHeader>
|
|
<CardFooter className="flex flex-col items-start">
|
|
<h5>
|
|
<Trans i18nKey={title} />
|
|
</h5>
|
|
<CardDescription className={descriptionColor}>
|
|
<Trans i18nKey={description} />
|
|
</CardDescription>
|
|
</CardFooter>
|
|
</Card>
|
|
),
|
|
)}
|
|
</div>
|
|
<Card>
|
|
<CardHeader className="items-start">
|
|
<h4>
|
|
<Trans i18nKey="dashboard:recommendedForYou" />
|
|
</h4>
|
|
</CardHeader>
|
|
<CardContent className="space-y-6">
|
|
{dummyRecommendations.map(
|
|
(
|
|
{
|
|
icon,
|
|
color,
|
|
title,
|
|
description,
|
|
tooltipContent,
|
|
price,
|
|
buttonText,
|
|
href,
|
|
},
|
|
index,
|
|
) => {
|
|
return (
|
|
<div className="flex justify-between" key={index}>
|
|
<div className="mr-4 flex flex-row items-center gap-4">
|
|
<div
|
|
className={cn(
|
|
'flex size-8 items-center-safe justify-center-safe rounded-full text-white',
|
|
color,
|
|
)}
|
|
>
|
|
{icon}
|
|
</div>
|
|
<div>
|
|
<div className="inline-flex items-center gap-1 align-baseline text-sm font-medium">
|
|
{title}
|
|
<InfoTooltip content={tooltipContent} />
|
|
</div>
|
|
<p className="text-muted-foreground text-sm">
|
|
{description}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
<div className="grid w-36 auto-rows-fr grid-cols-2 items-center gap-4">
|
|
<p className="text-sm font-medium"> {price}</p>
|
|
{href ? (
|
|
<Link href={href}>
|
|
<Button size="sm" variant="secondary">
|
|
{buttonText}
|
|
</Button>
|
|
</Link>
|
|
) : (
|
|
<Button size="sm" variant="secondary">
|
|
{buttonText}
|
|
</Button>
|
|
)}
|
|
</div>
|
|
</div>
|
|
);
|
|
},
|
|
)}
|
|
</CardContent>
|
|
</Card>
|
|
</>
|
|
);
|
|
}
|