2024-12-04 02:35:29 +00:00
|
|
|
"use client";
|
|
|
|
|
import { error } from "@/config/swal";
|
2025-05-04 07:14:12 +00:00
|
|
|
import { createMasterUser } from "@/services/master-user";
|
|
|
|
|
import { createMasterUserRole } from "@/services/master-user-role";
|
2024-12-04 02:35:29 +00:00
|
|
|
import { MasterUser } from "@/types/globals";
|
|
|
|
|
import { zodResolver } from "@hookform/resolvers/zod";
|
|
|
|
|
import {
|
|
|
|
|
Button,
|
|
|
|
|
Card,
|
|
|
|
|
Checkbox,
|
|
|
|
|
Input,
|
|
|
|
|
Radio,
|
|
|
|
|
RadioGroup,
|
|
|
|
|
Select,
|
|
|
|
|
SelectItem,
|
|
|
|
|
Selection,
|
|
|
|
|
Textarea,
|
2025-02-13 08:25:39 +00:00
|
|
|
} from "@heroui/react";
|
2024-12-04 02:35:29 +00:00
|
|
|
import Link from "next/link";
|
|
|
|
|
import { useRouter } from "next/navigation";
|
|
|
|
|
import React, { useEffect, useState } from "react";
|
|
|
|
|
import { Controller, useFieldArray, useForm } from "react-hook-form";
|
|
|
|
|
import Swal from "sweetalert2";
|
|
|
|
|
import withReactContent from "sweetalert2-react-content";
|
|
|
|
|
import { z } from "zod";
|
2024-04-24 10:41:04 +00:00
|
|
|
|
|
|
|
|
const masterUserSchema = z.object({
|
2024-12-04 02:35:29 +00:00
|
|
|
code: z.string().min(1, { message: "Required" }),
|
|
|
|
|
description: z.string().min(1, { message: "Required" }),
|
|
|
|
|
name: z.string().min(1, { message: "Required" }),
|
|
|
|
|
userLevelId: z.string().min(1, { message: "Required" }),
|
|
|
|
|
userRoleAccess: z.array(
|
|
|
|
|
z.object({
|
|
|
|
|
isAdminEnabled: z.boolean(),
|
|
|
|
|
isApprovalEnabled: z.boolean(),
|
|
|
|
|
isDeleteEnabled: z.boolean(),
|
|
|
|
|
isInsertEnabled: z.boolean(),
|
|
|
|
|
isUpdateEnabled: z.boolean(),
|
|
|
|
|
isViewEnabled: z.boolean(),
|
|
|
|
|
menuId: z.number(),
|
|
|
|
|
menuTitle: z.string(),
|
|
|
|
|
})
|
|
|
|
|
),
|
2024-04-24 10:41:04 +00:00
|
|
|
});
|
|
|
|
|
|
2024-12-04 02:35:29 +00:00
|
|
|
const menus = [{ id: 1, title: "Menu 1" }];
|
|
|
|
|
|
2024-04-24 10:41:04 +00:00
|
|
|
export default function FormMasterUserRole() {
|
2024-12-04 02:35:29 +00:00
|
|
|
const router = useRouter();
|
|
|
|
|
const MySwal = withReactContent(Swal);
|
2024-04-24 10:41:04 +00:00
|
|
|
|
2024-12-04 02:35:29 +00:00
|
|
|
const formOptions = {
|
|
|
|
|
resolver: zodResolver(masterUserSchema),
|
|
|
|
|
};
|
|
|
|
|
type MicroIssueSchema = z.infer<typeof masterUserSchema>;
|
|
|
|
|
const {
|
|
|
|
|
register,
|
|
|
|
|
control,
|
|
|
|
|
handleSubmit,
|
|
|
|
|
setValue,
|
|
|
|
|
getValues,
|
|
|
|
|
formState: { errors },
|
|
|
|
|
} = useForm<MicroIssueSchema>(formOptions);
|
|
|
|
|
const { fields, append, remove } = useFieldArray({
|
|
|
|
|
control,
|
|
|
|
|
name: "userRoleAccess",
|
|
|
|
|
});
|
2024-04-24 10:41:04 +00:00
|
|
|
|
2024-12-04 02:35:29 +00:00
|
|
|
useEffect(() => {
|
|
|
|
|
const data: any = [];
|
|
|
|
|
menus.map((menu) => {
|
|
|
|
|
data.push({
|
|
|
|
|
menuId: menu.id,
|
|
|
|
|
isAdminEnabled: false,
|
|
|
|
|
isApprovalEnabled: false,
|
|
|
|
|
isDeleteEnabled: false,
|
|
|
|
|
isInsertEnabled: false,
|
|
|
|
|
isUpdateEnabled: false,
|
|
|
|
|
isViewEnabled: false,
|
|
|
|
|
menuTitle: menu.title,
|
|
|
|
|
});
|
|
|
|
|
});
|
2024-04-24 10:41:04 +00:00
|
|
|
|
2024-12-04 02:35:29 +00:00
|
|
|
setValue("userRoleAccess", data);
|
|
|
|
|
}, []);
|
2024-04-24 10:41:04 +00:00
|
|
|
|
2024-12-04 02:35:29 +00:00
|
|
|
async function save(data: z.infer<typeof masterUserSchema>) {
|
|
|
|
|
const formData = {
|
|
|
|
|
code: data.code,
|
|
|
|
|
description: data.description,
|
2025-02-17 10:18:50 +00:00
|
|
|
statusId: 2,
|
2024-12-04 02:35:29 +00:00
|
|
|
userLevelIds: [Number(data.userLevelId)],
|
|
|
|
|
name: data.name,
|
|
|
|
|
userRoleAccess: data.userRoleAccess.map((roleAccess) => {
|
|
|
|
|
return {
|
|
|
|
|
isAdminEnabled: roleAccess.isAdminEnabled,
|
|
|
|
|
isApprovalEnabled: roleAccess.isApprovalEnabled,
|
|
|
|
|
isDeleteEnabled: roleAccess.isDeleteEnabled,
|
|
|
|
|
isInsertEnabled: roleAccess.isInsertEnabled,
|
|
|
|
|
isUpdateEnabled: roleAccess.isUpdateEnabled,
|
|
|
|
|
isViewEnabled: roleAccess.isViewEnabled,
|
2025-02-17 10:18:50 +00:00
|
|
|
menuId: 1,
|
2024-04-24 10:41:04 +00:00
|
|
|
};
|
2024-12-04 02:35:29 +00:00
|
|
|
}),
|
|
|
|
|
};
|
2024-04-24 10:41:04 +00:00
|
|
|
|
2024-12-04 02:35:29 +00:00
|
|
|
console.log("Form MasterUser:", formData);
|
|
|
|
|
const response = await createMasterUserRole(formData);
|
2024-04-24 10:41:04 +00:00
|
|
|
|
2024-12-04 02:35:29 +00:00
|
|
|
if (response?.error) {
|
|
|
|
|
error(response.message);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2024-04-24 10:41:04 +00:00
|
|
|
|
2024-12-04 02:35:29 +00:00
|
|
|
successSubmit("/admin/master-role");
|
|
|
|
|
}
|
2024-04-24 10:41:04 +00:00
|
|
|
|
2024-12-04 02:35:29 +00:00
|
|
|
function successSubmit(redirect: any) {
|
|
|
|
|
MySwal.fire({
|
|
|
|
|
title: "Sukses",
|
|
|
|
|
icon: "success",
|
|
|
|
|
confirmButtonColor: "#3085d6",
|
|
|
|
|
confirmButtonText: "OK",
|
|
|
|
|
}).then((result) => {
|
|
|
|
|
if (result.isConfirmed) {
|
|
|
|
|
router.push(redirect);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
2024-04-24 10:41:04 +00:00
|
|
|
|
2024-12-04 02:35:29 +00:00
|
|
|
async function onSubmit(data: z.infer<typeof masterUserSchema>) {
|
|
|
|
|
MySwal.fire({
|
|
|
|
|
title: "Simpan Data",
|
|
|
|
|
text: "",
|
|
|
|
|
icon: "warning",
|
|
|
|
|
showCancelButton: true,
|
|
|
|
|
cancelButtonColor: "#d33",
|
|
|
|
|
confirmButtonColor: "#3085d6",
|
|
|
|
|
confirmButtonText: "Simpan",
|
|
|
|
|
}).then((result) => {
|
|
|
|
|
if (result.isConfirmed) {
|
|
|
|
|
save(data);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
2024-04-24 10:41:04 +00:00
|
|
|
|
2024-12-04 02:35:29 +00:00
|
|
|
return (
|
|
|
|
|
<div className="mx-5 my-5 overflow-y-auto">
|
|
|
|
|
<form method="POST" onSubmit={handleSubmit(onSubmit)}>
|
|
|
|
|
<Card className="rounded-md flex flex-col gap-3 p-5">
|
|
|
|
|
<Controller
|
|
|
|
|
control={control}
|
|
|
|
|
name="code"
|
|
|
|
|
render={({ field: { onChange, value } }) => (
|
|
|
|
|
<Input
|
|
|
|
|
type="text"
|
|
|
|
|
id="code"
|
|
|
|
|
placeholder="Code..."
|
|
|
|
|
label="Code"
|
|
|
|
|
value={value}
|
|
|
|
|
onChange={onChange}
|
|
|
|
|
labelPlacement="outside"
|
|
|
|
|
className="w-full"
|
|
|
|
|
variant="bordered"
|
|
|
|
|
/>
|
|
|
|
|
)}
|
|
|
|
|
/>
|
|
|
|
|
{errors.code?.message && (
|
|
|
|
|
<p className="text-red-400 text-sm">{errors.code?.message}</p>
|
|
|
|
|
)}
|
|
|
|
|
<Controller
|
|
|
|
|
control={control}
|
|
|
|
|
name="name"
|
|
|
|
|
render={({ field: { onChange, value } }) => (
|
|
|
|
|
<Input
|
|
|
|
|
type="text"
|
|
|
|
|
id="name"
|
|
|
|
|
placeholder="Name..."
|
|
|
|
|
label="Name"
|
|
|
|
|
value={value}
|
|
|
|
|
onChange={onChange}
|
|
|
|
|
labelPlacement="outside"
|
|
|
|
|
className="w-full"
|
|
|
|
|
variant="bordered"
|
|
|
|
|
/>
|
|
|
|
|
)}
|
|
|
|
|
/>
|
|
|
|
|
{errors.name?.message && (
|
|
|
|
|
<p className="text-red-400 text-sm">{errors.name?.message}</p>
|
|
|
|
|
)}
|
|
|
|
|
<Controller
|
|
|
|
|
control={control}
|
|
|
|
|
name="description"
|
|
|
|
|
render={({ field: { onChange, value } }) => (
|
|
|
|
|
<Textarea
|
|
|
|
|
label="Description"
|
|
|
|
|
labelPlacement="outside"
|
|
|
|
|
placeholder="Enter Text"
|
|
|
|
|
value={value}
|
|
|
|
|
onValueChange={onChange}
|
|
|
|
|
/>
|
|
|
|
|
)}
|
|
|
|
|
/>
|
|
|
|
|
{errors.description?.message && (
|
|
|
|
|
<p className="text-red-400 text-sm">
|
|
|
|
|
{errors.description?.message}
|
|
|
|
|
</p>
|
|
|
|
|
)}
|
|
|
|
|
<Controller
|
|
|
|
|
control={control}
|
|
|
|
|
name="userLevelId"
|
|
|
|
|
render={({ field: { onChange, value } }) => (
|
|
|
|
|
<Input
|
|
|
|
|
type="number"
|
|
|
|
|
id="userLevelId"
|
|
|
|
|
placeholder="User Level..."
|
|
|
|
|
label="User Level"
|
|
|
|
|
value={value}
|
|
|
|
|
onChange={onChange}
|
|
|
|
|
labelPlacement="outside"
|
|
|
|
|
className="w-full"
|
|
|
|
|
variant="bordered"
|
|
|
|
|
/>
|
|
|
|
|
)}
|
|
|
|
|
/>
|
|
|
|
|
{errors.userLevelId?.message && (
|
|
|
|
|
<p className="text-red-400 text-sm">
|
|
|
|
|
{errors.userLevelId?.message}
|
|
|
|
|
</p>
|
|
|
|
|
)}
|
|
|
|
|
<p>Menus</p>
|
|
|
|
|
{fields.map((field, index) => (
|
|
|
|
|
<div key={field.menuId} className="flex flex-row gap-10">
|
|
|
|
|
<p>{field.menuTitle}</p>
|
|
|
|
|
<div className="grid grid-cols-6 gap-3">
|
|
|
|
|
{/* <Checkbox>Option</Checkbox> */}
|
|
|
|
|
<Controller
|
|
|
|
|
control={control}
|
|
|
|
|
name={`userRoleAccess.${index}.isAdminEnabled`}
|
|
|
|
|
render={({ field: { onChange, value } }) => (
|
|
|
|
|
<Checkbox isSelected={value} onValueChange={onChange}>
|
|
|
|
|
isAdminEnabled
|
|
|
|
|
</Checkbox>
|
|
|
|
|
)}
|
|
|
|
|
/>
|
|
|
|
|
<Controller
|
|
|
|
|
control={control}
|
|
|
|
|
name={`userRoleAccess.${index}.isApprovalEnabled`}
|
|
|
|
|
render={({ field: { onChange, value } }) => (
|
|
|
|
|
<Checkbox isSelected={value} onValueChange={onChange}>
|
|
|
|
|
isApprovalEnabled
|
|
|
|
|
</Checkbox>
|
|
|
|
|
)}
|
|
|
|
|
/>
|
|
|
|
|
<Controller
|
|
|
|
|
control={control}
|
|
|
|
|
name={`userRoleAccess.${index}.isDeleteEnabled`}
|
|
|
|
|
render={({ field: { onChange, value } }) => (
|
|
|
|
|
<Checkbox isSelected={value} onValueChange={onChange}>
|
|
|
|
|
isDeleteEnabled
|
|
|
|
|
</Checkbox>
|
|
|
|
|
)}
|
|
|
|
|
/>
|
|
|
|
|
<Controller
|
|
|
|
|
control={control}
|
|
|
|
|
name={`userRoleAccess.${index}.isInsertEnabled`}
|
|
|
|
|
render={({ field: { onChange, value } }) => (
|
|
|
|
|
<Checkbox isSelected={value} onValueChange={onChange}>
|
|
|
|
|
isInsertEnabled
|
|
|
|
|
</Checkbox>
|
|
|
|
|
)}
|
|
|
|
|
/>
|
|
|
|
|
<Controller
|
|
|
|
|
control={control}
|
|
|
|
|
name={`userRoleAccess.${index}.isUpdateEnabled`}
|
|
|
|
|
render={({ field: { onChange, value } }) => (
|
|
|
|
|
<Checkbox isSelected={value} onValueChange={onChange}>
|
|
|
|
|
isUpdateEnabled
|
|
|
|
|
</Checkbox>
|
|
|
|
|
)}
|
|
|
|
|
/>
|
|
|
|
|
<Controller
|
|
|
|
|
control={control}
|
|
|
|
|
name={`userRoleAccess.${index}.isViewEnabled`}
|
|
|
|
|
render={({ field: { onChange, value } }) => (
|
|
|
|
|
<Checkbox isSelected={value} onValueChange={onChange}>
|
|
|
|
|
isViewEnabled
|
|
|
|
|
</Checkbox>
|
|
|
|
|
)}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
))}
|
|
|
|
|
<div className="flex justify-end gap-3">
|
|
|
|
|
<Link href={`/admin/master-role`}>
|
|
|
|
|
<Button color="danger" variant="ghost">
|
|
|
|
|
Cancel
|
|
|
|
|
</Button>
|
|
|
|
|
</Link>
|
|
|
|
|
<Button type="submit" color="primary" variant="solid">
|
|
|
|
|
Save
|
|
|
|
|
</Button>
|
|
|
|
|
</div>
|
|
|
|
|
</Card>
|
|
|
|
|
</form>
|
|
|
|
|
</div>
|
|
|
|
|
);
|
2024-04-24 10:41:04 +00:00
|
|
|
}
|