Skip to content

Commit 99d865b

Browse files
committed
feat(Admin): enhance user management with improved mutation handling and UI updates
1 parent 390abc4 commit 99d865b

File tree

1 file changed

+100
-34
lines changed
  • app/[locale]/dashboard/[entityType]/[entitySlug]/admin

1 file changed

+100
-34
lines changed

app/[locale]/dashboard/[entityType]/[entitySlug]/admin/page.tsx

Lines changed: 100 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,21 @@
11
'use client';
22

3-
import React, { useState } from 'react';
3+
import React, { useEffect, useState } from 'react';
44
import { useParams } from 'next/navigation';
55
import { graphql } from '@/gql';
6-
import { useQuery } from '@tanstack/react-query';
7-
import { Button, DataTable, SearchInput, Text } from 'opub-ui';
6+
import { AddRemoveUserToOrganizationInput } from '@/gql/generated/graphql';
7+
import { useMutation, useQuery } from '@tanstack/react-query';
8+
import { Button, DataTable, Icon, SearchInput, Text, toast } from 'opub-ui';
89

910
import { GraphQL } from '@/lib/api';
1011
import { formatDate } from '@/lib/utils';
12+
import { Icons } from '@/components/icons';
1113
import { Loading } from '@/components/loading';
1214
import AddUser from './addUser';
1315

