diff --git a/src/app/api/calender/[id]/member/route.ts b/src/app/api/calender/[id]/member/route.ts new file mode 100644 index 0000000..69ceb7f --- /dev/null +++ b/src/app/api/calender/[id]/member/route.ts @@ -0,0 +1,57 @@ +import { prisma } from "@/module/_global"; +import { funGetUserByCookies } from "@/module/auth"; +import { createLogUser } from "@/module/user"; +import _ from "lodash"; +import { NextResponse } from "next/server"; + +// TAMBAH MEMBER KALENDER +export async function POST(request: Request, context: { params: { id: string } }) { + try { + const user = await funGetUserByCookies() + if (user.id == undefined) { + return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 401 }); + } + + const { id } = context.params + const member = await request.json() + + const cek = await prisma.divisionCalendar.count({ + where: { + id: id + } + }) + + if (cek == 0) { + return NextResponse.json( + { + success: false, + message: "Gagal menambahkan anggota, data tidak ditemukan", + }, + { status: 404 } + ); + } + + + if (member.length > 0) { + const dataMember = member.map((v: any) => ({ + ..._.omit(v, ["idUser", "name", "img"]), + idCalendar: id, + idUser: v.idUser, + })) + + const insertMember = await prisma.divisionCalendarMember.createMany({ + data: dataMember + }) + } + + // create log user + const log = await createLogUser({ act: 'CREATE', desc: 'User menambah anggota kalender', table: 'divisionCalendar', data: String(id) }) + + return NextResponse.json({ success: true, message: "Berhasil menambahkan anggota", }, { status: 200 }); + } catch (error) { + console.error(error); + return NextResponse.json({ success: false, message: "Gagal menambah anggota, coba lagi nanti", reason: (error as Error).message, }, { status: 500 }); + } + + +} \ No newline at end of file diff --git a/src/module/calender/lib/api_calender.ts b/src/module/calender/lib/api_calender.ts index 063ac84..77b5e5f 100644 --- a/src/module/calender/lib/api_calender.ts +++ b/src/module/calender/lib/api_calender.ts @@ -1,4 +1,4 @@ -import { IEditCalender, IFormCreateCalender } from "./type_calender"; +import { IEditCalender, IFormCreateCalender, IFormMemberCalenderNew } from "./type_calender"; export const funGetAllCalender = async (path?: string) => { const response = await fetch(`/api/calender${(path) ? path : ''}`, { next: { tags: ['calender'] } }); @@ -47,4 +47,15 @@ export const funEditCalenderById = async (path: string, data: IEditCalender) => export const funGetIndicatorCalender = async (path?: string) => { const response = await fetch(`/api/calender/indicator${(path) ? path : ''}`, { next: { tags: ['hostory'] } }); return await response.json().catch(() => null); -} \ No newline at end of file +} + +export const funAddMemberCalender = async (path: string, data: IFormMemberCalenderNew) => { + const response = await fetch(`/api/calender/${path}/member`, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify(data), + }); + return await response.json().catch(() => null); +}; \ No newline at end of file diff --git a/src/module/calender/lib/type_calender.ts b/src/module/calender/lib/type_calender.ts index ce281e6..902b44c 100644 --- a/src/module/calender/lib/type_calender.ts +++ b/src/module/calender/lib/type_calender.ts @@ -93,4 +93,9 @@ export interface IDetailByIdCalender { createdAt?: string linkMeet?: string repeatEventTyper?: string +} + +export interface IFormMemberCalenderNew { + idUser: string + name: string } \ No newline at end of file diff --git a/src/module/calender/ui/create_user_detail_calender.tsx b/src/module/calender/ui/create_user_detail_calender.tsx index e749827..e577416 100644 --- a/src/module/calender/ui/create_user_detail_calender.tsx +++ b/src/module/calender/ui/create_user_detail_calender.tsx @@ -1,9 +1,7 @@ "use client" import React, { useState } from 'react'; -import { globalCalender } from '../lib/val_calender'; import { useParams, useRouter } from 'next/navigation'; -import { funGetDivisionById, funGetSearchMemberDivision, IDataMemberDivision } from '@/module/division_new'; -import { useHookstate } from '@hookstate/core'; +import { funGetSearchMemberDivision, IDataMemberDivision } from '@/module/division_new'; import toast from 'react-hot-toast'; import { useShallowEffect } from '@mantine/hooks'; import { LayoutNavbarNew, SkeletonSingle, WARNA } from '@/module/_global'; @@ -12,13 +10,15 @@ import { FaCheck } from 'react-icons/fa6'; import { HiMagnifyingGlass } from 'react-icons/hi2'; import { IoArrowBackOutline, IoClose } from 'react-icons/io5'; import { Carousel } from '@mantine/carousel'; +import { funAddMemberCalender, funGetOneCalender } from '../lib/api_calender'; +import { IDataDetailByIdMember } from '../lib/type_calender'; export default function CreateUserDetailCalender() { const router = useRouter() - const param = useParams<{ id: string }>() + const param = useParams<{ id: string, detail: string }>() const [selectedFiles, setSelectedFiles] = useState([]) const [isData, setData] = useState([]) - const member = useHookstate(globalCalender) + const [isDataAnggota, setDataAnggota] = useState([]) const [selectAll, setSelectAll] = useState(false) const [loading, setLoading] = useState(true) const [onClickSearch, setOnClickSearch] = useState(false) @@ -28,11 +28,10 @@ export default function CreateUserDetailCalender() { try { setLoading(true) const response = await funGetSearchMemberDivision("?search=", param.id) + const res = await funGetOneCalender(param.detail) if (response.success) { + setDataAnggota(res.data.member) setData(response.data) - if (member.length > 0) { - setSelectedFiles(JSON.parse(JSON.stringify(member.get()))) - } setLoading(false) } else { toast.error(response.message) @@ -79,12 +78,23 @@ export default function CreateUserDetailCalender() { }; - function onSubmit() { - if (selectedFiles.length == 0) { - return toast.error("Error! silahkan pilih anggota") + async function onSubmit() { + try { + if (selectedFiles.length == 0) { + return toast.error("Error! silahkan pilih anggota") + } + + const res = await funAddMemberCalender(param.detail, selectedFiles) + if (res.success) { + toast.success(res.message) + router.push('./') + } else { + toast.error(res.message) + } + } catch (error) { + console.error(error); + toast.error("Gagal menambahkan anggota, coba lagi nanti"); } - member.set(selectedFiles) - // onClose(true) } const handleSearchClick = () => { @@ -161,8 +171,8 @@ export default function CreateUserDetailCalender() { ) : null } - {/* Close User */} - {isData.map((v, i) => { const isSelected = selectedFiles.some((i: any) => i?.idUser == v.idUser); + const found = isDataAnggota.some((i: any) => i.idUser == v.idUser) return ( - handleFileClick(i)}> + (!found) ? handleFileClick(i) : null}> {v.name} + {(found) ? "sudah menjadi anggota" : ""} {isSelected ? : null} diff --git a/src/module/calender/ui/detail_event_division.tsx b/src/module/calender/ui/detail_event_division.tsx index 52acbd1..1db1da6 100644 --- a/src/module/calender/ui/detail_event_division.tsx +++ b/src/module/calender/ui/detail_event_division.tsx @@ -193,131 +193,96 @@ export default function DetailEventDivision() { } - {/* {loading ? - - - {Array(4) - .fill(null) - .map((_, i) => ( - - - - ))} - - - : - - - Total Anggota - {isLengthMember} Anggota - - + + { + loading ? + - {isLengthMember == 0 ? ( - - Tidak ada anggota - - ) : - - {isDataAnggota.map((v, i) => { - return ( - - - - - - - - - {v.name} - - {v.email} - - - - - - - - - - ); - })} - - } + {Array(4) + .fill(null) + .map((_, i) => ( + + + + ))} - - } */} + : - - - Total Anggota - {isLengthMember} Anggota - - - - setOpenDrawerUser(true)}> - - - - - - - - - Nama - - email.com - - - - - - - - + + + Total Anggota + {isLengthMember} Anggota + + + + { + isLengthMember == 0 ? ( + + Tidak ada anggota + + ) : + + { + isDataAnggota.map((v, i) => { + return ( + setOpenDrawerUser(true)} key={i}> + + + + + + + + + {v.name} + + {v.email} + + + + + + + + + + + ) + }) + } + + } - - + } + + + Menu} onClose={() => setOpenDrawerUser(false)}>