diff --git a/src/app/dashboard/permissions/page.tsx b/src/app/dashboard/permissions/page.tsx
index 135bd44..b1ea645 100644
--- a/src/app/dashboard/permissions/page.tsx
+++ b/src/app/dashboard/permissions/page.tsx
@@ -1,24 +1,15 @@
import checkMultiplePermissions from "@/modules/auth/utils/checkMultiplePermissions";
-import getAllPermissions from "@/modules/permission/actions/getAllPermissions";
+import getAllPermissions from "@/modules/permission/services/getAllPermissions";
import PermissionsTable from "@/modules/permission/tables/PermissionTable/PermissionTable";
import { Card, Stack, Title } from "@mantine/core";
import { Metadata } from "next";
import React from "react";
-interface Props {
- searchParams: {
- detail?: string;
- edit?: string;
- delete?: string;
- create?: string;
- };
-}
-
export const metadata: Metadata = {
title: "Permissions - Dashboard",
};
-export default async function RolesPage({ searchParams }: Props) {
+export default async function RolesPage() {
const permissions = await checkMultiplePermissions({
create: "permissions.create",
readAll: "permissions.readAll",
@@ -27,14 +18,13 @@ export default async function RolesPage({ searchParams }: Props) {
delete: "permissions.delete",
});
- const res = await getAllPermissions();
- if (!res.success) throw new Error("Error while fetch permission");
+ const permissionsData = await getAllPermissions();
return (
Permissions
-
+
);
diff --git a/src/modules/permission/actions/deletePermission.ts b/src/modules/permission/actions/deletePermission.ts
deleted file mode 100644
index 4860325..0000000
--- a/src/modules/permission/actions/deletePermission.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-"use server";
-
-import db from "@/core/db";
-import prisma from "@/db";
-import checkPermission from "@/modules/dashboard/services/checkPermission";
-import ServerResponseAction from "@/modules/dashboard/types/ServerResponseAction";
-import handleCatch from "@/modules/dashboard/utils/handleCatch";
-import unauthorized from "@/modules/dashboard/utils/unauthorized";
-import { revalidatePath } from "next/cache";
-
-export default async function deletePermission(id: string): Promise {
- try {
- if (!(await checkPermission("permission.delete"))) unauthorized();
- const permission = await db.permission.delete({
- where: { id },
- });
-
-
- revalidatePath(".")
-
- return {
- success: true,
- message: "The permission has been deleted successfully",
- };
- } catch (e: unknown) {
- return handleCatch(e)
- }
-}
diff --git a/src/modules/permission/actions/deletePermissionAction.ts b/src/modules/permission/actions/deletePermissionAction.ts
new file mode 100644
index 0000000..fe03a23
--- /dev/null
+++ b/src/modules/permission/actions/deletePermissionAction.ts
@@ -0,0 +1,26 @@
+"use server";
+
+import ServerResponseAction from "@/modules/dashboard/types/ServerResponseAction";
+import handleCatch from "@/modules/dashboard/utils/handleCatch";
+import unauthorized from "@/modules/dashboard/utils/unauthorized";
+import { revalidatePath } from "next/cache";
+import deletePermission from "../services/deletePermission";
+import checkPermission from "@/modules/auth/utils/checkPermission";
+
+export default async function deletePermissionAction(
+ id: string
+): Promise {
+ try {
+ if (!(await checkPermission("permissions.delete"))) unauthorized();
+
+ await deletePermission(id);
+ revalidatePath(".");
+
+ return {
+ success: true,
+ message: "The permission has been deleted successfully",
+ };
+ } catch (e: unknown) {
+ return handleCatch(e);
+ }
+}
diff --git a/src/modules/permission/actions/getAllPermissions.ts b/src/modules/permission/actions/getAllPermissions.ts
deleted file mode 100644
index 8be34a4..0000000
--- a/src/modules/permission/actions/getAllPermissions.ts
+++ /dev/null
@@ -1,57 +0,0 @@
-"use server"
-import prisma from "@/db";
-import checkPermission from "@/modules/dashboard/services/checkPermission";
-import ServerResponseAction from "@/modules/dashboard/types/ServerResponseAction";
-import handleCatch from "@/modules/dashboard/utils/handleCatch";
-import unauthorized from "@/modules/dashboard/utils/unauthorized";
-import "server-only";
-import Permission from "../types/Permission";
-import db from "@/core/db";
-
-/**
- * Retrieves all permissions along with the count of associated permissions and users.
- * Authorization check is performed for the operation.
- *
- * @returns An array of permission objects each including details and counts of related permissions and users.
- */
-export default async function getAllPermissions(): Promise> {
- // Authorization check
- if (!(await checkPermission("permissions.readAll"))) {
- unauthorized();
- }
-
- try {
- // Fetch permissions from the database
- const permissions = await db.permission.findMany({
- include: {
- _count: {
- select: {
- roles: true,
- directUsers: true,
- },
- },
- },
- });
-
- // Transform the data into the desired format
- const permissionsData = permissions.map(
- ({ id, code, name, description, isActive, _count }) => ({
- id,
- code,
- name,
- description,
- isActive,
- roleCount: _count.roles,
- //User count counts only direct user
- userCount: _count.directUsers,
- })
- );
-
- return {
- success: true,
- data: permissionsData
- }
- } catch (error) {
- return handleCatch(error)
- }
-}
diff --git a/src/modules/permission/actions/getAllPermissionsAction.ts b/src/modules/permission/actions/getAllPermissionsAction.ts
new file mode 100644
index 0000000..7a26886
--- /dev/null
+++ b/src/modules/permission/actions/getAllPermissionsAction.ts
@@ -0,0 +1,34 @@
+"use server";
+import ServerResponseAction from "@/modules/dashboard/types/ServerResponseAction";
+import handleCatch from "@/modules/dashboard/utils/handleCatch";
+import unauthorized from "@/modules/dashboard/utils/unauthorized";
+import Permission from "../types/Permission";
+import getAllPermissions from "../services/getAllPermissions";
+import checkPermission from "@/modules/auth/utils/checkPermission";
+
+/**
+ * Retrieves all permissions along with the count of associated permissions and users.
+ * Authorization check is performed for the operation.
+ *
+ * @returns An array of permission objects each including details and counts of related permissions and users.
+ */
+export default async function getAllPermissionsAction(): Promise<
+ ServerResponseAction
+> {
+ // Authorization check
+ if (!(await checkPermission("permissions.readAll"))) {
+ unauthorized();
+ }
+
+ try {
+ // Fetch permissions from the database
+ const permissionsData = await getAllPermissions();
+
+ return {
+ success: true,
+ data: permissionsData,
+ };
+ } catch (error) {
+ return handleCatch(error);
+ }
+}
diff --git a/src/modules/permission/actions/getPermissionById.ts b/src/modules/permission/actions/getPermissionByIdAction.ts
similarity index 52%
rename from src/modules/permission/actions/getPermissionById.ts
rename to src/modules/permission/actions/getPermissionByIdAction.ts
index 9cabbec..7e19dfa 100644
--- a/src/modules/permission/actions/getPermissionById.ts
+++ b/src/modules/permission/actions/getPermissionByIdAction.ts
@@ -1,11 +1,10 @@
"use server";
-import db from "@/core/db";
-import prisma from "@/db";
-import checkPermission from "@/modules/dashboard/services/checkPermission";
+import checkPermission from "@/modules/auth/utils/checkPermission";
import ServerResponseAction from "@/modules/dashboard/types/ServerResponseAction";
import handleCatch from "@/modules/dashboard/utils/handleCatch";
import unauthorized from "@/modules/dashboard/utils/unauthorized";
+import getPermissionById from "../services/getPermissionById";
interface Permission {
id: string;
@@ -15,33 +14,16 @@ interface Permission {
isActive: boolean;
}
-export default async function getPermissionById(
+export default async function getPermissionByIdAction(
id: string
): Promise> {
try {
if (!(await checkPermission("permissions.read"))) unauthorized();
- const permission = await db.permission.findFirst({
- where: { id },
- select: {
- code: true,
- description: true,
- id: true,
- isActive: true,
- name: true,
- },
- });
-
- if (!permission) {
- return {
- success: false,
- message: "Permission not found",
- } as const;
- }
+ const permission = await getPermissionById(id);
return {
success: true,
- message: "Permission fetched successfully",
data: permission,
} as const;
} catch (e) {
diff --git a/src/modules/permission/actions/upsertPermission.ts b/src/modules/permission/actions/upsertPermission.ts
deleted file mode 100644
index 94d4c47..0000000
--- a/src/modules/permission/actions/upsertPermission.ts
+++ /dev/null
@@ -1,84 +0,0 @@
-"use server";
-
-import permissionFormDataSchema, { PermissionFormData } from "../formSchemas/PermissionFormData";
-import mapObjectToFirstValue from "@/utils/mapObjectToFirstValue";
-import prisma from "@/db";
-import { revalidatePath } from "next/cache";
-import ServerResponseAction from "@/modules/dashboard/types/ServerResponseAction";
-import checkPermission from "@/modules/dashboard/services/checkPermission";
-import unauthorized from "@/modules/dashboard/utils/unauthorized";
-import DashboardError from "@/modules/dashboard/errors/DashboardError";
-import handleCatch from "@/modules/dashboard/utils/handleCatch";
-import db from "@/core/db";
-
-/**
- * Upserts a permission based on the provided PermissionFormData.
- * If the permission already exists (determined by `id`), it updates the permission; otherwise, it creates a new permission.
- * Authorization checks are performed based on whether it's a create or update operation.
- *
- * @param data - The data for creating or updating the permission.
- * @returns An object containing the success status, message, and any errors.
- */
-export default async function upsertPermission(
- data: PermissionFormData
-): Promise {
- try {
- const isInsert = !data.id;
-
- // Authorization check
- const permissionType = isInsert ? "permission.create" : "permission.update";
- if (!(await checkPermission(permissionType))) {
- unauthorized();
- }
-
- // Validate form data
- const validatedFields = permissionFormDataSchema.safeParse(data);
- if (!validatedFields.success) {
- throw new DashboardError({
- errorCode: "INVALID_FORM_DATA",
- formErrors: mapObjectToFirstValue(validatedFields.error.flatten().fieldErrors)
- })
- }
- const permissionData = {
- code: validatedFields.data.code,
- description: validatedFields.data.description,
- name: validatedFields.data.name,
- isActive: validatedFields.data.isActive,
- };
-
- // Database operation
- if (isInsert) {
- if (await db.permission.findFirst({
- where: {
- code: permissionData.code
- }
- })){
- throw new DashboardError({
- errorCode: "INVALID_FORM_DATA",
- formErrors: {
- code: "The code is already exists"
- }
- })
- }
- await db.permission.create({ data: permissionData });
- } else {
- await db.permission.update({
- where: { id: validatedFields.data.id! },
- data: permissionData,
- });
- }
-
- // Revalidate the cache
- revalidatePath(".");
-
- // Return success message
- return {
- success: true,
- message: `Permission ${validatedFields.data.name} has been successfully ${
- isInsert ? "created" : "updated"
- }.`,
- };
- } catch (error) {
- return handleCatch(error)
- }
-}
diff --git a/src/modules/permission/actions/upsertPermissionAction.ts b/src/modules/permission/actions/upsertPermissionAction.ts
new file mode 100644
index 0000000..645e72a
--- /dev/null
+++ b/src/modules/permission/actions/upsertPermissionAction.ts
@@ -0,0 +1,48 @@
+"use server";
+
+import { PermissionFormData } from "../formSchemas/PermissionFormData";
+import { revalidatePath } from "next/cache";
+import ServerResponseAction from "@/modules/dashboard/types/ServerResponseAction";
+import unauthorized from "@/modules/dashboard/utils/unauthorized";
+import handleCatch from "@/modules/dashboard/utils/handleCatch";
+import checkPermission from "@/modules/auth/utils/checkPermission";
+import upsertPermission from "../services/upsertPermission";
+
+/**
+ * Upserts a permission based on the provided PermissionFormData.
+ * If the permission already exists (determined by `id`), it updates the permission; otherwise, it creates a new permission.
+ * Authorization checks are performed based on whether it's a create or update operation.
+ *
+ * @param data - The data for creating or updating the permission.
+ * @returns An object containing the success status, message, and any errors.
+ */
+export default async function upsertPermissionAction(
+ data: PermissionFormData
+): Promise {
+ try {
+ const isInsert = !data.id;
+
+ // Authorization check
+ const permissionType = isInsert
+ ? "permissions.create"
+ : "permissions.update";
+ if (!(await checkPermission(permissionType))) {
+ unauthorized();
+ }
+
+ const result = await upsertPermission(data);
+
+ // Revalidate the cache
+ revalidatePath(".");
+
+ // Return success message
+ return {
+ success: true,
+ message: `Permission ${result.name} has been successfully ${
+ isInsert ? "created" : "updated"
+ }.`,
+ };
+ } catch (error) {
+ return handleCatch(error);
+ }
+}
diff --git a/src/modules/permission/modals/PermissionDeleteModal.tsx b/src/modules/permission/modals/PermissionDeleteModal.tsx
index 7d74a3a..1508751 100644
--- a/src/modules/permission/modals/PermissionDeleteModal.tsx
+++ b/src/modules/permission/modals/PermissionDeleteModal.tsx
@@ -9,7 +9,7 @@ import {
} from "@mantine/core";
import { showNotification } from "@/utils/notifications";
import withServerAction from "@/modules/dashboard/utils/withServerAction";
-import deletePermission from "../actions/deletePermission";
+import deletePermissionAction from "../actions/deletePermissionAction";
import ClientError from "@/core/error/ClientError";
export interface DeleteModalProps {
@@ -37,7 +37,7 @@ export default function DeleteModal(props: DeleteModalProps) {
if (!props.data?.id) return;
setSubmitting(true);
- withServerAction(deletePermission, props.data!.id)
+ withServerAction(deletePermissionAction, props.data!.id)
.then((response) => {
showNotification(
response.message ?? "Permission deleted successfully"
diff --git a/src/modules/permission/modals/PermissionFormModal.tsx b/src/modules/permission/modals/PermissionFormModal.tsx
index a4db843..b4ec01a 100644
--- a/src/modules/permission/modals/PermissionFormModal.tsx
+++ b/src/modules/permission/modals/PermissionFormModal.tsx
@@ -17,9 +17,9 @@ import { useRouter } from "next/navigation";
import React, { useEffect, useState } from "react";
import { TbDeviceFloppy } from "react-icons/tb";
import permissionFormDataSchema, { PermissionFormData } from "../formSchemas/PermissionFormData";
-import getPermissionById from "../actions/getPermissionById";
+import getPermissionByIdAction from "../actions/getPermissionByIdAction";
import withServerAction from "@/modules/dashboard/utils/withServerAction";
-import upsertPermission from "../actions/upsertPermission";
+import upsertPermissionAction from "../actions/upsertPermissionAction";
import ClientError from "@/core/error/ClientError";
export interface ModalProps {
@@ -66,7 +66,7 @@ export default function FormModal(props: ModalProps) {
}
setFetching(true);
- getPermissionById(props.id)
+ withServerAction(getPermissionByIdAction, props.id)
.then((response) => {
if (response.success) {
const data = response.data;
@@ -95,7 +95,7 @@ export default function FormModal(props: ModalProps) {
const handleSubmit = (values: PermissionFormData) => {
setSubmitting(true);
- withServerAction(upsertPermission, values)
+ withServerAction(upsertPermissionAction, values)
.then((response) => {
showNotification(response.message!, "success");
closeModal();
diff --git a/src/modules/permission/services/deletePermission.ts b/src/modules/permission/services/deletePermission.ts
new file mode 100644
index 0000000..bbd438f
--- /dev/null
+++ b/src/modules/permission/services/deletePermission.ts
@@ -0,0 +1,15 @@
+import "server-only"
+import db from "@/core/db";
+import notFound from "@/modules/dashboard/utils/notFound";
+
+export default async function deletePermission(id: string) {
+ const permission = await db.permission.delete({
+ where: { id },
+ });
+
+ if (!permission) return notFound({
+ message: "The permission does not exists"
+ });
+
+ return true as const;
+}
diff --git a/src/modules/permission/services/getAllPermissions.ts b/src/modules/permission/services/getAllPermissions.ts
new file mode 100644
index 0000000..b1f77a4
--- /dev/null
+++ b/src/modules/permission/services/getAllPermissions.ts
@@ -0,0 +1,32 @@
+import db from "@/core/db";
+import "server-only";
+import Permission from "../types/Permission";
+
+export default async function getAllPermissions(): Promise {
+ const permissions = await db.permission.findMany({
+ include: {
+ _count: {
+ select: {
+ roles: true,
+ directUsers: true,
+ },
+ },
+ },
+ });
+
+ // Transform the data into the desired format
+ const permissionsData = permissions.map(
+ ({ id, code, name, description, isActive, _count }) => ({
+ id,
+ code,
+ name,
+ description,
+ isActive,
+ roleCount: _count.roles,
+ //User count counts only direct user
+ userCount: _count.directUsers,
+ })
+ );
+
+ return permissionsData;
+}
diff --git a/src/modules/permission/services/getPermissionById.ts b/src/modules/permission/services/getPermissionById.ts
new file mode 100644
index 0000000..59885bb
--- /dev/null
+++ b/src/modules/permission/services/getPermissionById.ts
@@ -0,0 +1,22 @@
+import db from "@/core/db";
+import notFound from "@/modules/dashboard/utils/notFound";
+import "server-only"
+
+export default async function getPermissionById(id: string){
+ const permission = await db.permission.findFirst({
+ where: { id },
+ select: {
+ code: true,
+ description: true,
+ id: true,
+ isActive: true,
+ name: true,
+ },
+ });
+
+ if (!permission) return notFound({
+ message: "The permission does not exists"
+ })
+
+ return permission;
+}
\ No newline at end of file
diff --git a/src/modules/permission/services/upsertPermission.ts b/src/modules/permission/services/upsertPermission.ts
new file mode 100644
index 0000000..5b1404c
--- /dev/null
+++ b/src/modules/permission/services/upsertPermission.ts
@@ -0,0 +1,50 @@
+import "server-only";
+import permissionFormDataSchema, { PermissionFormData } from "../formSchemas/PermissionFormData";
+import DashboardError from "@/modules/dashboard/errors/DashboardError";
+import mapObjectToFirstValue from "@/utils/mapObjectToFirstValue";
+import db from "@/core/db";
+
+export default async function upsertPermission(data: PermissionFormData) {
+ const isInsert = !data.id;
+
+ // Validate form data
+ const validatedFields = permissionFormDataSchema.safeParse(data);
+ if (!validatedFields.success) {
+ throw new DashboardError({
+ errorCode: "INVALID_FORM_DATA",
+ formErrors: mapObjectToFirstValue(
+ validatedFields.error.flatten().fieldErrors
+ ),
+ });
+ }
+ const permissionData = {
+ code: validatedFields.data.code,
+ description: validatedFields.data.description,
+ name: validatedFields.data.name,
+ isActive: validatedFields.data.isActive,
+ };
+
+ // Database operation
+ if (isInsert) {
+ if (
+ await db.permission.findFirst({
+ where: {
+ code: permissionData.code,
+ },
+ })
+ ) {
+ throw new DashboardError({
+ errorCode: "INVALID_FORM_DATA",
+ formErrors: {
+ code: "The code is already exists",
+ },
+ });
+ }
+ return await db.permission.create({ data: permissionData });
+ } else {
+ return await db.permission.update({
+ where: { id: validatedFields.data.id! },
+ data: permissionData,
+ });
+ }
+}
diff --git a/src/modules/permission/tables/PermissionTable/PermissionTable.tsx b/src/modules/permission/tables/PermissionTable/PermissionTable.tsx
index 65e5df9..71b9056 100644
--- a/src/modules/permission/tables/PermissionTable/PermissionTable.tsx
+++ b/src/modules/permission/tables/PermissionTable/PermissionTable.tsx
@@ -15,7 +15,7 @@ import DashboardTable from "@/modules/dashboard/components/DashboardTable";
interface Props {
permissions: Partial;
- permissionData: Permission[];
+ data: Permission[];
}
export default function PermissionsTable(props: Props) {
@@ -31,7 +31,7 @@ export default function PermissionsTable(props: Props) {
});
const table = useReactTable({
- data: props.permissionData,
+ data: props.data,
columns: createColumns({
permissions: props.permissions,
actions: {