Files
loyaly-merchant/src/features/team/components/TeamTable.tsx

84 lines
2.3 KiB
TypeScript

'use client';
import {proportional} from '@astryxdesign/core/Table';
import type {TableColumn} from '@astryxdesign/core/Table';
import {VStack, HStack} from '@astryxdesign/core/Layout';
import {Text} from '@astryxdesign/core/Text';
import {Avatar} from '@astryxdesign/core/Avatar';
import {Badge} from '@astryxdesign/core/Badge';
import {PanelCard} from '@/shared/components/patterns/PanelCard';
import {ResponsiveTable} from '@/shared/components/patterns/ResponsiveTable';
import {SkeletonRows} from '@/shared/components/patterns/LoadingState';
import {EmptyPanel} from '@/shared/components/patterns/EmptyPanel';
import type {TeamMember} from '@/features/team/types/team';
import type {Resource} from '@/shared/hooks/useResource';
interface Row extends Record<string, unknown> {
id: string;
name: string;
email: string;
role: string;
}
const COLUMNS: TableColumn<Row>[] = [
{
key: 'name',
header: 'Person',
width: proportional(1),
renderCell: (row) => (
<HStack gap={2} vAlign="center">
<Avatar name={row.name} size="sm" tooltip={false} />
<VStack gap={0}>
<Text size="sm" weight="medium">
{row.name}
</Text>
<Text size="xsm" color="secondary">
{row.email}
</Text>
</VStack>
</HStack>
),
},
{
key: 'role',
header: 'Role',
align: 'end',
// Role IS an enumerated state, which is what a Badge is for — unlike a
// status, which is a dot.
renderCell: (row) => <Badge variant="neutral" label={row.role} />,
},
];
export function TeamTable({resource}: {resource: Resource<TeamMember[]>}) {
return (
<PanelCard
title="Team"
subtitle="Who can sign in to this console, and at what privilege"
resource={resource}
loading={<SkeletonRows count={5} height={44} />}
empty={
<EmptyPanel
icon="staff"
title="No team members"
description="People appear here once they accept an invitation."
/>
}
>
{(members) => (
<ResponsiveTable
data={members.map((m) => ({
id: m.id,
name: m.name,
email: m.email,
role: m.role,
}))}
columns={COLUMNS}
idKey="id"
primaryKey="name"
density="balanced"
/>
)}
</PanelCard>
);
}