feat(dashboard, api): enhance dashboard card calculations and add team membership check

This commit is contained in:
Danel Kungla
2025-08-21 21:32:22 +03:00
parent 492327c5c7
commit b1b0846234
2 changed files with 100 additions and 73 deletions

View File

@@ -40,73 +40,80 @@ const cards = ({
age?: number;
height?: number | null;
weight?: number | 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-warning',
},
{
title: 'dashboard:bmi',
description: '27.5',
icon: <TrendingUp />,
iconBg: 'bg-warning',
},
{
title: 'dashboard:bloodPressure',
description: '160/98',
icon: <Activity />,
iconBg: 'bg-warning',
},
{
title: 'dashboard:cholesterol',
description: '5',
icon: <BlendingModeIcon className="size-4" />,
iconBg: 'bg-destructive',
},
{
title: 'dashboard:ldlCholesterol',
description: '3,6',
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 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 = [
{
@@ -162,8 +169,8 @@ export default function Dashboard({ account }: { account: AccountWithParams }) {
{cards({
gender: params?.gender,
age: params?.age,
height: account.account_params?.height,
weight: account.account_params?.weight,
height: account.account_params?.[0]?.height,
weight: account.account_params?.[0]?.weight,
}).map(
({
title,

View File

@@ -6,10 +6,12 @@ import { UserAnalysis } from '../types/accounts';
export type AccountWithParams =
Database['medreport']['Tables']['accounts']['Row'] & {
account_params: Pick<
Database['medreport']['Tables']['account_params']['Row'],
'weight' | 'height'
> | null;
account_params:
| Pick<
Database['medreport']['Tables']['account_params']['Row'],
'weight' | 'height'
>[]
| null;
};
/**
@@ -222,6 +224,24 @@ class AccountsApi {
),
}));
}
async hasAccountTeamMembership(accountId?: string) {
if (!accountId) {
return false;
}
const { count, error } = await this.client
.schema('medreport')
.from('accounts_memberships')
.select('account_id', { count: 'exact', head: true })
.eq('account_id', accountId);
if (error) {
throw error;
}
return (count ?? 0) > 0;
}
}
export function createAccountsApi(client: SupabaseClient<Database>) {