'use client';
import { useMemo, useState } from 'react';
import { ColumnDef } from '@tanstack/react-table';
import { Ellipsis } from 'lucide-react';
import { useTranslation } from 'react-i18next';
import { Database } from '@kit/supabase/database';
import { Badge } from '@kit/ui/badge';
import { Button } from '@kit/ui/button';
import { DataTable } from '@kit/ui/data-table';
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from '@kit/ui/dropdown-menu';
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 { RoleBadge } from '../members/role-badge';
import { DeleteInvitationDialog } from './delete-invitation-dialog';
import { RenewInvitationDialog } from './renew-invitation-dialog';
import { UpdateInvitationDialog } from './update-invitation-dialog';
type Invitations =
Database['public']['Functions']['get_account_invitations']['Returns'];
type AccountInvitationsTableProps = {
invitations: Invitations;
permissions: {
canUpdateInvitation: boolean;
canRemoveInvitation: boolean;
currentUserRoleHierarchy: number;
};
};
export function AccountInvitationsTable({
invitations,
permissions,
}: AccountInvitationsTableProps) {
const { t } = useTranslation('teams');
const [search, setSearch] = useState('');
const columns = useGetColumns(permissions);
const filteredInvitations = invitations.filter((member) => {
const searchString = search.toLowerCase();
const email = (
member.email.split('@')[0]?.toLowerCase() ?? ''
).toLowerCase();
return (
email.includes(searchString) ||
member.role.toLowerCase().includes(searchString)
);
});
return (
setSearch((e.target as HTMLInputElement).value)}
placeholder={t(`searchInvitations`)}
/>
);
}
function useGetColumns(permissions: {
canUpdateInvitation: boolean;
canRemoveInvitation: boolean;
currentUserRoleHierarchy: number;
}): ColumnDef[] {
const { t } = useTranslation('teams');
return useMemo(
() => [
{
header: t('emailLabel'),
size: 200,
cell: ({ row }) => {
const member = row.original;
const email = member.email;
return (
{email}
);
},
},
{
header: t('personalCode'),
cell: ({ row }) => {
const { personal_code } = row.original;
return personal_code;
},
},
{
header: t('roleLabel'),
cell: ({ row }) => {
const { role } = row.original;
return ;
},
},
{
header: t('invitedAtLabel'),
cell: ({ row }) => {
return new Date(row.original.created_at).toLocaleDateString();
},
},
{
header: t('expiresAtLabel'),
cell: ({ row }) => {
return new Date(row.original.expires_at).toLocaleDateString();
},
},
{
header: t('inviteStatus'),
cell: ({ row }) => {
const isExpired = getIsInviteExpired(row.original.expires_at);
if (isExpired) {
return {t('expired')};
}
return {t('active')};
},
},
{
header: '',
id: 'actions',
cell: ({ row }) => (
),
},
],
[permissions, t],
);
}
function ActionsDropdown({
permissions,
invitation,
}: {
permissions: AccountInvitationsTableProps['permissions'];
invitation: Invitations[0];
}) {
const [isDeletingInvite, setIsDeletingInvite] = useState(false);
const [isUpdatingRole, setIsUpdatingRole] = useState(false);
const [isRenewingInvite, setIsRenewingInvite] = useState(false);
if (!permissions.canUpdateInvitation && !permissions.canRemoveInvitation) {
return null;
}
return (
<>
setIsUpdatingRole(true)}
>
setIsRenewingInvite(true)}
>
setIsDeletingInvite(true)}
>
>
);
}
function getIsInviteExpired(isoExpiresAt: string) {
const currentIsoTime = new Date().toISOString();
const isoExpiresAtDate = new Date(isoExpiresAt);
const currentIsoTimeDate = new Date(currentIsoTime);
return isoExpiresAtDate < currentIsoTimeDate;
}