Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added functionality of blocking/deleting users #239

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions admin/src/components/ServerData.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,9 @@ export function ServerDataProvider(props: { children: ReactNode }) {
deleteUser(id: string) {
return sock.updateUserData({ user: { id }, deleted: true });
},
banUser(userId: string, isBanned: boolean) {
return sock.banUser({ userId, isBanned });
},
updateGroup(group: GroupDto) {
return sock.updateGroupData({ group, deleted: false });
},
Expand Down
81 changes: 81 additions & 0 deletions admin/src/components/Users.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,41 @@ const SAVE_SVG = (
</svg>
);

const DELETE_SVG = (
<svg
height="20"
viewBox="0 0 20 20"
width="20"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M5 5l10 10M5 15L15 5"
fill="none"
stroke="#f44336"
strokeWidth="2"
/>
</svg>
);

const BLOCK_SVG = (
<svg
height="20"
viewBox="0 0 20 20"
width="20"
xmlns="http://www.w3.org/2000/svg"
>
<circle
cx="10"
cy="10"
r="9"
stroke="#ff9800"
strokeWidth="2"
fill="none"
/>
<line x1="5" y1="5" x2="15" y2="15" stroke="#ff9800" strokeWidth="2" />
</svg>
);

const styles = {
select: { margin: "0 20px" },
buttonsCellContainer: {
Expand All @@ -58,6 +93,7 @@ const styles = {
display: "flex",
justifyContent: "flex-end",
alignItems: "center",
gap: "3px",
},
editButton: {
background: "#f3f3f3",
Expand Down Expand Up @@ -106,6 +142,7 @@ function toForm(user: any) {
id: user.id,
groupId: user.groupId,
email: user.email,
isBanned: user.isBanned,
};
}

Expand Down Expand Up @@ -163,6 +200,50 @@ function getColumns(setRowsData: any, serverData: any) {
>
{EDIT_SVG}
</button>
<button
title="Block/Unblock"
style={styles.cancelButton}
onClick={async (e) => {
e.stopPropagation();

// Toggle isBanned status
const newStatus = !data.isBanned;
await serverData.banUser(data.id, newStatus);
data.isBanned = newStatus;

setRowsData((prevRows: any[]) =>
prevRows.map((row) =>
row.id === data.id ? { ...row, isBanned: newStatus } : row
)
);
alert(
`User ${data.username} has been ${
newStatus ? "blocked" : "unblocked"
}.`
);
}}
>
{BLOCK_SVG}
</button>
<button
title="Delete"
style={styles.cancelButton}
onClick={(e) => {
e.stopPropagation();

if (
window.confirm("Are you sure you want to delete this user?")
) {
setRowsData((prevRows: any[]) =>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Amazing job implementing the blocking feature! One thing I would consider is using a map for the row data (such as prevRows) instead of an array to optimize updates for larger datasets. This could allow for constant-time lookups and updates.

prevRows.filter((row) => row.id !== data.id)
);
serverData.users.delete(data.id);
serverData.deleteUser(data.id);
}
}}
>
{DELETE_SVG}
</button>
</div>
),
editorCellRenderer: ({
Expand Down
12 changes: 12 additions & 0 deletions server/src/user/user.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,10 @@ export class UserService {
return await this.prisma.user.findMany();
}

/**
* Delete a user based on their user id.
* @param user the user who will be deleted.
*/
async deleteUser(ability: AppAbility, user: User) {
if (
(await this.prisma.user.count({
Expand All @@ -157,6 +161,7 @@ export class UserService {
await this.prisma.$transaction(async tx => {
await this.groupsService.fixOrDeleteGroup({ id: user.groupId }, tx);
});
console.log(`User ${user.id} deleted!`);
}

/**
Expand Down Expand Up @@ -219,6 +224,13 @@ export class UserService {
});
}

/**
* Check if a user exists based on their authentication type and id.
* @param authType the authentication type of the user.
* @param id the id of the user.
* @returns A promise containing the user if they exist.
* Otherwise, it returns null.
*/
async checkIfUserExists(
authType: AuthType,
id: string,
Expand Down
Loading