1416
const usersListDoc: any = graphql(`
15-
query userByOrganization {
16-
users {
17+
query userByOrg {
18+
userByOrganization {
1719
id
1820
fullName
1921
organizationMemberships {
@@ -28,15 +30,49 @@ const usersListDoc: any = graphql(`
2830
}
2931
`);
3032

33+
const removeUserDoc: any = graphql(`
34+
mutation removeUserFromOrganization(
35+
$input: AddRemoveUserToOrganizationInput!
36+
) {
37+
removeUserFromOrganization(input: $input) {
38+
success
39+
message
40+
}
41+
}
42+
`);
43+
3144
const Admin = () => {
32-
const params = useParams();
45+
const params = useParams<{ entityType: string; entitySlug: string }>();
3346
const usersList: { data: any; isLoading: boolean; refetch: any } = useQuery(
3447
[`fetch_users_list_admin_members`],
35-
() => GraphQL(usersListDoc, {}, [])
48+
() => GraphQL(usersListDoc, {
49+
[params.entityType]: params.entitySlug,
50+
}, [])
3651
);
3752
const [isOpen, setIsOpen] = useState(false);
3853
const [isEdit, setIsEdit] = useState(false);
3954
const [selectedUser, setSelectedUser] = useState({});
55+
const [refetch,setRefetch]=useState(false)
56+
57+
const { mutate, isLoading: removeUserLoading } = useMutation(
58+
(input: { input: AddRemoveUserToOrganizationInput }) =>
59+
GraphQL(
60+
removeUserDoc,
61+
{
62+
[params.entityType]: params.entitySlug,
63+
},
64+
input
65+
),
66+
{
67+
onSuccess: (res: any) => {
68+
toast('User removed successfully');
69+
usersList.refetch();
70+
},
71+
onError: (err: any) => {
72+
toast('Failed to remove user');
73+
},
74+
}
75+
);
4076

4177
const table = {
4278
columns: [
@@ -45,43 +81,66 @@ const Admin = () => {
4581
header: 'Name',
4682
},
4783
{ accessorKey: 'role', header: 'Role' },
48-
{ accessorKey: 'created', header: 'Date Created' },
4984
{ accessorKey: 'modified', header: 'Date Modified' },
5085
{
5186
accessorKey: 'edit',
5287
header: 'Edit',
5388
cell: ({ row }: any) => (
54-
<Button
55-
onClick={() => {
56-
setSelectedUser({
57-
id: row.original.id,
58-
name: row.original.name,
59-
role: {
60-
id: row.original.roleId,
61-
name: row.original.role,
62-
},
63-
});
64-
setIsOpen(true);
65-
setIsEdit(true)
66-
}}
67-
>
68-
Edit
69-
</Button>
89+
<div className="">
90+
<Button
91+
onClick={() => {
92+
setSelectedUser({
93+
id: row.original.id,
94+
name: row.original.name,
95+
role: {
96+
id: row.original.roleId,
97+
name: row.original.role,
98+
},
99+
});
100+
setIsOpen(true);
101+
setIsEdit(true);
102+
}}
103+
kind="tertiary"
104+
>
105+
<Icon source={Icons.pencil} size={24} color="warning" />
106+
</Button>
107+
</div>
108+
),
109+
},
110+
{
111+
accessorKey: 'delete',
112+
header: 'Delete',
113+
cell: ({ row }: any) => (
114+
<div className="">
115+
<Button
116+
onClick={() => {
117+
mutate({
118+
input: {
119+
userId: row.original.id,
120+
roleId: row.original.roleId,
121+
},
122+
});
123+
}}
124+
kind="tertiary"
125+
>
126+
<Icon source={Icons.delete} size={24} color="warning" />
127+
</Button>
128+
</div>
70129
),
71130
},
72131
],
132+
73133
rows:
74-
usersList.data?.users.map((item: any) => ({
134+
usersList.data?.userByOrganization.map((item: any) => ({
75135
name: item.fullName,
76136
role: item.organizationMemberships[0]?.role?.name || 'N/A',
77137
roleId: item.organizationMemberships[0]?.role?.id || '',
78-
created:
79-
formatDate(item.organizationMemberships[0]?.createdAt) || 'N/A',
80138
modified:
81139
formatDate(item.organizationMemberships[0]?.updatedAt) || 'N/A',
82140
id: item.id,
83141
})) || [],
84142
};
143+
85144

86145
const [filteredRows, setFilteredRows] = React.useState<any[]>(table.rows);
87146
const handleSearchChange = (e: string) => {
@@ -92,10 +151,18 @@ const Admin = () => {
92151
setFilteredRows(filtered);
93152
};
94153

154+
useEffect(() => {
155+
usersList.refetch();
156+
setRefetch(false);
157+
}, [refetch]);
158+
95159
return (
96160
<div>
97-
<div className="my-4 lg:my-8 flex flex-wrap items-center justify-between gap-4 lg:gap-6 px-4 lg:flex-nowrap">
98-
<Text>Showing {usersList.data?.users?.length || 0} of {usersList.data?.users?.length || 0} People</Text>
161+
<div className="my-4 flex flex-wrap items-center justify-between gap-4 px-4 lg:my-8 lg:flex-nowrap lg:gap-6">
162+
<Text>
163+
Showing {usersList.data?.userByOrganization?.length || 0} of{' '}
164+
{usersList.data?.userByOrganization?.length || 0} People
165+
</Text>
99166
<SearchInput
100167
className="w-full lg:w-1/2 "
101168
placeholder="Search for a person"
@@ -114,7 +181,7 @@ const Admin = () => {
114181
name: '',
115182
},
116183
});
117-
setIsEdit(false)
184+
setIsEdit(false);
118185
setIsOpen(true);
119186
}}
120187
>
@@ -125,23 +192,22 @@ const Admin = () => {
125192
<AddUser
126193
setIsOpen={setIsOpen}
127194
selectedUser={selectedUser}
128-
title="Add User"
129195
isOpen={isOpen}
130-
refetchUsers={usersList.refetch()}
131196
isEdit={isEdit}
197+
setRefetch={setRefetch}
132198
/>
133199
)}
134200
</div>
135201
<div>
136-
{usersList.data?.users?.length > 0 ? (
202+
{usersList.data?.userByOrganization?.length > 0 ? (
137203
<DataTable
138204
columns={table.columns}
139205
rows={table.rows}
140206
hideSelection
141207
hideViewSelector
142208
/>
143209
) : (
144-
<Loading />
210+
<Loading/>
145211
)}
146212
</div>
147213
</div>

0 commit comments

Comments
 (0)