From f1121afee6704dd1dfb7a5446428f3121513d602 Mon Sep 17 00:00:00 2001 From: lukman Date: Fri, 23 Aug 2024 14:12:01 +0800 Subject: [PATCH] style: update skelaton --- .../skeleton_detail_list_tugas_task.tsx | 60 ++++++++ src/module/_global/index.ts | 4 +- .../discussion/ui/detail_discussion.tsx | 71 +++++++-- src/module/discussion/ui/list_discussion.tsx | 119 ++++++++++----- .../division_new/ui/information_division.tsx | 38 ++++- src/module/division_new/ui/list_division.tsx | 136 ++++++++++------- .../division_new/ui/navbar_create_users.tsx | 78 ++++++---- src/module/task/ui/create_users_project.tsx | 106 ++++++++----- .../task/ui/detail_list_anggota_task.tsx | 12 +- src/module/task/ui/detail_list_file_task.tsx | 18 ++- src/module/task/ui/detail_list_tugas_task.tsx | 13 +- src/module/task/ui/detail_progress_task.tsx | 15 +- src/module/task/ui/list_division_task.tsx | 85 +++++++---- src/module/task/ui/navbar_division_task.tsx | 4 +- src/module/user/member/ui/create_member.tsx | 144 ++++++++++++++---- src/module/user/member/ui/edit_member.tsx | 131 +++++++++++++--- 16 files changed, 756 insertions(+), 278 deletions(-) create mode 100644 src/module/_global/components/skeleton_detail_list_tugas_task.tsx diff --git a/src/module/_global/components/skeleton_detail_list_tugas_task.tsx b/src/module/_global/components/skeleton_detail_list_tugas_task.tsx new file mode 100644 index 0000000..07e3fcd --- /dev/null +++ b/src/module/_global/components/skeleton_detail_list_tugas_task.tsx @@ -0,0 +1,60 @@ +import { Box, Center, Grid, Group, SimpleGrid, Skeleton } from '@mantine/core'; +import React from 'react'; + +export default function SkeletonDetailListTugasTask() { + return ( + + +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ ); +} diff --git a/src/module/_global/index.ts b/src/module/_global/index.ts index f0ed0b3..b1ffe41 100644 --- a/src/module/_global/index.ts +++ b/src/module/_global/index.ts @@ -2,6 +2,7 @@ import prisma from "./bin/prisma"; import { pwd_key_config } from "./bin/val_global"; import SkeletonDetailDiscussionComment from "./components/skeleton_detail_discussion_comment"; import SkeletonDetailDiscussionMember from "./components/skeleton_detail_discussion_member"; +import SkeletonDetailListTugasTask from "./components/skeleton_detail_list_tugas_task"; import SkeletonDetailProfile from "./components/skeleton_detail_profile"; import SkeletonSingle from "./components/skeleton_single"; import { funUploadFile } from "./fun/upload-file"; @@ -28,4 +29,5 @@ export { SkeletonSingle } export { SkeletonDetailDiscussionComment } export { SkeletonDetailDiscussionMember } export { funUploadFile } -export { SkeletonDetailProfile } \ No newline at end of file +export { SkeletonDetailProfile } +export {SkeletonDetailListTugasTask} \ No newline at end of file diff --git a/src/module/discussion/ui/detail_discussion.tsx b/src/module/discussion/ui/detail_discussion.tsx index 666df96..3d0789a 100644 --- a/src/module/discussion/ui/detail_discussion.tsx +++ b/src/module/discussion/ui/detail_discussion.tsx @@ -1,5 +1,5 @@ "use client" -import { ActionIcon, Avatar, Badge, Box, Center, Divider, Flex, Grid, Group, Text, TextInput } from "@mantine/core"; +import { ActionIcon, Avatar, Badge, Box, Center, Divider, Flex, Grid, Group, Skeleton, Text, TextInput } from "@mantine/core"; import { SkeletonDetailDiscussionComment, SkeletonDetailDiscussionMember, SkeletonSingle, WARNA } from "@/module/_global"; import { GrChatOption } from "react-icons/gr"; import { LuSendHorizonal } from "react-icons/lu"; @@ -17,7 +17,7 @@ export default function DetailDiscussion({ id, idDivision }: { id: string, idDiv const [isData, setData] = useState() const [isComent, setIsComent] = useState("") const param = useParams<{ id: string, detail: string }>() - const [isLoad, setIsLoad] = useState(false) + const [isLoad, setIsLoad] = useState(true) const getData = async () => { try { @@ -67,8 +67,26 @@ export default function DetailDiscussion({ id, idDivision }: { id: string, idDiv Array(1) .fill(null) .map((_, i) => ( - - + + + + + + + + + + + + + + + + )) : @@ -104,11 +122,35 @@ export default function DetailDiscussion({ id, idDivision }: { id: string, idDiv } {isLoad ? - Array(6) + Array(2) .fill(0) .map((_, i) => ( - + + + + + + + + + + + + + + + + + + + + + )) : isData?.DivisionDisscussionComment.map((v, i) => { @@ -137,14 +179,20 @@ export default function DetailDiscussion({ id, idDivision }: { id: string, idDiv }) } - + : + + + {300 - isComent.length} karakter tersisa + - + setIsComent(e.target.value)} - value={isComent} - /> + value={isComent} + maxLength={300} + /> +
@@ -171,6 +221,7 @@ export default function DetailDiscussion({ id, idDivision }: { id: string, idDiv + } ) diff --git a/src/module/discussion/ui/list_discussion.tsx b/src/module/discussion/ui/list_discussion.tsx index 70226c7..d02fb88 100644 --- a/src/module/discussion/ui/list_discussion.tsx +++ b/src/module/discussion/ui/list_discussion.tsx @@ -1,6 +1,6 @@ 'use client' import { WARNA } from "@/module/_global"; -import { Avatar, Badge, Box, Divider, Flex, Group, Text, TextInput } from "@mantine/core"; +import { Avatar, Badge, Box, Divider, Flex, Group, Skeleton, Text, TextInput } from "@mantine/core"; import { useParams, useRouter, useSearchParams } from "next/navigation"; import { useState } from "react"; import { GrChatOption } from "react-icons/gr"; @@ -13,13 +13,18 @@ export default function ListDiscussion({ id }: { id: string }) { const [isData, setData] = useState([]) const [searchQuery, setSearchQuery] = useState('') const param = useParams<{ id: string }>() + const [loading, setLoading] = useState(true) const getData = async () => { try { + setLoading(true) const response = await funGetAllDiscussion('?division=' + id + '&search=' + searchQuery) setData(response.data) + setLoading(false) } catch (error) { console.log(error) + } finally { + setLoading(false) } } @@ -45,45 +50,83 @@ export default function ListDiscussion({ id }: { id: string }) { value={searchQuery} onChange={(e) => setSearchQuery(e.target.value)} /> - {isData.map((v, i) => { - return ( - { - router.push(`/division/${param.id}/discussion/${v.id}`) - }} - > - - - - - - {v.user_name} - - {v.status === 1 ? "BUKA" : "TUTUP"} + {loading ? + Array(3) + .fill(null) + .map((_, i) => ( + + + + + + + + + + + + + + - - {v.createdAt} - - {v.desc} - - - - Diskusikan - - - {v.total_komentar} Komentar - - - - + + + + + + + + - - ); - })} + )) + : + isData.map((v, i) => { + return ( + { + router.push(`/division/${param.id}/discussion/${v.id}`) + }} + > + + + + + + {v.user_name} + + {v.status === 1 ? "BUKA" : "TUTUP"} + + + {v.createdAt} + + {v.desc} + + + + Diskusikan + + + {v.total_komentar} Komentar + + + + {isData.length <= 1 ? "" : + + } + + + ); + }) + } + ) } \ No newline at end of file diff --git a/src/module/division_new/ui/information_division.tsx b/src/module/division_new/ui/information_division.tsx index a08338a..6a327b8 100644 --- a/src/module/division_new/ui/information_division.tsx +++ b/src/module/division_new/ui/information_division.tsx @@ -21,7 +21,7 @@ export default function InformationDivision() { const [name, setName] = useState('') const [deskripsi, setDeskripsi] = useState('') const [member, setMember] = useState([]) - const [loading, setLoading] = useState(false) + const [loading, setLoading] = useState(true) const [valChooseMember, setChooseMember] = useState("") const [valChooseMemberStatus, setChooseMemberStatus] = useState(false) const [valChooseMemberName, setChooseMemberName] = useState("") @@ -137,12 +137,36 @@ export default function InformationDivision() { {member.length} Anggota - router.push('/division/add-member/' + param.id)}> - - - - Tambah Anggota - + {loading ? + + + + + + + + + + + : + router.push('/division/add-member/' + param.id)}> + + + + Tambah Anggota + + } diff --git a/src/module/division_new/ui/list_division.tsx b/src/module/division_new/ui/list_division.tsx index 8e8a66b..1a40c3d 100644 --- a/src/module/division_new/ui/list_division.tsx +++ b/src/module/division_new/ui/list_division.tsx @@ -1,5 +1,5 @@ 'use client' -import { LayoutDrawer, LayoutNavbarNew, WARNA } from '@/module/_global'; +import { LayoutDrawer, LayoutNavbarNew, SkeletonSingle, WARNA } from '@/module/_global'; import { ActionIcon, Avatar, Box, Card, Center, Divider, Flex, Grid, Group, Skeleton, Text, TextInput, Title } from '@mantine/core'; import { useRouter, useSearchParams } from 'next/navigation'; import React, { useState } from 'react'; @@ -95,72 +95,98 @@ export default function ListDivision() { - + + {loading ? + <> + + + : Total Divisi {jumlah} - + } + {isList ? ( - {data?.map((v: any, i: any) => { - return ( - - router.push(`/division/${v.id}`)}> - -
- - - -
- {v.name} + {loading + ? Array(6) + .fill(null) + .map((_, i) => ( + + + + )) + : + data?.map((v: any, i: any) => { + return ( + + router.push(`/division/${v.id}`)}> + +
+ + + +
+ {v.name} +
-
- -
- ); - })} + +
+ ); + }) + }
) : ( - - {data?.map((v: any, i: any) => { - return ( - - router.push(`/division/${v.id}`)}> - - - - {v.name} - + + {loading ? + Array(6) + .fill(null) + .map((_, i) => ( + + + + )) + : + data?.map((v: any, i: any) => { + return ( + + router.push(`/division/${v.id}`)}> + + + + {v.name} + + + + + {v.desc} + + + + + + +{v.jumlah_member - 1} + + - - - {v.desc} - - - - - - +{v.jumlah_member - 1} - - - - - - ); - })} + + + ); + }) + }
)} diff --git a/src/module/division_new/ui/navbar_create_users.tsx b/src/module/division_new/ui/navbar_create_users.tsx index d2bbc15..3969394 100644 --- a/src/module/division_new/ui/navbar_create_users.tsx +++ b/src/module/division_new/ui/navbar_create_users.tsx @@ -1,7 +1,7 @@ "use client" import { LayoutNavbarNew, WARNA } from '@/module/_global'; import { useHookstate } from '@hookstate/core'; -import { Avatar, Box, Button, Center, Input, SimpleGrid, Stack, Text, TextInput } from '@mantine/core'; +import { Avatar, Box, Button, Center, Input, SimpleGrid, Skeleton, Stack, Text, TextInput } from '@mantine/core'; import { useShallowEffect } from '@mantine/hooks'; import { useRouter } from 'next/navigation'; import React, { useState } from 'react'; @@ -17,6 +17,7 @@ export default function NavbarCreateUsers({ grup, onClose }: { grup?: string, on const member = useHookstate(globalMemberDivision) const [selectedFiles, setSelectedFiles] = useState([]); const [dataMember, setDataMember] = useState([]) + const [loading, setLoading] = useState(true) const handleFileClick = (index: number) => { if (selectedFiles.some((i: any) => i.idUser == dataMember[index].id)) { @@ -28,6 +29,7 @@ export default function NavbarCreateUsers({ grup, onClose }: { grup?: string, on async function loadData(search: string) { + setLoading(true) const res = await funGetAllmember('?active=true&group=' + grup + '&search=' + search); const user = await funGetUserByCookies(); @@ -41,7 +43,7 @@ export default function NavbarCreateUsers({ grup, onClose }: { grup?: string, on } else { toast.error(res.message) } - + setLoading(false) } @@ -77,35 +79,51 @@ export default function NavbarCreateUsers({ grup, onClose }: { grup?: string, on onChange={(e) => loadData(e.target.value)} /> - - {dataMember.map((v, index) => { - const isSelected = selectedFiles.some((i: any) => i.idUser == dataMember[index].id); - return ( - - handleFileClick(index)} - > -
- -
- - {v.name} - + {loading ? + + {Array(6) + .fill(null) + .map((_, i) => ( + + -
- ); - })} -
+ ))} + + : + + {dataMember.map((v, index) => { + const isSelected = selectedFiles.some((i: any) => i.idUser == dataMember[index].id); + return ( + + handleFileClick(index)} + > +
+ +
+ + {v.name} + +
+
+ ); + })} +
+ }
diff --git a/src/module/task/ui/create_users_project.tsx b/src/module/task/ui/create_users_project.tsx index 57bf146..7f9d3bd 100644 --- a/src/module/task/ui/create_users_project.tsx +++ b/src/module/task/ui/create_users_project.tsx @@ -3,6 +3,7 @@ import { LayoutNavbarNew, WARNA } from "@/module/_global"; import { funGetDivisionById, IDataMemberDivision } from "@/module/division_new"; import { useHookstate } from "@hookstate/core"; import { + ActionIcon, Anchor, Avatar, Box, @@ -11,6 +12,7 @@ import { Divider, Flex, Group, + Skeleton, Text, TextInput, } from "@mantine/core"; @@ -28,10 +30,12 @@ export default function CreateUsersProject({ onClose }: { onClose: (val: any) => const [isData, setData] = useState([]) const member = useHookstate(globalMemberTask) const [selectAll, setSelectAll] = useState(false) + const [loading, setLoading] = useState(true) async function getData() { try { + setLoading(true) const response = await funGetDivisionById(param.id) if (response.success) { setData(response.data.member) @@ -41,9 +45,12 @@ export default function CreateUsersProject({ onClose }: { onClose: (val: any) => } else { toast.error(response.message) } + setLoading(false) } catch (error) { console.log(error) toast.error("Gagal mendapatkan anggota, coba lagi nanti"); + } finally { + setLoading(false) } } @@ -110,43 +117,72 @@ export default function CreateUsersProject({ onClose }: { onClose: (val: any) => leftSection={} placeholder="Pencarian" /> */} - - - Pilih Semua Anggota - - {selectAll ? : ""} - + {loading ? + + : + + + Pilih Semua Anggota + + {selectAll ? : ""} + + } - {isData.map((v, i) => { - const isSelected = selectedFiles.some((i: any) => i?.idUser == v.idUser); - return ( - handleFileClick(i)}> - + {loading ? + Array(3) + .fill(null) + .map((_, i) => ( + - - - {v.name} - + + + + + + + + - - {isSelected ? : ""} - - - - - ); - })} + + )) + : + isData.map((v, i) => { + const isSelected = selectedFiles.some((i: any) => i?.idUser == v.idUser); + return ( + handleFileClick(i)}> + + + + + {v.name} + + + + {isSelected ? : ""} + + + + + ); + }) + } diff --git a/src/module/task/ui/detail_list_anggota_task.tsx b/src/module/task/ui/detail_list_anggota_task.tsx index d31accc..9ddba9f 100644 --- a/src/module/task/ui/detail_list_anggota_task.tsx +++ b/src/module/task/ui/detail_list_anggota_task.tsx @@ -1,5 +1,5 @@ 'use client' -import { LayoutDrawer, WARNA } from "@/module/_global"; +import { LayoutDrawer, SkeletonSingle, WARNA } from "@/module/_global"; import { Box, Group, Flex, Avatar, Text, SimpleGrid, Stack } from "@mantine/core"; import { useShallowEffect } from "@mantine/hooks"; import { useParams, useRouter } from "next/navigation"; @@ -79,7 +79,15 @@ export default function ListAnggotaDetailTask() { py={10} > { - loading ? loading : + loading ? + Array(6) + .fill(null) + .map((_, i) => ( + + + + )) + : isData.length === 0 ? Tidak ada anggota : isData.map((v, i) => { return ( diff --git a/src/module/task/ui/detail_list_file_task.tsx b/src/module/task/ui/detail_list_file_task.tsx index 7873acf..937d0f3 100644 --- a/src/module/task/ui/detail_list_file_task.tsx +++ b/src/module/task/ui/detail_list_file_task.tsx @@ -1,6 +1,6 @@ 'use client' -import { WARNA } from "@/module/_global"; -import { Box, Group, Text } from "@mantine/core"; +import { SkeletonDetailListTugasTask, WARNA } from "@/module/_global"; +import { Box, Group, Skeleton, Text } from "@mantine/core"; import { useShallowEffect } from "@mantine/hooks"; import { useParams } from "next/navigation"; import { useState } from "react"; @@ -22,7 +22,6 @@ export default function ListFileDetailTask() { } else { toast.error(res.message); } - } catch (error) { console.error(error); toast.error("Gagal mendapatkan file tugas divisi, coba lagi nanti"); @@ -45,7 +44,18 @@ export default function ListFileDetailTask() { }}> { - loading ? loading : + loading ? + Array(1) + .fill(null) + .map((_, i) => ( + + + + + + + )) + : isData.length === 0 ? Tidak ada file : isData.map((item, index) => { return ( diff --git a/src/module/task/ui/detail_list_tugas_task.tsx b/src/module/task/ui/detail_list_tugas_task.tsx index 5582e23..cbcc855 100644 --- a/src/module/task/ui/detail_list_tugas_task.tsx +++ b/src/module/task/ui/detail_list_tugas_task.tsx @@ -1,5 +1,5 @@ 'use client' -import { LayoutDrawer, WARNA } from "@/module/_global" +import { LayoutDrawer, SkeletonDetailListTugasTask, WARNA } from "@/module/_global" import { Box, Grid, Center, Checkbox, Group, SimpleGrid, Text, Stack, Flex, Divider } from "@mantine/core" import { useShallowEffect } from "@mantine/hooks" import { useParams, useRouter } from "next/navigation" @@ -99,7 +99,11 @@ export default function ListTugasDetailTask() { }} > { - loading ? loading : + loading ? + <> + + + : isData.length === 0 ? Tidak ada tugas : isData.map((item, index) => { return ( @@ -163,7 +167,10 @@ export default function ListTugasDetailTask() { - + {isData.length >= 1 + ? "" : + + } ) }) diff --git a/src/module/task/ui/detail_progress_task.tsx b/src/module/task/ui/detail_progress_task.tsx index af14cbb..42656f8 100644 --- a/src/module/task/ui/detail_progress_task.tsx +++ b/src/module/task/ui/detail_progress_task.tsx @@ -1,6 +1,6 @@ 'use client' import { WARNA } from "@/module/_global"; -import { Box, Grid, ActionIcon, Progress, Text } from "@mantine/core"; +import { Box, Grid, ActionIcon, Progress, Text, Skeleton } from "@mantine/core"; import { useShallowEffect } from "@mantine/hooks"; import { useParams } from "next/navigation"; import toast from "react-hot-toast"; @@ -15,9 +15,11 @@ export default function ProgressDetailTask() { const [valLastUpdate, setValLastUpdate] = useState('') const param = useParams<{ id: string, detail: string }>() const refresh = useHookstate(globalRefreshTask) + const [loading, setLoading] = useState(true) async function getOneData() { try { + setLoading(true) const res = await funGetTaskDivisionById(param.detail, 'progress'); if (res.success) { setValProgress(res.data.progress); @@ -25,10 +27,12 @@ export default function ProgressDetailTask() { } else { toast.error(res.message); } - + setLoading(false) } catch (error) { console.error(error); toast.error("Gagal mendapatkan progress tugas divisi, coba lagi nanti"); + } finally { + setLoading(false) } } @@ -39,7 +43,7 @@ export default function ProgressDetailTask() { } } - + useEffect(() => { onRefresh() @@ -51,6 +55,9 @@ export default function ProgressDetailTask() { return ( + {loading ? + + : - {/* Update terakhir : {valLastUpdate} */} + } ) } \ No newline at end of file diff --git a/src/module/task/ui/list_division_task.tsx b/src/module/task/ui/list_division_task.tsx index 2b3541e..16f6fdf 100644 --- a/src/module/task/ui/list_division_task.tsx +++ b/src/module/task/ui/list_division_task.tsx @@ -1,5 +1,5 @@ import { WARNA } from "@/module/_global"; -import { ActionIcon, Avatar, Badge, Box, Card, Center, Divider, Flex, Grid, Group, Progress, Text, TextInput, Title } from "@mantine/core"; +import { ActionIcon, Avatar, Badge, Box, Card, Center, Divider, Flex, Grid, Group, Progress, Skeleton, Text, TextInput, Title } from "@mantine/core"; import { useParams, useRouter, useSearchParams } from "next/navigation"; import { useState } from "react"; import { HiMagnifyingGlass, HiMiniPresentationChartBar, HiOutlineListBullet, HiSquares2X2 } from "react-icons/hi2"; @@ -8,6 +8,7 @@ import { IDataTask } from "../lib/type_task"; import { funGetAllTask } from "../lib/api_task"; import toast from "react-hot-toast"; import { useShallowEffect } from "@mantine/hooks"; +import _ from "lodash"; export default function ListDivisionTask() { const [isList, setIsList] = useState(false) @@ -79,12 +80,18 @@ export default function ListDivisionTask() { + {loading ? + + + + : Total Proyek {isData.length} + } {isList ? ( {isData.map((v, i) => { @@ -117,37 +124,53 @@ export default function ListDivisionTask() { ) : ( - {isData.map((v: any, i: any) => { - return ( - - router.push(`task/${v.id}`)}> - - - - {v.title} - - - - - - - {v.progress}% - - - {v.desc} - - - - - - +{v.member-1} - - - - + {loading ? + Array(3) + .fill(null) + .map((_, i) => ( + + + + )) + : + _.isEmpty(isData) + ? + + Tidak ada Tugas - ); - })} + : + isData.map((v: any, i: any) => { + return ( + + router.push(`task/${v.id}`)}> + + + + {v.title} + + + + + + + {v.progress}% + + + {v.desc} + + + + + + +{v.member - 1} + + + + + + ); + }) + } )} diff --git a/src/module/task/ui/navbar_division_task.tsx b/src/module/task/ui/navbar_division_task.tsx index 1892491..1fbcbe4 100644 --- a/src/module/task/ui/navbar_division_task.tsx +++ b/src/module/task/ui/navbar_division_task.tsx @@ -4,12 +4,14 @@ import { ActionIcon } from "@mantine/core"; import { useState } from "react"; import { HiMenu } from "react-icons/hi"; import DrawerDivisionTask from "./drawer_division_task"; +import { useParams } from "next/navigation"; export default function NavbarDivisionTask() { const [openDrawer, setOpenDrawer] = useState(false) + const param = useParams<{ id: string}>() return ( <> - setOpenDrawer(true)} bg={WARNA.bgIcon} size="lg" radius="lg" aria-label="Settings"> diff --git a/src/module/user/member/ui/create_member.tsx b/src/module/user/member/ui/create_member.tsx index 72c8517..41e71b8 100644 --- a/src/module/user/member/ui/create_member.tsx +++ b/src/module/user/member/ui/create_member.tsx @@ -10,6 +10,7 @@ import { HiUser } from "react-icons/hi2"; import { IDataPositionMember, IDataROleMember } from "../lib/type_member"; import { funGetAllPosition } from "@/module/position/lib/api_position"; import { funCreateMember, funGetRoleUser } from "../lib/api_member"; +import _ from "lodash"; export default function CreateMember() { const router = useRouter(); @@ -17,6 +18,16 @@ export default function CreateMember() { const [listGroup, setListGorup] = useState([]); const [listPosition, setListPosition] = useState([]); const [listUserRole, setListUserRole] = useState([]); + const [touched, setTouched] = useState({ + nik: false, + name: false, + phone: false, + email: false, + gender: false, + idGroup: false, + idPosition: false, + idUserRole: false + }); const [listData, setListData] = useState({ nik: "", @@ -80,24 +91,29 @@ export default function CreateMember() { async function onSubmit(val: boolean) { try { - const res = await funCreateMember({ - nik: listData.nik, - name: listData.name, - phone: listData.phone, - email: listData.email, - gender: listData.gender, - idGroup: listData.idGroup, - idPosition: listData.idPosition, - idUserRole: listData.idUserRole, - }); - - if (res.success) { - toast.success(res.message); - setModal(false); - router.push("/member?active=true"); - } else { - toast.error(res.message); + if (_.isEmpty(listData)) { + return; } + if (val) { + const res = await funCreateMember({ + nik: listData.nik, + name: listData.name, + phone: listData.phone, + email: listData.email, + gender: listData.gender, + idGroup: listData.idGroup, + idPosition: listData.idPosition, + idUserRole: listData.idUserRole, + }); + if (res.success) { + toast.success(res.message); + setModal(false); + router.push("/member?active=true"); + } else { + toast.error(res.message); + } + } + setModal(false); } catch (error) { toast.error("Error"); } finally { @@ -142,14 +158,20 @@ export default function CreateMember() { data={ listGroup ? listGroup.map((data) => ({ - value: data.id, - label: data.name, - })) + value: data.id, + label: data.name, + })) : [] } onChange={(val: any) => { changeGrup(val); }} + onBlur={() => setTouched({ ...touched, idGroup: true })} + error={ + touched.idGroup && ( + listData.idGroup == "" ? "Grup Tidak Boleh Kosong" : null + ) + } /> ({ - value: data.id, - label: data.name, - })) + value: data.id, + label: data.name, + })) : [] } onChange={(val: any) => @@ -211,6 +239,12 @@ export default function CreateMember() { idUserRole: val, }) } + onBlur={() => setTouched({ ...touched, idUserRole: true })} + error={ + touched.idUserRole && ( + listData.idUserRole == "" ? "Role Tidak Boleh Kosong" : null + ) + } /> - setListData({ - ...listData, - nik: event.target.value, - }) + onChange={(event: any) => { + setListData({ ...listData, nik: event.target.value }); + setTouched({ ...touched, nik: true }); + }} + onBlur={() => setTouched({ ...touched, nik: true })} + error={ + touched.nik && ( + listData.nik == "" ? "NIK Tidak Boleh Kosong" : + listData.nik.length < 16 ? "NIK Harus 16 Karakter" : null + ) } /> setTouched({ ...touched, name: true })} + error={ + touched.name && ( + listData.name == "" ? "Nama Tidak Boleh Kosong" : null + ) + } /> setTouched({ ...touched, email: true })} + error={ + touched.email && ( + listData.email == "" ? "Email Tidak Boleh Kosong" : + !/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/.test(listData.email) ? "Email tidak valid" : null + ) + } /> setTouched({ ...touched, phone: true })} + error={ + touched.phone && ( + listData.phone == "" ? "Nomor Telepon Tidak Boleh Kosong" : + listData.phone.length < 10 ? "Nomor Telepon harus 10 digit" : null + ) + } /> setData({ ...data, idPosition: val })} value={(data?.idPosition == "") ? null : data.idPosition} + onBlur={() => setTouched({ ...touched, idPosition: true })} + error={ + touched.idPosition && ( + data.idPosition == "" ? "Jabatan Tidak Boleh Kosong" : null + ) + } /> setData({ ...data, gender: val })} value={data.gender} + onBlur={() => setTouched({ ...touched, gender: true })} + error={ + touched.gender && ( + data.gender == "" ? "Gender Tidak Boleh Kosong" : null + ) + } /> - + setModal(false)} description="Apakah Anda yakin ingin mengubah data?"