From b7d67986c65ef6177385b5eae7b88b9069c5171a Mon Sep 17 00:00:00 2001 From: amel Date: Wed, 21 Aug 2024 16:35:56 +0800 Subject: [PATCH 1/3] upd: document Deskripsi: - rename No Issues --- src/app/api/document/route.ts | 72 ++++++++ src/module/document/lib/api_document.ts | 16 +- src/module/document/lib/type_document.ts | 9 + .../ui/drawer_menu_document_division.tsx | 12 +- .../document/ui/navbar_document_division.tsx | 166 +++++++++++++++--- 5 files changed, 240 insertions(+), 35 deletions(-) diff --git a/src/app/api/document/route.ts b/src/app/api/document/route.ts index 54bfbc6..fc8c9e6 100644 --- a/src/app/api/document/route.ts +++ b/src/app/api/document/route.ts @@ -107,6 +107,22 @@ export async function POST(request: Request) { } } + const nameFile = await prisma.divisionDocumentFolderFile.count({ + where: { + name, + idDivision, + path, + extension: "folder", + category: "FOLDER", + isActive: true + } + }) + + + if (nameFile > 0) { + return NextResponse.json({ success: false, message: "Gagal membuat folder baru, folder sudah ada" }, { status: 400 }); + } + const data = await prisma.divisionDocumentFolderFile.create({ data: { name, @@ -123,4 +139,60 @@ export async function POST(request: Request) { console.log(error); return NextResponse.json({ success: false, message: "Gagal membuat folder, coba lagi nanti", reason: (error as Error).message, }, { status: 500 }); } +}; + + +export async function PUT(request: Request) { + try { + const user = await funGetUserByCookies() + if (user.id == undefined) { + return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 401 }); + } + + const { name, id, path, idDivision, extension } = (await request.json()); + const cekFile = await prisma.divisionDocumentFolderFile.count({ + where: { + id: id, + isActive: true + } + }) + + if (cekFile == 0) { + return NextResponse.json({ success: false, message: "Gagal mendapatkan item, data tidak ditemukan" }, { status: 404 }); + } + + const nameFile = await prisma.divisionDocumentFolderFile.count({ + where: { + name, + idDivision, + path, + extension, + isActive: true, + NOT: { + id: id + }, + } + }) + + + if (nameFile > 0) { + return NextResponse.json({ success: false, message: "Gagal mengubah nama item, item sudah ada" }, { status: 400 }); + } + + const update = await prisma.divisionDocumentFolderFile.update({ + where: { + id: id + }, + data: { + name, + } + }) + + + + return NextResponse.json({ success: true, message: "Berhasil mengubah nama item" }, { status: 200 }); + } catch (error) { + console.log(error); + return NextResponse.json({ success: false, message: "Gagal mengubah nama item, coba lagi nanti", reason: (error as Error).message, }, { status: 500 }); + } }; \ No newline at end of file diff --git a/src/module/document/lib/api_document.ts b/src/module/document/lib/api_document.ts index d58e308..a596c4b 100644 --- a/src/module/document/lib/api_document.ts +++ b/src/module/document/lib/api_document.ts @@ -1,4 +1,4 @@ -import { IFormFolder } from "./type_document"; +import { IFormEditItem, IFormFolder } from "./type_document"; export const funGetAllDocument = async (path?: string) => { const response = await fetch(`/api/document${(path) ? path : ''}`, { next: { tags: ['document'] } }); @@ -18,4 +18,18 @@ export const funCreateFolder = async (data: IFormFolder) => { body: JSON.stringify(data), }); return await response.json().catch(() => null); +}; + +export const funRenameDocument = async (data: IFormEditItem) => { + if (data.name == "") + return { success: false, message: 'Nama item tidak boleh kosong' } + + const response = await fetch("/api/document", { + method: "PUT", + 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/document/lib/type_document.ts b/src/module/document/lib/type_document.ts index a798709..9f2dbb0 100644 --- a/src/module/document/lib/type_document.ts +++ b/src/module/document/lib/type_document.ts @@ -14,4 +14,13 @@ export interface IFormFolder { name: string; path: string; idDivision: string +} + + +export interface IFormEditItem { + id: string + name: string + path: string + idDivision: string + extension: string } \ No newline at end of file diff --git a/src/module/document/ui/drawer_menu_document_division.tsx b/src/module/document/ui/drawer_menu_document_division.tsx index 4befdac..01165c0 100644 --- a/src/module/document/ui/drawer_menu_document_division.tsx +++ b/src/module/document/ui/drawer_menu_document_division.tsx @@ -29,17 +29,17 @@ export default function DrawerMenuDocumentDivision() { async function onCreateFolder() { try { const res = await funCreateFolder(bodyFolder) - if (res.success) { - refresh.set(true) - setOpenModal(false) - setOpenDrawerDocument(false) - } else { - toast.error(res.message); + if (!res.success) { + toast.error(res.message) } } catch (error) { console.error(error); toast.error("Gagal membuat folder baru, coba lagi nanti"); } + + refresh.set(true) + setOpenModal(false) + setOpenDrawerDocument(false) } return ( diff --git a/src/module/document/ui/navbar_document_division.tsx b/src/module/document/ui/navbar_document_division.tsx index a40d36e..27a0d1f 100644 --- a/src/module/document/ui/navbar_document_division.tsx +++ b/src/module/document/ui/navbar_document_division.tsx @@ -4,11 +4,11 @@ import { ActionIcon, Box, Button, Checkbox, Divider, Flex, Grid, Group, Modal, S import React, { useState } from 'react'; import { HiMenu } from 'react-icons/hi'; import { FcDocument, FcFolder, FcImageFile } from 'react-icons/fc'; -import { BsDownload } from 'react-icons/bs'; +import { BsDownload, BsListCheck } from 'react-icons/bs'; import { AiOutlineDelete } from 'react-icons/ai'; import { CgRename } from "react-icons/cg"; import { LuShare2 } from 'react-icons/lu'; -import { MdOutlineMoreHoriz } from 'react-icons/md'; +import { MdClose, MdOutlineMoreHoriz } from 'react-icons/md'; import LayoutModal from '@/module/_global/layout/layout_modal'; import toast from 'react-hot-toast'; import { useParams, useRouter, useSearchParams } from 'next/navigation'; @@ -16,13 +16,13 @@ import DrawerMenuDocumentDivision from './drawer_menu_document_division'; import DrawerMore from './drawer_more'; import { funGetDivisionById } from '@/module/division_new'; import { useShallowEffect } from '@mantine/hooks'; -import { funGetAllDocument } from '../lib/api_document'; +import { funGetAllDocument, funRenameDocument } from '../lib/api_document'; import { IDataDocument } from '../lib/type_document'; import { useHookstate } from '@hookstate/core'; import { globalRefreshDocument } from '../lib/val_document'; +import { RiListCheck } from 'react-icons/ri'; export default function NavbarDocumentDivision() { - const [isChecked, setIsChecked] = useState(false); const router = useRouter() const param = useParams<{ id: string }>() const [name, setName] = useState('') @@ -35,11 +35,70 @@ export default function NavbarDocumentDivision() { const path = searchParams.get('path') const [dataDocument, setDataDocument] = useState([]) const refresh = useHookstate(globalRefreshDocument) + const [selectedFiles, setSelectedFiles] = useState([]) + const [selectAll, setSelectAll] = useState(false) + const [dariSelectAll, setDariSelectAll] = useState(false) + const [bodyRename, setBodyRename] = useState({ + id: '', + name: '', + path: '', + idDivision: param.id, + extension: '' + }) + + const handleCheckboxChange = (index: number) => { + setDariSelectAll(false) + if (selectedFiles.some((i: any) => i.id == dataDocument[index].id)) { + setSelectedFiles(selectedFiles.filter((i: any) => i.id != dataDocument[index].id)) + } else { + setSelectedFiles([ + ...selectedFiles, + { + id: dataDocument[index].id, + name: dataDocument[index].name, + path: dataDocument[index].path, + extension: dataDocument[index].extension + } + ]) + } - const handleCheckboxChange = () => { - setIsChecked(!isChecked); }; + function cek() { + if (selectedFiles.length == dataDocument.length) { + setSelectAll(true) + } else { + setSelectAll(false) + } + } + + const handleSelectAll = () => { + if (!selectAll) { + setDariSelectAll(false) + for (let index = 0; index < dataDocument.length; index++) { + if (!selectedFiles.some((i: any) => i.id == dataDocument[index].id)) { + const newArr = { + id: dataDocument[index].id, + name: dataDocument[index].name, + path: dataDocument[index].path, + extension: dataDocument[index].extension + } + setSelectedFiles((selectedFiles: any) => [...selectedFiles, newArr]) + } + } + } else { + setDariSelectAll(true) + setSelectedFiles([]); + } + + }; + + const handleBatal = () => { + setSelectedFiles([]) + setSelectAll(false) + setDariSelectAll(false) + } + function onTrue(val: boolean) { if (val) { @@ -47,10 +106,22 @@ export default function NavbarDocumentDivision() { } setIsDelete(false) } - function onEdit(val: boolean) { - if (val) { - toast.success("Sukses! Edit Data"); + async function onRenameSubmit() { + try { + const res = await funRenameDocument(bodyRename) + if (res.success) { + getOneData() + + } else { + toast.error(res.message) + } + } catch (error) { + console.log(error) + toast.error("Gagal mengganti nama item, coba lagi nanti") } + + setSelectedFiles([]) + setDariSelectAll(false) setRename(false) } @@ -81,21 +152,48 @@ export default function NavbarDocumentDivision() { setOpen(false) } + useShallowEffect(() => { + cek() + }, [selectedFiles]) + useShallowEffect(() => { getOneData() resetRefresh() }, [param.id, path, refresh.get()]) + + function onChooseRename() { + setBodyRename({ + ...bodyRename, + id: selectedFiles[0].id, + name: selectedFiles[0].name, + path: selectedFiles[0].path, + extension: selectedFiles[0].extension, + + }) + setRename(true) + } + return ( - {isChecked && ( + {(selectedFiles.length > 0 || dariSelectAll) && ( <> - Dibatalkan - Pilih Semua + handleBatal()}> + + + {(selectedFiles.length > 0) ? selectedFiles.length + " item terpilih" : "Pilih Item"} + handleSelectAll()}> + { + (selectAll) ? + : + + } + + - - Unduh + 0) ? 'white' : 'grey'} /> + 0) ? 'white' : 'grey'}>Unduh setIsDelete(true)} justify={'center'} align={'center'} direction={'column'}> - - Hapus + 0) ? 'white' : 'grey'} /> + 0) ? 'white' : 'grey'}>Hapus - setRename(true)} justify={'center'} align={'center'} direction={'column'}> - - Ganti Name + { + if (selectedFiles.length == 1) { + onChooseRename() + } + }} justify={'center'} align={'center'} direction={'column'}> + + Ganti Nama setShare(true)} justify={'center'} align={'center'} direction={'column'}> - - Bagikan + 0) ? 'white' : 'grey'} /> + 0) ? 'white' : 'grey'}>Bagikan setMore(true)} justify={'center'} align={'center'} direction={'column'}> - - Lainnya + 0) ? 'white' : 'grey'} /> + 0) ? 'white' : 'grey'}>Lainnya @@ -139,6 +241,7 @@ export default function NavbarDocumentDivision() { {dataDocument.map((v, i) => { + const isSelected = selectedFiles.some((i: any) => i?.id == v.id); return ( @@ -171,8 +274,8 @@ export default function NavbarDocumentDivision() { color="teal" radius="lg" size="md" - checked={isChecked} - onChange={handleCheckboxChange} + checked={isSelected} + onChange={() => handleCheckboxChange(i)} /> @@ -195,6 +298,8 @@ export default function NavbarDocumentDivision() { setIsDelete(false)} description="Apakah Anda yakin ingin menghapus data?" onYes={(val) => { onTrue(val) }} /> + + setRename(false)} centered withCloseButton={false}> - Edit Folder + Ganti Nama Item setBodyRename({ ...bodyRename, name: e.target.value })} /> @@ -225,11 +332,14 @@ export default function NavbarDocumentDivision() { - + + + + setShare(false)} size='lg'>