feat(MED-97): show benefits amount for each member

This commit is contained in:
2025-09-26 15:39:33 +03:00
parent 428cbd9477
commit eb6ef2abe1
6 changed files with 63 additions and 7 deletions

View File

@@ -5,6 +5,7 @@ import { SupabaseClient } from '@supabase/supabase-js';
import { Database } from '@/packages/supabase/src/database.types';
import { loadTeamWorkspace } from '~/home/[account]/_lib/server/team-account-workspace.loader';
import { getSupabaseServerAdminClient } from '@/packages/supabase/src/clients/server-admin-client';
/**
* Load data for the members page
@@ -15,11 +16,13 @@ export async function loadMembersPageData(
client: SupabaseClient<Database>,
slug: string,
) {
const workspace = await loadTeamWorkspace(slug);
return Promise.all([
loadAccountMembers(client, slug),
loadInvitations(client, slug),
canAddMember,
loadTeamWorkspace(slug),
workspace,
loadAccountMembersBenefitsUsage(getSupabaseServerAdminClient(), workspace.account.id),
]);
}
@@ -60,6 +63,27 @@ async function loadAccountMembers(
return data ?? [];
}
export async function loadAccountMembersBenefitsUsage(
client: SupabaseClient<Database>,
accountId: string,
): Promise<{
personal_account_id: string;
benefit_amount: number;
}[]> {
const { data, error } = await client
.schema('medreport')
.rpc('get_benefits_usages_for_company_members', {
p_account_id: accountId,
});
if (error) {
console.error('Failed to load account members benefits usage', error);
return [];
}
return data ?? [];
}
/**
* Load account invitations
* @param client

View File

@@ -42,7 +42,7 @@ async function TeamAccountMembersPage({ params }: TeamAccountMembersPageProps) {
const client = getSupabaseServerClient();
const slug = (await params).account;
const [members, invitations, canAddMember, { user, account }] =
const [members, invitations, canAddMember, { user, account }, membersBenefitsUsage] =
await loadMembersPageData(client, slug);
const canManageRoles = account.permissions.includes('roles.manage');
@@ -96,6 +96,7 @@ async function TeamAccountMembersPage({ params }: TeamAccountMembersPageProps) {
members={members}
isPrimaryOwner={isPrimaryOwner}
canManageRoles={canManageRoles}
membersBenefitsUsage={membersBenefitsUsage}
/>
</CardContent>
</Card>

View File

@@ -20,6 +20,7 @@ import { If } from '@kit/ui/if';
import { Input } from '@kit/ui/input';
import { ProfileAvatar } from '@kit/ui/profile-avatar';
import { Trans } from '@kit/ui/trans';
import { formatCurrency } from '@kit/shared/utils';
import { RemoveMemberDialog } from './remove-member-dialog';
import { RoleBadge } from './role-badge';
@@ -42,6 +43,10 @@ type AccountMembersTableProps = {
userRoleHierarchy: number;
isPrimaryOwner: boolean;
canManageRoles: boolean;
membersBenefitsUsage: {
personal_account_id: string;
benefit_amount: number;
}[];
};
export function AccountMembersTable({
@@ -51,6 +56,7 @@ export function AccountMembersTable({
isPrimaryOwner,
userRoleHierarchy,
canManageRoles,
membersBenefitsUsage,
}: AccountMembersTableProps) {
const [search, setSearch] = useState('');
const { t } = useTranslation('teams');
@@ -73,6 +79,7 @@ export function AccountMembersTable({
currentUserId,
currentAccountId,
currentRoleHierarchy: userRoleHierarchy,
membersBenefitsUsage,
});
const filteredMembers = members
@@ -122,9 +129,13 @@ function useGetColumns(
currentUserId: string;
currentAccountId: string;
currentRoleHierarchy: number;
membersBenefitsUsage: {
personal_account_id: string;
benefit_amount: number;
}[];
},
): ColumnDef<Members[0]>[] {
const { t } = useTranslation('teams');
const { t, i18n: { language } } = useTranslation('teams');
return useMemo(
() => [
@@ -168,6 +179,23 @@ function useGetColumns(
return row.original.personal_code ?? '-';
},
},
{
header: t('distributedBenefitsAmount'),
cell: ({ row }) => {
const benefitAmount = params.membersBenefitsUsage.find(
(usage) => usage.personal_account_id === row.original.id
)?.benefit_amount;
if (typeof benefitAmount !== 'number') {
return '-';
}
return formatCurrency({
currencyCode: 'EUR',
locale: language,
value: benefitAmount,
});
},
},
{
header: t('roleLabel'),
cell: ({ row }) => {
@@ -175,7 +203,7 @@ function useGetColumns(
const isPrimaryOwner = primary_owner_user_id === user_id;
return (
<span className={'flex items-center space-x-1'}>
<span className={'flex items-center space-x-1 flex-wrap space-y-1 sm:space-y-0 sm:flex-nowrap'}>
<RoleBadge role={role} />
<If condition={isPrimaryOwner}>

View File

@@ -160,5 +160,6 @@
"leaveTeamInputDescription": "By leaving the company, you will no longer have access to it.",
"reservedNameError": "This name is reserved. Please choose a different one.",
"specialCharactersError": "This name cannot contain special characters. Please choose a different one.",
"personalCode": "Personal Code"
"personalCode": "Personal Code",
"distributedBenefitsAmount": "Assigned benefits"
}

View File

@@ -193,5 +193,6 @@
"reservedNameError": "See nimi on reserveeritud. Palun vali mõni teine.",
"specialCharactersError": "Nimi ei tohi sisaldada erimärke. Palun vali mõni teine.",
"personalCode": "Isikukood",
"teamOwnerPersonalCodeLabel": "Omaniku isikukood"
"teamOwnerPersonalCodeLabel": "Omaniku isikukood",
"distributedBenefitsAmount": "Väljastatud toetus"
}

View File

@@ -193,5 +193,6 @@
"reservedNameError": "Это имя зарезервировано. Пожалуйста, выберите другое.",
"specialCharactersError": "Это имя не может содержать специальные символы. Пожалуйста, выберите другое.",
"personalCode": "Идентификационный код",
"teamOwnerPersonalCodeLabel": "Идентификационный код владельца"
"teamOwnerPersonalCodeLabel": "Идентификационный код владельца",
"distributedBenefitsAmount": "Распределенные выплаты"
}