MED-151: add profile view and working smoking dashboard card (#71)
* MED-151: add profile view and working smoking dashboard card * update zod * move some components to shared * move some components to shared * remove console.logs * remove unused password form components * only check null for variant * use pathsconfig
This commit is contained in:
@@ -7,6 +7,7 @@ import { Database } from '@/packages/supabase/src/database.types';
|
||||
import { BlendingModeIcon, RulerHorizontalIcon } from '@radix-ui/react-icons';
|
||||
import {
|
||||
Activity,
|
||||
ChevronRight,
|
||||
Clock9,
|
||||
Droplets,
|
||||
Pill,
|
||||
@@ -16,6 +17,7 @@ import {
|
||||
} from 'lucide-react';
|
||||
|
||||
import { InfoTooltip } from '@kit/shared/components/ui/info-tooltip';
|
||||
import { pathsConfig } from '@kit/shared/config';
|
||||
import { getPersonParameters } from '@kit/shared/utils';
|
||||
import { Button } from '@kit/ui/button';
|
||||
import {
|
||||
@@ -24,10 +26,12 @@ import {
|
||||
CardDescription,
|
||||
CardFooter,
|
||||
CardHeader,
|
||||
CardProps,
|
||||
} from '@kit/ui/card';
|
||||
import { Trans } from '@kit/ui/trans';
|
||||
import { cn } from '@kit/ui/utils';
|
||||
|
||||
import { isNil } from 'lodash';
|
||||
import { BmiCategory } from '~/lib/types/bmi';
|
||||
import {
|
||||
bmiFromMetric,
|
||||
@@ -35,85 +39,101 @@ import {
|
||||
getBmiStatus,
|
||||
} from '~/lib/utils';
|
||||
|
||||
const getCardVariant = (isSuccess: boolean | null): CardProps['variant'] => {
|
||||
if (isSuccess === null) return 'default';
|
||||
if (isSuccess) return 'gradient-success';
|
||||
return 'gradient-destructive';
|
||||
};
|
||||
|
||||
const cards = ({
|
||||
gender,
|
||||
age,
|
||||
height,
|
||||
weight,
|
||||
bmiStatus,
|
||||
smoking,
|
||||
}: {
|
||||
gender?: string;
|
||||
age?: number;
|
||||
height?: number | null;
|
||||
weight?: number | null;
|
||||
bmiStatus: BmiCategory | null;
|
||||
smoking?: boolean | null;
|
||||
}) => [
|
||||
{
|
||||
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: bmiFromMetric(weight || 0, height || 0).toString(),
|
||||
icon: <TrendingUp />,
|
||||
iconBg: getBmiBackgroundColor(bmiStatus),
|
||||
},
|
||||
{
|
||||
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'],
|
||||
// },
|
||||
];
|
||||
{
|
||||
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: bmiFromMetric(weight || 0, height || 0).toString(),
|
||||
icon: <TrendingUp />,
|
||||
iconBg: getBmiBackgroundColor(bmiStatus),
|
||||
},
|
||||
{
|
||||
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:
|
||||
isNil(smoking)
|
||||
? 'dashboard:respondToQuestion'
|
||||
: !!smoking
|
||||
? 'common:yes'
|
||||
: 'common:no',
|
||||
descriptionColor: 'text-primary',
|
||||
icon:
|
||||
isNil(smoking) ? (
|
||||
<Link href={pathsConfig.app.personalAccountSettings}>
|
||||
<Button size="icon" variant="outline" className="px-2 text-black">
|
||||
<ChevronRight className="size-4 stroke-2" />
|
||||
</Button>
|
||||
</Link>
|
||||
) : null,
|
||||
cardVariant: getCardVariant(isNil(smoking) ? null : !smoking),
|
||||
},
|
||||
];
|
||||
|
||||
const dummyRecommendations = [
|
||||
{
|
||||
@@ -160,8 +180,8 @@ export default function Dashboard({
|
||||
const params = getPersonParameters(account.personal_code!);
|
||||
const bmiStatus = getBmiStatus(bmiThresholds, {
|
||||
age: params?.age || 0,
|
||||
height: account.account_params?.[0]?.height || 0,
|
||||
weight: account.account_params?.[0]?.weight || 0,
|
||||
height: account.accountParams?.height || 0,
|
||||
weight: account.accountParams?.weight || 0,
|
||||
});
|
||||
|
||||
return (
|
||||
@@ -170,21 +190,22 @@ export default function Dashboard({
|
||||
{cards({
|
||||
gender: params?.gender,
|
||||
age: params?.age,
|
||||
height: account.account_params?.[0]?.height,
|
||||
weight: account.account_params?.[0]?.weight,
|
||||
height: account.accountParams?.height,
|
||||
weight: account.accountParams?.weight,
|
||||
bmiStatus,
|
||||
smoking: account.accountParams?.isSmoker,
|
||||
}).map(
|
||||
({
|
||||
title,
|
||||
description,
|
||||
icon,
|
||||
iconBg,
|
||||
// cardVariant,
|
||||
cardVariant,
|
||||
// descriptionColor,
|
||||
}) => (
|
||||
<Card
|
||||
key={title}
|
||||
// variant={cardVariant}
|
||||
variant={cardVariant}
|
||||
className="flex flex-col justify-between"
|
||||
>
|
||||
<CardHeader className="items-end-safe">
|
||||
@@ -256,7 +277,7 @@ export default function Dashboard({
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="grid w-36 auto-rows-fr grid-cols-2 items-center gap-4 min-w-fit">
|
||||
<div className="grid w-36 min-w-fit auto-rows-fr grid-cols-2 items-center gap-4">
|
||||
<p className="text-sm font-medium"> {price}</p>
|
||||
{href ? (
|
||||
<Link href={href}>
|
||||
|
||||
@@ -60,7 +60,7 @@ export async function HomeMenuNavigation(props: {
|
||||
<span className="flex items-center text-nowrap">{totalValue}</span>
|
||||
</Button>
|
||||
)}
|
||||
<Link href="/home/cart">
|
||||
<Link href={pathsConfig.app.cart}>
|
||||
<Button
|
||||
variant="ghost"
|
||||
className="relative mr-0 h-10 cursor-pointer border-1 px-4 py-2"
|
||||
|
||||
@@ -4,11 +4,13 @@ import { useMemo } from 'react';
|
||||
|
||||
import Link from 'next/link';
|
||||
|
||||
import SignOutDropdownItem from '@kit/shared/components/sign-out-dropdown-item';
|
||||
import { StoreCart } from '@medusajs/types';
|
||||
import { Cross, LogOut, Menu, Shield, ShoppingCart } from 'lucide-react';
|
||||
import { Cross, Menu, Shield, ShoppingCart } from 'lucide-react';
|
||||
|
||||
import { usePersonalAccountData } from '@kit/accounts/hooks/use-personal-account-data';
|
||||
import { ApplicationRoleEnum } from '@kit/accounts/types/accounts';
|
||||
import DropdownLink from '@kit/shared/components/ui/dropdown-link';
|
||||
import {
|
||||
pathsConfig,
|
||||
personalAccountNavigationConfig,
|
||||
@@ -91,7 +93,7 @@ export function HomeMobileNavigation(props: {
|
||||
<If condition={props.cart && hasCartItems}>
|
||||
<DropdownMenuGroup>
|
||||
<DropdownLink
|
||||
path="/home/cart"
|
||||
path={pathsConfig.app.cart}
|
||||
label="common:shoppingCartCount"
|
||||
Icon={<ShoppingCart className="stroke-[1.5px]" />}
|
||||
labelOptions={{ count: cartQuantityTotal }}
|
||||
@@ -145,49 +147,4 @@ export function HomeMobileNavigation(props: {
|
||||
);
|
||||
}
|
||||
|
||||
function DropdownLink(
|
||||
props: React.PropsWithChildren<{
|
||||
path: string;
|
||||
label: string;
|
||||
labelOptions?: Record<string, any>;
|
||||
Icon: React.ReactNode;
|
||||
}>,
|
||||
) {
|
||||
return (
|
||||
<DropdownMenuItem asChild key={props.path}>
|
||||
<Link
|
||||
href={props.path}
|
||||
className={'flex h-12 w-full items-center space-x-4'}
|
||||
>
|
||||
{props.Icon}
|
||||
|
||||
<span>
|
||||
<Trans
|
||||
i18nKey={props.label}
|
||||
defaults={props.label}
|
||||
values={props.labelOptions}
|
||||
/>
|
||||
</span>
|
||||
</Link>
|
||||
</DropdownMenuItem>
|
||||
);
|
||||
}
|
||||
|
||||
function SignOutDropdownItem(
|
||||
props: React.PropsWithChildren<{
|
||||
onSignOut: () => unknown;
|
||||
}>,
|
||||
) {
|
||||
return (
|
||||
<DropdownMenuItem
|
||||
className={'flex h-12 w-full items-center space-x-4'}
|
||||
onClick={props.onSignOut}
|
||||
>
|
||||
<LogOut className={'h-6'} />
|
||||
|
||||
<span>
|
||||
<Trans i18nKey={'common:signOut'} defaults={'Sign out'} />
|
||||
</span>
|
||||
</DropdownMenuItem>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user