diff --git a/src/app/dashboard/(auth)/roles/_components/CreateButton/CreateButton.tsx b/src/app/dashboard/(auth)/roles/_components/CreateButton/CreateButton.tsx
deleted file mode 100644
index 12c67be..0000000
--- a/src/app/dashboard/(auth)/roles/_components/CreateButton/CreateButton.tsx
+++ /dev/null
@@ -1,20 +0,0 @@
-"use client"
-import { Button } from '@mantine/core'
-import Link from 'next/link'
-import { usePathname, useRouter } from 'next/navigation'
-import React, { useState } from 'react'
-import { TbPlus } from 'react-icons/tb'
-import { CreateModal } from '../../_modals'
-
-export default function CreateButton() {
-
- const [isModalOpened, setModalOpened] = useState(false)
-
- return (
- <>
- } onClick={() => setModalOpened(true)}>New Role
-
- setModalOpened(false)} />
- >
- )
-}
diff --git a/src/app/dashboard/(auth)/roles/_modals/CreateModal/CreateModal.tsx b/src/app/dashboard/(auth)/roles/_modals/CreateModal/CreateModal.tsx
deleted file mode 100644
index da59749..0000000
--- a/src/app/dashboard/(auth)/roles/_modals/CreateModal/CreateModal.tsx
+++ /dev/null
@@ -1,25 +0,0 @@
-import React from "react";
-import FormModal from "../FormModal";
-
-interface Props {
- opened: boolean
- onClose?: () => void
-}
-
-export default function CreateModal(props: Props) {
- return (
-
- );
-}
diff --git a/src/app/dashboard/(auth)/roles/_modals/CreateModal/index.ts b/src/app/dashboard/(auth)/roles/_modals/CreateModal/index.ts
deleted file mode 100644
index c88ba8a..0000000
--- a/src/app/dashboard/(auth)/roles/_modals/CreateModal/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export { default } from "./CreateModal"
\ No newline at end of file
diff --git a/src/app/dashboard/(auth)/roles/_modals/DeleteModal/DeleteModal.tsx b/src/app/dashboard/(auth)/roles/_modals/DeleteModal/DeleteModal.tsx
new file mode 100644
index 0000000..695fec3
--- /dev/null
+++ b/src/app/dashboard/(auth)/roles/_modals/DeleteModal/DeleteModal.tsx
@@ -0,0 +1,93 @@
+"use client";
+import { useRouter } from "next/navigation";
+import React, { useState } from "react";
+import {
+ Avatar,
+ Button,
+ Center,
+ Flex,
+ Modal,
+ ScrollArea,
+ Text,
+ Stack,
+ TextInput,
+ Title,
+} from "@mantine/core";
+import { showNotification } from "@/utils/notifications";
+import deleteRole from "@/features/dashboard/roles/actions/deleteRole";
+
+export interface DeleteModalProps {
+ data?: {
+ id: string,
+ name: string,
+ };
+ onClose: () => void
+}
+
+export default function DeleteModal(props: DeleteModalProps) {
+ const router = useRouter();
+
+ const [isSubmitting, setSubmitting] = useState(false);
+
+ /**
+ * Closes the modal. It won't close if a submission is in progress.
+ */
+ const closeModal = () => {
+ if (isSubmitting) return;
+ props.onClose()
+ };
+
+ const confirmAction = () => {
+ if (!props.data?.id) return;
+ setSubmitting(true)
+ deleteRole(props.data.id)
+ .then((response) => {
+ if (response.success){
+ showNotification(response.message);
+ setSubmitting(false)
+ props.onClose()
+ return;
+ } else {
+ showNotification(response.message, "error")
+ }
+ })
+ .catch(() => {
+ //TODO: Handle Error
+ })
+ .finally(() => {
+ setSubmitting(false)
+ })
+ }
+
+ return (
+
+
+ Are you sure you want to delete role{" "}
+
+ {props.data?.name}
+
+ ? This action is irreversible.
+
+ {/* Buttons */}
+
+
+ }
+ type="submit"
+ color="red"
+ loading={isSubmitting}
+ onClick={confirmAction}
+ >
+ Delete Role
+
+
+
+ );
+}
diff --git a/src/app/dashboard/(auth)/roles/_modals/DeleteModal/index.ts b/src/app/dashboard/(auth)/roles/_modals/DeleteModal/index.ts
new file mode 100644
index 0000000..34d6794
--- /dev/null
+++ b/src/app/dashboard/(auth)/roles/_modals/DeleteModal/index.ts
@@ -0,0 +1 @@
+export { default } from "./DeleteModal";
diff --git a/src/app/dashboard/(auth)/roles/_modals/FormModal/FormModal.tsx b/src/app/dashboard/(auth)/roles/_modals/FormModal/FormModal.tsx
index d2f7471..975b835 100644
--- a/src/app/dashboard/(auth)/roles/_modals/FormModal/FormModal.tsx
+++ b/src/app/dashboard/(auth)/roles/_modals/FormModal/FormModal.tsx
@@ -1,4 +1,5 @@
-"use client";
+/* eslint-disable react-hooks/exhaustive-deps */
+import getRoleById from "@/features/dashboard/roles/actions/getRoleById";
import upsertRole from "@/features/dashboard/roles/actions/upsertRole";
import roleFormDataSchema, {
RoleFormData,
@@ -14,59 +15,101 @@ import {
Button,
ScrollArea,
Checkbox,
+ Skeleton,
+ Fieldset,
} from "@mantine/core";
import { useForm, zodResolver } from "@mantine/form";
-import { notifications } from "@mantine/notifications";
import { useRouter } from "next/navigation";
-import React, { useState } from "react";
+import React, { useCallback, useEffect, useState } from "react";
import { TbDeviceFloppy } from "react-icons/tb";
-interface Props {
+export interface ModalProps {
title: string;
readonly?: boolean;
- data: RoleFormData;
+ id?: string;
opened: boolean;
onClose?: () => void;
}
-export default function FormModal(props: Props) {
+/**
+ * A component for rendering a modal with a form to create or edit a role.
+ *
+ * @param props - The props for the component.
+ * @returns The rendered element.
+ */
+export default function FormModal(props: ModalProps) {
const router = useRouter();
+ const [isSubmitting, setSubmitting] = useState(false);
+ const [isFetching, setFetching] = useState(false);
- const [isSubmitting, setSubmitting] = useState(false);
- const [value, setValue] = useState("");
+ const form = useForm({
+ initialValues: {
+ code: "",
+ description: "",
+ id: "",
+ isActive: false,
+ name: "",
+ },
+ validate: zodResolver(roleFormDataSchema),
+ validateInputOnChange: false,
+ onValuesChange: (values) => {
+ console.log(values);
+ },
+ });
- const form = useForm({
- initialValues: props.data,
- validate: zodResolver(roleFormDataSchema),
- validateInputOnChange: false,
- onValuesChange: (values) => {
- console.log(values);
- },
- });
+ /**
+ * Fetches role data by ID and populates the form if the modal is opened and an ID is provided.
+ */
+ useEffect(() => {
+ if (!props.opened || !props.id) {
+ return;
+ }
+
+ setFetching(true);
+ getRoleById(props.id)
+ .then((response) => {
+ if (response.success) {
+ const data = response.data;
+ form.setValues({
+ code: data.code,
+ description: data.description,
+ id: data.id,
+ isActive: data.isActive,
+ name: data.name,
+ });
+ }
+ })
+ .catch((e) => {
+ //TODO: Handle error
+ console.log(e);
+ })
+ .finally(() => {
+ setFetching(false);
+ });
+ }, [props.opened, props.id]);
const closeModal = () => {
- form.reset();
props.onClose ? props.onClose() : router.replace("?");
};
const handleSubmit = (values: RoleFormData) => {
upsertRole(values)
.then((response) => {
- if (response.success){
- showNotification(response.message,"success");
- return closeModal()
+ if (response.success) {
+ showNotification(response.message, "success");
+ return closeModal();
} else {
form.setErrors(response.errors ?? {});
- if (!response.errors){
- showNotification(response.message, "error")
+ if (!response.errors) {
+ showNotification(response.message, "error");
}
}
})
- .catch(e =>{
+ .catch((e) => {
//TODO: Handle Error
- console.log(e)
- })
- }
+ console.log(e);
+ });
+ };
return (