fix:create user, create role form

This commit is contained in:
Rama Priyanto 2024-12-04 09:35:29 +07:00
parent 24d27df67e
commit 0d04ea0b14
3 changed files with 381 additions and 176 deletions

View File

@ -1,10 +1,10 @@
import FormMasterUserRole from '@/components/form/form-master-user-role'
import { Card } from '@nextui-org/react'
import FormMasterUserRole from "@/components/form/form-master-user-role";
import { Card } from "@nextui-org/react";
export default function CreateMasterUserRolePage() {
return (
<Card className="h-[96vh] rounded-md my- ml-3 border bg-transparent">
<Card className="h-[96vh] rounded-md border bg-transparent">
<FormMasterUserRole />
</Card>
)
);
}

View File

@ -1,51 +1,107 @@
'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';
"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,
Checkbox,
Input,
Radio,
RadioGroup,
Select,
SelectItem,
Selection,
Textarea,
} from "@nextui-org/react";
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";
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" }),
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(),
})
),
});
const menus = [{ id: 1, title: "Menu 1" }];
export default function FormMasterUserRole() {
const router = useRouter();
const MySwal = withReactContent(Swal);
const [code, setCode] = useState<string>();
const [description, setDescription] = useState<string>();
const [levelNumber, setLevelNumber] = useState<any>(1);
const [name, setName] = useState<string>();
const formOptions = { resolver: zodResolver(masterUserSchema) };
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",
});
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,
});
});
setValue("userRoleAccess", data);
}, []);
async function save(data: any) {
async function save(data: z.infer<typeof masterUserSchema>) {
const formData = {
code: code,
description: description,
level_number: levelNumber,
name: name,
code: data.code,
description: data.description,
statusId: 1,
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,
menuId: roleAccess.menuId,
};
}),
};
console.log("Form MasterUser:", formData);
@ -57,7 +113,7 @@ export default function FormMasterUserRole() {
}
successSubmit("/admin/master-role");
};
}
function successSubmit(redirect: any) {
MySwal.fire({
@ -72,7 +128,7 @@ export default function FormMasterUserRole() {
});
}
async function onSubmit(data: any) {
async function onSubmit(data: z.infer<typeof masterUserSchema>) {
MySwal.fire({
title: "Simpan Data",
text: "",
@ -89,76 +145,164 @@ export default function FormMasterUserRole() {
}
return (
<div className='mx-5 my-5 overflow-y-auto'>
<div className="mx-5 my-5 overflow-y-auto">
<form method="POST" onSubmit={handleSubmit(onSubmit)}>
<Card className='rounded-md p-5 space-y-5'>
<div>
<Card className="rounded-md flex flex-col gap-3 p-5">
<Controller
control={control}
name="code"
render={({ field: { onChange, value } }) => (
<Input
type="text"
{...register("code")}
id="code"
placeholder="Code..."
label="Code"
variant='bordered'
placeholder="Enter Text"
labelPlacement='outside'
value={code}
onChange={(e) => setCode(e.target.value)}
value={value}
onChange={onChange}
labelPlacement="outside"
className="w-full"
variant="bordered"
/>
{errors.code?.message}
</div>
<div>
)}
/>
{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"
{...register("name")}
label="Role"
variant='bordered'
placeholder="Enter Text"
labelPlacement='outside'
value={name}
onChange={(e) => setName(e.target.value)}
id="name"
placeholder="Name..."
label="Name"
value={value}
onChange={onChange}
labelPlacement="outside"
className="w-full"
variant="bordered"
/>
{errors.name?.message}
</div>
<div>
)}
/>
{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"
{...register("description")}
labelPlacement="outside"
placeholder="Enter Text"
value={description}
onValueChange={setDescription}
value={value}
onValueChange={onChange}
/>
</div>
<div>
)}
/>
{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="text"
{...register("levelNumber")}
label="Level Number"
variant='bordered'
placeholder="Enter Text"
labelPlacement='outside'
value={levelNumber}
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>
)}
/>
{errors.code?.message}
</div>
<div className='flex justify-end gap-3'>
</div>
))}
<div className="flex justify-end gap-3">
<Link href={`/admin/master-role`}>
<Button
color='danger'
variant="ghost"
>
<Button color="danger" variant="ghost">
Cancel
</Button>
</Link>
<Button
type="submit"
color='primary'
variant="solid"
>
<Button type="submit" color="primary" variant="solid">
Save
</Button>
</div>
</Card>
</form>
</div >
)
</div>
);
}

