Remove user from organization

Signed-off-by: gearnode <bryan@frimin.fr>
This commit is contained in:
gearnode
2025-03-14 11:17:07 +01:00
parent c2a93f6871
commit 7153831fb2
7 changed files with 498 additions and 2 deletions

View File

@@ -38,6 +38,7 @@ import {
import type { SettingsPageQuery as SettingsPageQueryType } from "./__generated__/SettingsPageQuery.graphql";
import type { SettingsPageUpdateOrganizationMutation as SettingsPageUpdateOrganizationMutationType } from "./__generated__/SettingsPageUpdateOrganizationMutation.graphql";
import type { SettingsPageInviteUserMutation as SettingsPageInviteUserMutationType } from "./__generated__/SettingsPageInviteUserMutation.graphql";
import type { SettingsPageRemoveUserMutation as SettingsPageRemoveUserMutationType } from "./__generated__/SettingsPageRemoveUserMutation.graphql";
const settingsPageQuery = graphql`
query SettingsPageQuery($organizationID: ID!) {
@@ -83,6 +84,14 @@ const inviteUserMutation = graphql`
}
`;
const removeUserMutation = graphql`
mutation SettingsPageRemoveUserMutation($input: RemoveUserInput!) {
removeUser(input: $input) {
success
}
}
`;
function SettingsPageContent({
queryRef,
}: {
@@ -103,6 +112,7 @@ function SettingsPageContent({
organization.name || ""
);
const [isUploading, setIsUploading] = useState(false);
const [isRemoving, setIsRemoving] = useState(false);
const [updateOrganization] =
useMutation<SettingsPageUpdateOrganizationMutationType>(
@@ -112,6 +122,13 @@ function SettingsPageContent({
const [inviteUser] =
useMutation<SettingsPageInviteUserMutationType>(inviteUserMutation);
const [removeUser] =
useMutation<SettingsPageRemoveUserMutationType>(removeUserMutation);
const { organizationId } = useParams();
const [, loadQuery] =
useQueryLoader<SettingsPageQueryType>(settingsPageQuery);
const handleUpdateName = () => {
updateOrganization({
variables: {
@@ -232,6 +249,45 @@ function SettingsPageContent({
});
};
const handleRemoveUser = (userId: string) => {
setIsRemoving(true);
removeUser({
variables: {
input: {
organizationId: organization.id,
userId: userId,
},
},
onCompleted: (response) => {
setIsRemoving(false);
if (response.removeUser?.success) {
toast({
title: "User removed",
description: "The user has been removed from the organization.",
variant: "default",
});
// Refresh the query to update the UI
loadQuery({ organizationID: organizationId! });
} else {
toast({
title: "Error removing user",
description: "The user could not be removed. Please try again.",
variant: "destructive",
});
}
},
onError: (error) => {
setIsRemoving(false);
toast({
title: "Error removing user",
description: error.message,
variant: "destructive",
});
},
});
};
return (
<>
<div className="container mx-auto p-6 space-y-6">
@@ -377,8 +433,12 @@ function SettingsPageContent({
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
<DropdownMenuItem className="text-red-600">
Remove member
<DropdownMenuItem
className="text-red-600"
onClick={() => handleRemoveUser(user.id)}
disabled={isRemoving}
>
{isRemoving ? "Removing..." : "Remove member"}
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>

View File

@@ -0,0 +1,93 @@
/**
* @generated SignedSource<<9d909d5fc7076593317b01aab165513d>>
* @lightSyntaxTransform
* @nogrep
*/
/* tslint:disable */
/* eslint-disable */
// @ts-nocheck
import { ConcreteRequest } from 'relay-runtime';
export type RemoveUserInput = {
organizationId: string;
userId: string;
};
export type SettingsPageRemoveUserMutation$variables = {
input: RemoveUserInput;
};
export type SettingsPageRemoveUserMutation$data = {
readonly removeUser: {
readonly success: boolean;
};
};
export type SettingsPageRemoveUserMutation = {
response: SettingsPageRemoveUserMutation$data;
variables: SettingsPageRemoveUserMutation$variables;
};
const node: ConcreteRequest = (function(){
var v0 = [
{
"defaultValue": null,
"kind": "LocalArgument",
"name": "input"
}
],
v1 = [
{
"alias": null,
"args": [
{
"kind": "Variable",
"name": "input",
"variableName": "input"
}
],
"concreteType": "RemoveUserPayload",
"kind": "LinkedField",
"name": "removeUser",
"plural": false,
"selections": [
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "success",
"storageKey": null
}
],
"storageKey": null
}
];
return {
"fragment": {
"argumentDefinitions": (v0/*: any*/),
"kind": "Fragment",
"metadata": null,
"name": "SettingsPageRemoveUserMutation",
"selections": (v1/*: any*/),
"type": "Mutation",
"abstractKey": null
},
"kind": "Request",
"operation": {
"argumentDefinitions": (v0/*: any*/),
"kind": "Operation",
"name": "SettingsPageRemoveUserMutation",
"selections": (v1/*: any*/)
},
"params": {
"cacheID": "62588cd355b82b5a48d0b539a009b3bd",
"id": null,
"metadata": {},
"name": "SettingsPageRemoveUserMutation",
"operationKind": "mutation",
"text": "mutation SettingsPageRemoveUserMutation(\n $input: RemoveUserInput!\n) {\n removeUser(input: $input) {\n success\n }\n}\n"
}
};
})();
(node as any).hash = "8d375bb2dfdab0f9d9520eee9f732b10";
export default node;