diff --git a/app/routes/admin.py b/app/routes/admin.py index 7d59800..4bec1b0 100644 --- a/app/routes/admin.py +++ b/app/routes/admin.py @@ -154,7 +154,7 @@ def get_admin_users(username: str, db: DBDep, admin: SudoAdminDep): return paginate(query) -@router.get("/{username}/disable_users", response_model=AdminResponse) +@router.post("/{username}/disable_users", response_model=AdminResponse) async def disable_users(username: str, db: DBDep, admin: SudoAdminDep): db_admin = crud.get_admin(db, username) if not db_admin: @@ -176,7 +176,7 @@ async def disable_users(username: str, db: DBDep, admin: SudoAdminDep): return db_admin -@router.get("/{username}/enable_users", response_model=AdminResponse) +@router.post("/{username}/enable_users", response_model=AdminResponse) async def enable_users(username: str, db: DBDep, admin: SudoAdminDep): db_admin = crud.get_admin(db, username) if not db_admin: diff --git a/dashboard/public/locales/en.json b/dashboard/public/locales/en.json index 88ba371..5ddf443 100644 --- a/dashboard/public/locales/en.json +++ b/dashboard/public/locales/en.json @@ -247,6 +247,8 @@ } }, "admins": { + "disable_users": "Disable users", + "enable_users": "Enable users", "permission": "Permission", "dialogs": { "creation": { diff --git a/dashboard/src/modules/admins/api/disable-admin-users.mutate.ts b/dashboard/src/modules/admins/api/disable-admin-users.mutate.ts new file mode 100644 index 0000000..232b8e3 --- /dev/null +++ b/dashboard/src/modules/admins/api/disable-admin-users.mutate.ts @@ -0,0 +1,45 @@ +import { useMutation } from "@tanstack/react-query"; +import { fetch, queryClient } from "@marzneshin/common/utils"; +import { toast } from "sonner"; +import i18n from "@marzneshin/features/i18n"; +import { AdminType } from "../types"; + +interface AdminUsersStatusDisableQuery { + admin: AdminType; +} + +export async function adminUsersStatusDisable({ admin }: AdminUsersStatusDisableQuery): Promise { + return fetch(`/admins/${admin.username}/disable_users`, { method: 'post' }).then((admin) => { + return admin; + }); +} + +const handleError = (error: Error, value: AdminUsersStatusDisableQuery) => { + toast.error( + i18n.t('events.user_status.error', { name: value.admin.username }), + { + description: error.message + }) +} + +const handleSuccess = (value: AdminType) => { + toast.success( + i18n.t('events.user_status.success.title', { name: value.username }), + { + description: i18n.t('events.user_status.success.desc') + }) + queryClient.invalidateQueries({ queryKey: [UsersStatusEnabledFetchKey] }) + queryClient.invalidateQueries({ queryKey: [UsersStatusEnabledFetchKey, value.username] }) +} + + +const UsersStatusEnabledFetchKey = "admins"; + +export const useAdminUsersStatusDisable = () => { + return useMutation({ + mutationKey: [UsersStatusEnabledFetchKey], + mutationFn: adminUsersStatusDisable, + onError: handleError, + onSuccess: handleSuccess, + }) +} diff --git a/dashboard/src/modules/admins/api/enable-admin-users.mutate.ts b/dashboard/src/modules/admins/api/enable-admin-users.mutate.ts new file mode 100644 index 0000000..b7e327f --- /dev/null +++ b/dashboard/src/modules/admins/api/enable-admin-users.mutate.ts @@ -0,0 +1,45 @@ +import { useMutation } from "@tanstack/react-query"; +import { fetch, queryClient } from "@marzneshin/common/utils"; +import { toast } from "sonner"; +import i18n from "@marzneshin/features/i18n"; +import { AdminType } from "../types"; + +interface AdminUsersStatusEnableQuery { + admin: AdminType; +} + +export async function adminUsersStatusEnable({ admin }: AdminUsersStatusEnableQuery): Promise { + return fetch(`/admins/${admin.username}/enable_users`, { method: 'post' }).then((admin) => { + return admin; + }); +} + +const handleError = (error: Error, value: AdminUsersStatusEnableQuery) => { + toast.error( + i18n.t('events.user_status.error', { name: value.admin.username }), + { + description: error.message + }) +} + +const handleSuccess = (value: AdminType) => { + toast.success( + i18n.t('events.user_status.success.title', { name: value.username }), + { + description: i18n.t('events.user_status.success.desc') + }) + queryClient.invalidateQueries({ queryKey: [UsersStatusEnabledFetchKey] }) + queryClient.invalidateQueries({ queryKey: [UsersStatusEnabledFetchKey, value.username] }) +} + + +const UsersStatusEnabledFetchKey = "admins"; + +export const useAdminUsersStatusEnable = () => { + return useMutation({ + mutationKey: [UsersStatusEnabledFetchKey], + mutationFn: adminUsersStatusEnable, + onError: handleError, + onSuccess: handleSuccess, + }) +} diff --git a/dashboard/src/modules/admins/api/index.ts b/dashboard/src/modules/admins/api/index.ts index ace51db..f551d29 100644 --- a/dashboard/src/modules/admins/api/index.ts +++ b/dashboard/src/modules/admins/api/index.ts @@ -3,3 +3,5 @@ export * from "./admin.query"; export * from "./update-admin.mutate"; export * from "./create-admin.mutate"; export * from "./delete-admin.mutate"; +export * from "./disable-admin-users.mutate"; +export * from "./enable-admin-users.mutate"; diff --git a/dashboard/src/modules/admins/components/dialogs/settings/admin-info/table.tsx b/dashboard/src/modules/admins/components/dialogs/settings/admin-info/table.tsx index 967e930..58125aa 100644 --- a/dashboard/src/modules/admins/components/dialogs/settings/admin-info/table.tsx +++ b/dashboard/src/modules/admins/components/dialogs/settings/admin-info/table.tsx @@ -1,4 +1,5 @@ import { + Button, Card, CardContent, CardHeader, @@ -7,23 +8,50 @@ import { TableBody, TableRowWithCell, } from "@marzneshin/common/components"; -import { FC } from "react"; +import { FC, useCallback } from "react"; import { type AdminProp, AdminEnabledPill, - AdminPermissionPill + AdminPermissionPill, + useAdminUsersStatusDisable, + useAdminUsersStatusEnable } from "@marzneshin/modules/admins"; import { useTranslation } from "react-i18next"; +import { LoaderIcon, UserCheck, UserX } from "lucide-react"; import { format } from '@chbphone55/pretty-bytes'; export const AdminInfoTable: FC = ({ admin: entity }) => { const { t } = useTranslation(); const usersDataUsage = format(entity.users_data_usage); + const { mutate: adminStatusEnable, isPending: enablePending } = useAdminUsersStatusEnable() + const { mutate: adminStatusDisable, isPending: disablePending } = useAdminUsersStatusDisable() + + const handleAdmingStatusEnable = useCallback(() => { + adminStatusEnable({ admin: entity }) + }, [entity, adminStatusEnable]); + + const handleAdmingStatusDisable = useCallback(() => { + adminStatusDisable({ admin: entity }) + }, [entity, adminStatusDisable]); return ( {t("admin_info")} +
+ + +