This commit is contained in:
giancarlo
2024-03-24 02:23:22 +08:00
parent 648d77b430
commit bce3479368
589 changed files with 37067 additions and 9596 deletions

View File

@@ -0,0 +1,139 @@
'use client';
import Link from 'next/link';
import { usePathname, useRouter } from 'next/navigation';
import type { ColumnDef } from '@tanstack/react-table';
import { EllipsisVerticalIcon } from 'lucide-react';
import type UserData from '@kit/session/types/user-data';
import { Button } from '@kit/ui/button';
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from '@kit/ui/dropdown-menu';
import type Membership from '@/lib/organizations/types/membership';
import { DataTable } from '@/components/app/DataTable';
import RoleBadge from '../../../../../(app)/[account]/account/organization/components/RoleBadge';
type Data = {
id: Membership['id'];
role: Membership['role'];
user: {
id: UserData['id'];
displayName: UserData['displayName'];
};
};
const columns: ColumnDef<Data>[] = [
{
header: 'Membership ID',
id: 'id',
accessorKey: 'id',
},
{
header: 'User ID',
id: 'user-id',
cell: ({ row }) => {
const userId = row.original.user.id;
return (
<Link className={'hover:underline'} href={`/admin/users/${userId}`}>
{userId}
</Link>
);
},
},
{
header: 'Name',
id: 'name',
accessorKey: 'user.displayName',
},
{
header: 'Role',
cell: ({ row }) => {
return (
<div className={'inline-flex'}>
<RoleBadge role={row.original.role} />
</div>
);
},
},
{
header: 'Actions',
cell: ({ row }) => {
const membership = row.original;
const userId = membership.user.id;
return (
<div className={'flex'}>
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button size={'icon'}>
<span className="sr-only">Open menu</span>
<EllipsisVerticalIcon className="h-4 w-4" />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
<DropdownMenuItem asChild>
<Link href={`/admin/users/${userId}`}>View User</Link>
</DropdownMenuItem>
<DropdownMenuItem asChild>
<Link href={`/admin/users/${userId}/impersonate`}>
Impersonate User
</Link>
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</div>
);
},
},
];
function OrganizationsMembersTable({
memberships,
page,
perPage,
pageCount,
}: React.PropsWithChildren<{
memberships: Data[];
page: number;
perPage: number;
pageCount: number;
}>) {
const data = memberships.filter((membership) => {
return membership.user;
});
const router = useRouter();
const path = usePathname();
return (
<DataTable
tableProps={{
'data-test': 'admin-organization-members-table',
}}
onPaginationChange={({ pageIndex }) => {
const { pathname } = new URL(path, window.location.origin);
const page = pageIndex + 1;
router.push(pathname + '?page=' + page);
}}
pageCount={pageCount}
pageIndex={page - 1}
pageSize={perPage}
columns={columns}
data={data}
/>
);
}
export default OrganizationsMembersTable;

View File

@@ -0,0 +1,82 @@
import { use } from 'react';
import Link from 'next/link';
import { ChevronRightIcon } from 'lucide-react';
import AdminHeader from '@packages/admin/components/AdminHeader';
import getSupabaseServerComponentClient from '@packages/supabase/server-component-client';
import appConfig from '@/config/app.config';
import { PageBody } from '@/components/app/Page';
import getPageFromQueryParams from '../../../utils/get-page-from-query-param';
import { getMembershipsByOrganizationUid } from '../../queries';
import OrganizationsMembersTable from './components/OrganizationsMembersTable';
interface AdminMembersPageParams {
params: {
uid: string;
};
searchParams: {
page?: string;
};
}
export const metadata = {
title: `Members | ${appConfig.name}`,
};
function AdminMembersPage(params: AdminMembersPageParams) {
const adminClient = getSupabaseServerComponentClient({ admin: true });
const uid = params.params.uid;
const perPage = 20;
const page = getPageFromQueryParams(params.searchParams.page);
const { data: memberships, count } = use(
getMembershipsByOrganizationUid(adminClient, { uid, page, perPage }),
);
const pageCount = count ? Math.ceil(count / perPage) : 0;
return (
<div className={'flex flex-1 flex-col'}>
<AdminHeader>Manage Members</AdminHeader>
<PageBody>
<div className={'flex flex-col space-y-4'}>
<Breadcrumbs />
<OrganizationsMembersTable
page={page}
perPage={perPage}
pageCount={pageCount}
memberships={memberships}
/>
</div>
</PageBody>
</div>
);
}
export default AdminMembersPage;
function Breadcrumbs() {
return (
<div className={'flex items-center space-x-2 p-2 text-xs'}>
<div className={'flex items-center space-x-1.5'}>
<Link href={'/admin'}>Admin</Link>
</div>
<ChevronRightIcon className={'w-3'} />
<Link href={'/admin/organizations'}>Organizations</Link>
<ChevronRightIcon className={'w-3'} />
<span>Members</span>
</div>
);
}