diff --git a/app/(admin)/admin/master-role/create/page.tsx b/app/(admin)/admin/master-role/create/page.tsx
new file mode 100644
index 0000000..ab2c6f9
--- /dev/null
+++ b/app/(admin)/admin/master-role/create/page.tsx
@@ -0,0 +1,10 @@
+import FormMasterUserRole from '@/components/form/form-master-user-role'
+import { Card } from '@nextui-org/react'
+
+export default function CreateMasterUserRolePage() {
+ return (
+
+
+
+ )
+}
diff --git a/app/(admin)/admin/master-role/page.tsx b/app/(admin)/admin/master-role/page.tsx
new file mode 100644
index 0000000..6abf18b
--- /dev/null
+++ b/app/(admin)/admin/master-role/page.tsx
@@ -0,0 +1,24 @@
+"use client"
+import { AddIcon } from "@/components/icons";
+import MasterRoleTable from "@/components/table/master-role-table";
+import { Button, Card } from "@nextui-org/react";
+import Link from "next/link";
+
+export default function MasterRolePage() {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/components/form/form-master-user-role.tsx b/components/form/form-master-user-role.tsx
new file mode 100644
index 0000000..0d2a685
--- /dev/null
+++ b/components/form/form-master-user-role.tsx
@@ -0,0 +1,164 @@
+'use client'
+import { error } from '@/config/swal';
+import { createMasterUser } from '@/service/master-user';
+import { createMasterUserRole } from '@/service/master-user-role';
+import { MasterUser } from '@/types/globals';
+import { zodResolver } from '@hookform/resolvers/zod';
+import { Button, Card, Input, Radio, RadioGroup, Select, SelectItem, Selection, Textarea } from '@nextui-org/react'
+import Link from 'next/link';
+import { useRouter } from 'next/navigation';
+import React, { useState } from 'react'
+import { useForm } from 'react-hook-form';
+import Swal from 'sweetalert2';
+import withReactContent from 'sweetalert2-react-content';
+import { z } from 'zod';
+
+const masterUserSchema = z.object({
+ code: z.string().min(1, { message: "Required" }),
+ description: z.string().min(1, { message: "Required" }),
+ levelNumber: z.string().min(1, { message: "Required" }),
+ name: z.string().min(1, { message: "Required" }),
+});
+
+export default function FormMasterUserRole() {
+ const router = useRouter();
+ const MySwal = withReactContent(Swal);
+ const [code, setCode] = useState();
+ const [description, setDescription] = useState();
+ const [levelNumber, setLevelNumber] = useState(1);
+ const [name, setName] = useState();
+
+ const formOptions = { resolver: zodResolver(masterUserSchema) };
+ type MicroIssueSchema = z.infer;
+ const {
+ register,
+ control,
+ handleSubmit,
+ setValue,
+ formState: { errors },
+ } = useForm(formOptions);
+
+
+
+ async function save(data: any) {
+ const formData = {
+ code: code,
+ description: description,
+ level_number: levelNumber,
+ name: name,
+ };
+
+ console.log("Form MasterUser:", formData);
+ const response = await createMasterUserRole(formData);
+
+ if (response?.error) {
+ error(response.message);
+ return false;
+ }
+
+ successSubmit("/admin/master-role");
+ };
+
+ function successSubmit(redirect: any) {
+ MySwal.fire({
+ title: "Sukses",
+ icon: "success",
+ confirmButtonColor: "#3085d6",
+ confirmButtonText: "OK",
+ }).then((result) => {
+ if (result.isConfirmed) {
+ router.push(redirect);
+ }
+ });
+ }
+
+ async function onSubmit(data: any) {
+ MySwal.fire({
+ title: "Simpan Data",
+ text: "",
+ icon: "warning",
+ showCancelButton: true,
+ cancelButtonColor: "#d33",
+ confirmButtonColor: "#3085d6",
+ confirmButtonText: "Simpan",
+ }).then((result) => {
+ if (result.isConfirmed) {
+ save(data);
+ }
+ });
+ }
+
+ return (
+
+ )
+}
diff --git a/components/sidebar/sidebar.tsx b/components/sidebar/sidebar.tsx
index d23cbe0..a8b3a2f 100644
--- a/components/sidebar/sidebar.tsx
+++ b/components/sidebar/sidebar.tsx
@@ -182,7 +182,7 @@ const sideBarDummyData = [
name: "Master User Role",
moduleId: 656,
moduleName: "Form Validation",
- modulePathUrl: "/admin/master-user-role",
+ modulePathUrl: "/admin/master-role",
parentId: -1,
icon: ,
position: 1,
diff --git a/components/table/master-role-table.tsx b/components/table/master-role-table.tsx
new file mode 100644
index 0000000..66c546d
--- /dev/null
+++ b/components/table/master-role-table.tsx
@@ -0,0 +1,291 @@
+"use client";
+import {
+ CreateIconIon,
+ DeleteIcon,
+ DotsYIcon,
+ EyeIconMdi
+} from "@/components/icons";
+import { error } from "@/config/swal";
+import { deleteMasterUser } from "@/service/master-user";
+import { deleteMasterUserRole, listUserRole } from "@/service/master-user-role";
+import { MasterUser, MasterUserRole } from "@/types/globals";
+import { Button } from "@nextui-org/button";
+import {
+ Chip,
+ ChipProps,
+ Dropdown,
+ DropdownItem,
+ DropdownMenu,
+ DropdownTrigger,
+ Spinner,
+ Table,
+ TableBody,
+ TableCell,
+ TableColumn,
+ TableHeader,
+ TableRow
+} from "@nextui-org/react";
+import Link from "next/link";
+import { Key, useCallback, useEffect, useState } from "react";
+import Swal from "sweetalert2";
+import withReactContent from "sweetalert2-react-content";
+
+type UserObject = {
+ id: number;
+ user: string;
+ status: string;
+ projectName: string;
+ avatar: string;
+};
+
+const statusColorMap = {
+ active: "success",
+ paused: "danger",
+ vacation: "warning",
+};
+
+
+export default function MasterRoleTable() {
+ const MySwal = withReactContent(Swal);
+ const [role, setRole] = useState([]);
+
+
+ useEffect(() => {
+ initState();
+ }, []);
+
+ async function initState() {
+ const res = await listUserRole();
+ setRole(res.data?.data);
+
+ console.log("List Users", res.data.data);
+ }
+
+ type TableRow = (typeof usersTable)[0];
+
+ const columns = [
+
+ { name: "No", uid: "id" },
+ { name: "Role", uid: "name" },
+ { name: "Description", uid: "description" },
+ { name: "Code", uid: "code" },
+ { name: "Level Number", uid: "level_number" },
+ // { name: "Status Id", uid: "status_id" },
+ { name: "Aksi", uid: "actions" },
+ ];
+
+
+ async function doDelete(id: any) {
+ // loading();
+ const resDelete = await deleteMasterUserRole(id);
+
+ if (resDelete?.error) {
+ error(resDelete.message);
+ return false;
+ }
+ close();
+ successSubmit();
+ }
+
+ const handleDelete = (id: any) => {
+ MySwal.fire({
+ title: "Hapus Data",
+ icon: "warning",
+ showCancelButton: true,
+ cancelButtonColor: "#3085d6",
+ confirmButtonColor: "#d33",
+ confirmButtonText: "Hapus",
+ }).then((result) => {
+ if (result.isConfirmed) {
+ doDelete(id);
+ }
+ });
+ };
+
+ function successSubmit() {
+ MySwal.fire({
+ title: "Sukses",
+ icon: "success",
+ confirmButtonColor: "#3085d6",
+ confirmButtonText: "OK",
+ }).then((result) => {
+ if (result.isConfirmed) {
+ initState()
+ }
+ });
+ }
+
+ // const statusOptions = [
+ // { name: "Active", uid: "active" },
+ // { name: "Paused", uid: "paused" },
+ // { name: "Vacation", uid: "vacation" },
+ // ];
+
+ const usersTable = [
+ {
+ id: 1,
+ user: "Olivia Rhya",
+ status: "active",
+ projectName: "Xtreme admin",
+ avatar: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSa8Luglga9J2R3Bxt_PsWZISUHQWODD6_ZTAJ5mIQgxYCAE-YbkY81faTqp-hSA_jVPTs&usqp=CAU",
+ },
+ {
+ id: 2,
+ user: "Barbara Steele",
+ status: "cancel",
+ projectName: "Adminpro admin",
+ avatar: "https://cdn.icon-icons.com/icons2/2859/PNG/512/avatar_face_man_boy_male_profile_smiley_happy_people_icon_181661.png",
+ },
+ {
+ id: 3,
+ user: "Leonardo Gordon",
+ status: "pending",
+ projectName: "Monster admin",
+ avatar: "https://cdn.icon-icons.com/icons2/2859/PNG/512/avatar_face_man_boy_male_profile_smiley_happy_people_icon_181657.png",
+ },
+ {
+ id: 4,
+ user: "Evelyn Pope",
+ status: "cancel",
+ projectName: "Materialpro admin",
+ avatar: "https://cdn.icon-icons.com/icons2/3708/PNG/512/man_person_people_avatar_icon_230017.png",
+ },
+ {
+ id: 5,
+ user: "Tommy Garza",
+ status: "cancel",
+ projectName: "Elegant admin",
+ avatar: "https://cdn.icon-icons.com/icons2/1736/PNG/512/4043275-avatar-man-person-punk_113271.png",
+ },
+
+
+ ];
+
+ const renderCell = useCallback(
+ (role: MasterUserRole, columnKey: Key) => {
+ const cellValue = role[columnKey as keyof MasterUserRole];
+ const statusColorMap: Record = {
+ active: "primary",
+ cancel: "danger",
+ pending: "success",
+ };
+
+ switch (columnKey) {
+ case "id":
+ return (
+ {role.id}
+ )
+
+ case "status":
+ return (
+
+
+ {cellValue}
+
+
+ );
+
+ case "actions":
+ return (
+
+
+
+
+
+
+
+
+
+
+ Detail
+
+
+
+
+
+
+
+ Edit
+
+
+
+ handleDelete(role.id)}
+ >
+
+
+ Delete
+
+
+
+
+
+
+ );
+
+ default:
+ return cellValue;
+ }
+ }, []);
+
+ return (
+ <>
+
+
+
+
+
+ {(column) => (
+ {column.name}
+ )}
+
+ }
+ >
+ {(item) => (
+
+ {(columnKey) => (
+ {renderCell(item, columnKey)}
+ )}
+
+ )}
+
+
+
+
+
+ >
+ );
+}
diff --git a/service/master-user-role.ts b/service/master-user-role.ts
new file mode 100644
index 0000000..c02290c
--- /dev/null
+++ b/service/master-user-role.ts
@@ -0,0 +1,20 @@
+import { httpDeleteInterceptor, httpGet, httpPost } from "./http-config/axios-base-service";
+
+export async function listUserRole() {
+ const headers = {
+ "content-type": "application/json",
+ };
+ return await httpGet(`/user-roles`, headers);
+}
+
+export async function createMasterUserRole(data: any) {
+ const headers = {
+ "content-type": "application/json",
+ };
+ const pathUrl = `/user-roles`;
+ return await httpPost(pathUrl, headers, data);
+}
+
+export async function deleteMasterUserRole(id: string) {
+ return await httpDeleteInterceptor(`/user-roles/${id}`);
+}
\ No newline at end of file
diff --git a/types/globals.tsx b/types/globals.tsx
index ce6becb..67dfea2 100644
--- a/types/globals.tsx
+++ b/types/globals.tsx
@@ -42,3 +42,15 @@ export type MasterUser = {
workType: string
};
+export type MasterUserRole = {
+ id: number,
+ name: string,
+ description: string,
+ code: string,
+ level_number: number,
+ status_id: number,
+ created_by_id: string | number,
+ is_active: true,
+ created_at: string,
+ updated_at: string
+};