mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-29 19:58:11 +00:00
feat: rebuild the admin pages
This commit is contained in:
@@ -0,0 +1,199 @@
|
||||
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
||||
import { toast } from "sonner";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useErrorHandler } from "@/shared/hooks/useErrorHandler";
|
||||
import {
|
||||
assignOrganizationAdmin,
|
||||
fetchAllUnitAdminById,
|
||||
OrganizationAdminPayload,
|
||||
} from "@/super-admin/services/api/organizationAdminService";
|
||||
import {
|
||||
assignOrgAdminRole,
|
||||
removeOrgAdminRole,
|
||||
removeUnitAdminRole,
|
||||
} from "@/super-admin/services/api/userRoleService";
|
||||
import {
|
||||
activateUser,
|
||||
deactivateUser,
|
||||
} from "@/super-admin/services/api/userService";
|
||||
import { resendVerificationCode } from "@/shared/services/authService";
|
||||
import {
|
||||
updateProfile,
|
||||
UpdateProfilePayload,
|
||||
} from "@/user-management/services/api/employeePositionsService";
|
||||
|
||||
export interface OrgAdminUserRole {
|
||||
id: string;
|
||||
organizationId?: string | null;
|
||||
unitId?: string | null;
|
||||
role?: { key?: string } | null;
|
||||
}
|
||||
|
||||
/** User row returned by GET /organizations/all-admins/:id (userRoles.role relation included). */
|
||||
export interface OrgAdminUser {
|
||||
id: string;
|
||||
name?: { am?: string; en?: string };
|
||||
username?: string;
|
||||
email?: string;
|
||||
phoneNumber?: string;
|
||||
isActive: boolean;
|
||||
hasSetPassword: boolean;
|
||||
status?: string;
|
||||
createdAt?: string;
|
||||
userRoles?: OrgAdminUserRole[];
|
||||
}
|
||||
|
||||
export const ORG_ADMINS_KEY = "orgAdmins";
|
||||
export const ORG_PICKER_KEY = "orgAdminsOrgPicker";
|
||||
|
||||
export interface RemoveAdminInput {
|
||||
userId: string;
|
||||
/** set for org-admin removal */
|
||||
organizationId?: string;
|
||||
/** set for unit-admin removal (wins over organizationId) */
|
||||
unitId?: string;
|
||||
}
|
||||
|
||||
export const useOrgAdmins = (
|
||||
orgId?: string,
|
||||
params?: { take?: number; skip?: number },
|
||||
) => {
|
||||
const queryClient = useQueryClient();
|
||||
const { t } = useTranslation();
|
||||
const { handleError } = useErrorHandler(t);
|
||||
|
||||
const {
|
||||
data: adminsResponse,
|
||||
isLoading,
|
||||
isError,
|
||||
refetch,
|
||||
} = useQuery({
|
||||
queryKey: [ORG_ADMINS_KEY, orgId, params],
|
||||
queryFn: async () => {
|
||||
const { data } = await fetchAllUnitAdminById(orgId as string, params);
|
||||
return {
|
||||
count: (data?.count ?? 0) as number,
|
||||
items: (data?.items ?? []) as OrgAdminUser[],
|
||||
};
|
||||
},
|
||||
enabled: !!orgId,
|
||||
staleTime: 5 * 60 * 1000,
|
||||
retry: false,
|
||||
});
|
||||
|
||||
const invalidate = () => {
|
||||
queryClient.invalidateQueries({ queryKey: [ORG_ADMINS_KEY] });
|
||||
// picker + org tables show adminsCount — keep them fresh
|
||||
queryClient.invalidateQueries({ queryKey: [ORG_PICKER_KEY] });
|
||||
queryClient.invalidateQueries({ queryKey: ["organizations"] });
|
||||
queryClient.invalidateQueries({ queryKey: ["organizationAdmins"] });
|
||||
};
|
||||
|
||||
const { mutate: inviteAdmin, isPending: isInviting } = useMutation({
|
||||
mutationFn: async (payload: OrganizationAdminPayload) => {
|
||||
const { data } = await assignOrganizationAdmin(payload);
|
||||
return data;
|
||||
},
|
||||
onSuccess: () => {
|
||||
toast.success(t("orgAdmins.toasts.invited"));
|
||||
invalidate();
|
||||
},
|
||||
onError: handleError,
|
||||
});
|
||||
|
||||
const { mutate: assignAdmin, isPending: isAssigning } = useMutation({
|
||||
mutationFn: async (payload: { organizationId: string; userId: string }) => {
|
||||
const { data } = await assignOrgAdminRole(payload);
|
||||
return data;
|
||||
},
|
||||
onSuccess: () => {
|
||||
toast.success(t("orgAdmins.toasts.assigned"));
|
||||
invalidate();
|
||||
},
|
||||
onError: handleError,
|
||||
});
|
||||
|
||||
const { mutate: removeAdmin, isPending: isRemoving } = useMutation({
|
||||
mutationFn: async ({ userId, organizationId, unitId }: RemoveAdminInput) => {
|
||||
const { data } = unitId
|
||||
? await removeUnitAdminRole({ unitId, userId })
|
||||
: await removeOrgAdminRole({
|
||||
organizationId: organizationId as string,
|
||||
userId,
|
||||
});
|
||||
return data;
|
||||
},
|
||||
onSuccess: () => {
|
||||
toast.success(t("orgAdmins.toasts.removed"));
|
||||
invalidate();
|
||||
},
|
||||
onError: handleError,
|
||||
});
|
||||
|
||||
const { mutate: resendInvite, isPending: isResending } = useMutation({
|
||||
mutationFn: async (payload: { email: string; phoneNumber: string }) => {
|
||||
const { data } = await resendVerificationCode(payload);
|
||||
return data;
|
||||
},
|
||||
onSuccess: () => {
|
||||
toast.success(t("orgAdmins.toasts.resent"));
|
||||
},
|
||||
onError: handleError,
|
||||
});
|
||||
|
||||
const { mutate: toggleActive, isPending: isToggling } = useMutation({
|
||||
mutationFn: async ({ id, activate }: { id: string; activate: boolean }) => {
|
||||
const { data } = activate
|
||||
? await activateUser(id)
|
||||
: await deactivateUser(id);
|
||||
return data;
|
||||
},
|
||||
onSuccess: (_data, variables) => {
|
||||
toast.success(
|
||||
variables.activate
|
||||
? t("orgAdmins.toasts.activated")
|
||||
: t("orgAdmins.toasts.deactivated"),
|
||||
);
|
||||
invalidate();
|
||||
},
|
||||
onError: handleError,
|
||||
});
|
||||
|
||||
const { mutate: updateAdminProfile, isPending: isUpdatingProfile } =
|
||||
useMutation({
|
||||
mutationFn: async ({
|
||||
id,
|
||||
payload,
|
||||
}: {
|
||||
id: string;
|
||||
payload: UpdateProfilePayload;
|
||||
}) => {
|
||||
const { data } = await updateProfile(payload, id);
|
||||
return data;
|
||||
},
|
||||
onSuccess: () => {
|
||||
toast.success(t("orgAdmins.toasts.profileUpdated"));
|
||||
invalidate();
|
||||
},
|
||||
onError: handleError,
|
||||
});
|
||||
|
||||
return {
|
||||
adminsResponse,
|
||||
isLoading,
|
||||
isError,
|
||||
refetch,
|
||||
inviteAdmin,
|
||||
isInviting,
|
||||
assignAdmin,
|
||||
isAssigning,
|
||||
removeAdmin,
|
||||
isRemoving,
|
||||
resendInvite,
|
||||
isResending,
|
||||
toggleActive,
|
||||
isToggling,
|
||||
updateAdminProfile,
|
||||
isUpdatingProfile,
|
||||
};
|
||||
};
|
||||
Reference in New Issue
Block a user