View File

@ -27,7 +27,20 @@ import { EyeFilledIcon, EyeSlashFilledIcon } from "../icons";
const masterUserSchema = z.object({
fullname: z.string().min(1, { message: "Required" }),
username: z.string().min(1, { message: "Required" }),
password: z.string().min(1, { message: "Required" }),
password: z
.string()
.min(8, "Password harus memiliki minimal 8 karakter.")
.refine((password) => /[A-Z]/.test(password), {
message: "Password harus memiliki minimal satu huruf kapital.",
})
.refine((password) => /[0-9]/.test(password), {
message: "Password harus memiliki minimal satu angka.",
})
.refine((password) => /[!@#$%^&*(),.?":{}|<>]/.test(password), {
message: "Password harus memiliki minimal satu simbol.",
}),
passwordValidate: z.string().min(1, { message: "Required" }),
email: z.string().min(1, { message: "Required" }),
identityType: z.string().min(1, { message: "Required" }),
identityNumber: z.string().min(1, { message: "Required" }),
@ -114,8 +127,12 @@ const educationGrade = [
export default function FormMasterUser() {
const router = useRouter();
const MySwal = withReactContent(Swal);
const [isVisible, setIsVisible] = useState(false);
const toggleVisibility = () => setIsVisible(!isVisible);
const [isVisible, setIsVisible] = useState([false, false]);
const toggleVisibility = (type: number) => {
setIsVisible(
type === 0 ? [!isVisible[0], isVisible[1]] : [isVisible[0], !isVisible[1]]
);
};
const formOptions = {
resolver: zodResolver(masterUserSchema),
@ -129,6 +146,7 @@ export default function FormMasterUser() {
control,
handleSubmit,
formState: { errors },
setError,
} = useForm<MicroIssueSchema>(formOptions);
async function save(data: z.infer<typeof masterUserSchema>) {
@ -173,6 +191,7 @@ export default function FormMasterUser() {
}
async function onSubmit(data: z.infer<typeof masterUserSchema>) {
if (data.password === data.passwordValidate) {
MySwal.fire({
title: "Simpan Data",
text: "",
@ -186,6 +205,12 @@ export default function FormMasterUser() {
save(data);
}
});
} else {
setError("passwordValidate", {
type: "manual",
message: "Password harus sama.",
});
}
}
return (
@ -237,7 +262,7 @@ export default function FormMasterUser() {
name="password"
render={({ field: { onChange, value } }) => (
<Input
type={isVisible ? "text" : "password"}
type={isVisible[0] ? "text" : "password"}
id="password"
placeholder="Password..."
label="Password"
@ -250,9 +275,9 @@ export default function FormMasterUser() {
<button
className="focus:outline-none"
type="button"
onClick={toggleVisibility}
onClick={() => toggleVisibility(0)}
>
{isVisible ? (
{isVisible[0] ? (
<EyeSlashFilledIcon className="text-2xl text-default-400 pointer-events-none" />
) : (
<EyeFilledIcon className="text-2xl text-default-400 pointer-events-none" />
@ -265,6 +290,42 @@ export default function FormMasterUser() {
{errors.password?.message && (
<p className="text-red-400 text-sm">{errors.password?.message}</p>
)}
<Controller
control={control}
name="passwordValidate"
render={({ field: { onChange, value } }) => (
<Input
type={isVisible[1] ? "text" : "password"}
id="passwordValidate"
placeholder="Confirm Password..."
label="Confirm Password"
value={value}
onChange={onChange}
labelPlacement="outside"
className="w-full"
variant="bordered"
endContent={
<button
className="focus:outline-none"
type="button"
onClick={() => toggleVisibility(1)}
>
{isVisible[1] ? (
<EyeSlashFilledIcon className="text-2xl text-default-400 pointer-events-none" />
) : (
<EyeFilledIcon className="text-2xl text-default-400 pointer-events-none" />
)}
</button>
}
/>
)}
/>
{errors.passwordValidate?.message && (
<p className="text-red-400 text-sm">
{errors.passwordValidate?.message}
</p>
)}
<Controller
control={control}
name="email"
@ -343,8 +404,8 @@ export default function FormMasterUser() {
value={value}
onValueChange={onChange}
>
<Radio value="male">Laki-laki</Radio>
<Radio value="female">Perempuan</Radio>
<Radio value="Male">Laki-laki</Radio>
<Radio value="Female">Perempuan</Radio>
</RadioGroup>
)}
/>