From 8aac1709670787e857c0486c026aa5d36010fa35 Mon Sep 17 00:00:00 2001 From: amel Date: Wed, 13 Nov 2024 17:03:52 +0800 Subject: [PATCH 1/2] upd: dokumen Deskripsi; - update info dokumen No Issues --- src/app/api/document/more/route.ts | 93 ++++++++- src/module/document/lib/api_document.ts | 5 + src/module/document/lib/type_document.ts | 14 ++ .../document/ui/drawer_info_document.tsx | 196 ++++++++++++++++++ src/module/document/ui/drawer_more.tsx | 42 +++- .../document/ui/navbar_document_division.tsx | 8 +- 6 files changed, 343 insertions(+), 15 deletions(-) create mode 100644 src/module/document/ui/drawer_info_document.tsx diff --git a/src/app/api/document/more/route.ts b/src/app/api/document/more/route.ts index 9e833ab..de13d09 100644 --- a/src/app/api/document/more/route.ts +++ b/src/app/api/document/more/route.ts @@ -2,7 +2,9 @@ import { DIR, funCopyFile, prisma } from "@/module/_global"; import { funGetUserByCookies } from "@/module/auth"; import { createLogUser } from "@/module/user"; import _ from "lodash"; +import moment from "moment"; import { NextResponse } from "next/server"; +import "moment/locale/id"; // MOVE ITEM @@ -199,4 +201,93 @@ export async function DELETE(request: Request) { console.error(error); return NextResponse.json({ success: false, message: "Gagal membagikan item, coba lagi nanti (error: 500)", reason: (error as Error).message, }, { status: 500 }); } -}; \ No newline at end of file +}; + +// GET INFO ITEM +export async function GET(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 { searchParams } = new URL(request.url); + const idItem = searchParams.get("item"); + + const cekItem = await prisma.divisionDocumentFolderFile.count({ + where: { + id: String(idItem), + } + }) + + if (cekItem == 0) { + return NextResponse.json({ success: false, message: "Gagal mendapatkan dokumen, data tidak ditemukan" }, { status: 404 }); + } + + const data = await prisma.divisionDocumentFolderFile.findUnique({ + where: { + id: String(idItem), + }, + select: { + category: true, + name: true, + extension: true, + createdAt: true, + path: true, + Division: { + select: { + name: true + } + }, + User: { + select: { + name: true + } + } + } + }) + + const dataPath = await prisma.divisionDocumentFolderFile.findUnique({ + where: { + id: data?.path + } + }) + + const share = await prisma.divisionDocumentShare.findMany({ + where: { + idDocument: String(idItem), + isActive: true + }, + select: { + Division: { + select: { + name: true + } + } + } + }) + + + const dataUtama = { + category: data?.category, + name: data?.name, + extension: data?.extension, + createdAt: moment(data?.createdAt).format('DD MMMM YYYY'), + path: (dataPath?.name !== undefined && dataPath?.name !== null && dataPath?.name !== '') ? dataPath.name : "home", + division: data?.Division?.name, + createdBy: data?.User?.name + } + + const dataShare = share.map((v: any) => ({ + ..._.omit(v, ["Division"]), + division: v.Division.name + })) + + return NextResponse.json({ success: true, message: "Berhasil mendapatkan item", data: dataUtama, share: dataShare }, { status: 200 }); + + } catch (error) { + console.error(error); + return NextResponse.json({ success: false, message: "Gagal mendapatkan item, coba lagi nanti (error: 500)", 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 d7c218f..a089669 100644 --- a/src/module/document/lib/api_document.ts +++ b/src/module/document/lib/api_document.ts @@ -79,6 +79,11 @@ export const funShareDocument = async (data: IShareDocument) => { return await response.json().catch(() => null); }; +export const funGetInfoDocument = async (path?: string) => { + const response = await fetch(`/api/document/more${(path) ? path : ''}`); + return await response.json().catch(() => null); +}; + export const funUploadFileDocument = async (data: FormData) => { const response = await fetch(`/api/document/upload`, { method: "POST", diff --git a/src/module/document/lib/type_document.ts b/src/module/document/lib/type_document.ts index 25e7638..d9432aa 100644 --- a/src/module/document/lib/type_document.ts +++ b/src/module/document/lib/type_document.ts @@ -11,6 +11,20 @@ export interface IDataDocument { updatedAt: string; } +export interface IInfoDocument { + id: string; + path: string; + name: string; + extension: string; + category: string; + division: string; + createdBy: string; + createdAt: string; +} + +export interface IInfoShare { + division: string +} export interface IFormFolder { name: string; diff --git a/src/module/document/ui/drawer_info_document.tsx b/src/module/document/ui/drawer_info_document.tsx new file mode 100644 index 0000000..19cd6ff --- /dev/null +++ b/src/module/document/ui/drawer_info_document.tsx @@ -0,0 +1,196 @@ +import { SkeletonDetailProfile } from "@/module/_global"; +import { Accordion, Box, Divider, Grid, Group, List, ScrollArea, Skeleton, Stack, Text } from "@mantine/core"; +import { useMediaQuery, useShallowEffect } from "@mantine/hooks"; +import _ from "lodash"; +import { useState } from "react"; +import toast from "react-hot-toast"; +import { CiCalendarDate } from "react-icons/ci"; +import { FcDocument, FcFolder, FcImageFile } from "react-icons/fc"; +import { GrLocationPin } from "react-icons/gr"; +import { HiOutlineDocumentText } from "react-icons/hi2"; +import { MdOutlineCategory } from "react-icons/md"; +import { PiUsersThree } from "react-icons/pi"; +import { TbLockAccess } from "react-icons/tb"; +import { funGetInfoDocument } from "../lib/api_document"; +import { IFormDetailMoreItem, IInfoDocument, IInfoShare } from "../lib/type_document"; + +export default function DrawerInfoDocument({ data }: { data: IFormDetailMoreItem[] }) { + const [dataInfo, setDataInfo] = useState(); + const [dataShare, setDataShare] = useState([]) + const [loading, setLoading] = useState(true); + const isMobile = useMediaQuery("(max-width: 369px)"); + + + async function getOneData(loading: boolean) { + try { + setLoading(loading); + const respon = await funGetInfoDocument("?item=" + data[0].id); + if (respon.success) { + setDataInfo(respon.data); + setDataShare(respon.share) + } else { + toast.error(respon.message); + } + } catch (error) { + console.error(error); + toast.error("Gagal mendapatkan item, coba lagi nanti"); + } finally { + setLoading(false); + } + } + + useShallowEffect(() => { + getOneData(true); + }, []); + + return ( + + + + + {loading ? : + dataInfo?.category == "FOLDER" + ? () + : dataInfo?.extension == "pdf" || dataInfo?.extension == "csv" + ? () + : () + } + + + + {loading ? ( + + ) : ( + + + + + { + !isMobile ? + + : '' + } + Nama Dokumen + + + + {dataInfo?.category == "FOLDER" ? dataInfo?.name : dataInfo?.name + '.' + dataInfo?.extension} + + + + + + + { + !isMobile ? + + : '' + } + Tipe + + + + {_.lowerCase(dataInfo?.category)} + + + + + + + { + !isMobile ? + + : '' + } + Lokasi + + + + {dataInfo?.path} + + + + + + + { + !isMobile ? + + : '' + } + Pemilik + + + + {dataInfo?.division} + + + + + + + { + !isMobile ? + + : '' + } + Tanggal Dibuat + + + + + {dataInfo?.createdAt} + + + + + + + + : '' + } fz={15}>Yang Memiliki Akses + + + } + > + {dataInfo?.division} + { + dataShare.map((i: any) => { + return ( + {i.division} + ) + }) + } + + + + + + )} + + + + ); +} diff --git a/src/module/document/ui/drawer_more.tsx b/src/module/document/ui/drawer_more.tsx index 494132a..4a5817d 100644 --- a/src/module/document/ui/drawer_more.tsx +++ b/src/module/document/ui/drawer_more.tsx @@ -5,14 +5,15 @@ import { useShallowEffect } from "@mantine/hooks"; import { useParams, useSearchParams } from "next/navigation"; import { useState } from "react"; import toast from "react-hot-toast"; -import { LuFolders, LuFolderSymlink } from "react-icons/lu"; +import { LuFolders, LuFolderSymlink, LuInfo } from "react-icons/lu"; import { useWibuRealtime } from "wibu-realtime"; import { funCopyDocument, funMoveDocument } from "../lib/api_document"; import { IDataDocument } from "../lib/type_document"; import { globalRefreshDocument } from "../lib/val_document"; import DrawerCutDocuments from "./drawer_cut_documents"; +import DrawerInfoDocument from "./drawer_info_document"; -export default function DrawerMore({ data }: { data: IDataDocument[] }) { +export default function DrawerMore({ data, share }: { data: IDataDocument[], share: boolean }) { const [isCut, setIsCut] = useState(false) const [isCopy, setIsCopy] = useState(false) const refresh = useHookstate(globalRefreshDocument) @@ -27,6 +28,8 @@ export default function DrawerMore({ data }: { data: IDataDocument[] }) { }) const searchParams = useSearchParams() const pathAwal = searchParams.get('path') + const [nFileSelected, setNFileSelected] = useState(0) + const [isInfo, setIsInfo] = useState(false) async function onMoveItem(path: string) { @@ -86,6 +89,7 @@ export default function DrawerMore({ data }: { data: IDataDocument[] }) { function cekFileSelected() { const cek = data.some((i: any) => i.category == "FOLDER") setForbidCopy(cek) + setNFileSelected(data.length) } useShallowEffect(() => { @@ -100,14 +104,17 @@ export default function DrawerMore({ data }: { data: IDataDocument[] }) { - setIsCut(true)} justify={'center'} align={'center'} direction={'column'} > - - - - - Pindah - - + { + !share && + setIsCut(true)} justify={'center'} align={'center'} direction={'column'} > + + + + + Pindah + + + } { (!forbidCopy) && setIsCopy(true)} justify={'center'} align={'center'} direction={'column'} > @@ -119,6 +126,17 @@ export default function DrawerMore({ data }: { data: IDataDocument[] }) { } + { + (nFileSelected == 1) && + setIsInfo(true)} justify={'center'} align={'center'} direction={'column'} > + + + + + Informasi + + + } @@ -130,6 +148,10 @@ export default function DrawerMore({ data }: { data: IDataDocument[] }) { setIsCopy(false)} title={'Pilih Lokasi Salin'} size="lg"> { onCopyItem(val) }} category="copy" /> + + setIsInfo(false)} title={'Informasi Dokumen'} size="lg"> + + ); } diff --git a/src/module/document/ui/navbar_document_division.tsx b/src/module/document/ui/navbar_document_division.tsx index c6e929a..9ddbd38 100644 --- a/src/module/document/ui/navbar_document_division.tsx +++ b/src/module/document/ui/navbar_document_division.tsx @@ -461,7 +461,7 @@ export default function NavbarDocumentDivision() { variant="subtle" aria-label="share" onClick={ - selectedFiles.length > 0 && !shareSelected + (selectedFiles.length == 1) || (selectedFiles.length > 0 && !shareSelected) ? () => setMore(true) : undefined } @@ -469,7 +469,7 @@ export default function NavbarDocumentDivision() { 0 && !shareSelected + (selectedFiles.length == 1) || (selectedFiles.length > 0 && !shareSelected) ? "white" : "#656060" } @@ -479,7 +479,7 @@ export default function NavbarDocumentDivision() { fz={12} ta={"center"} c={ - selectedFiles.length > 0 && !shareSelected + (selectedFiles.length == 1) || (selectedFiles.length > 0 && !shareSelected) ? "white" : "#656060" } @@ -891,7 +891,7 @@ export default function NavbarDocumentDivision() { setMore(false)}> - + Date: Wed, 13 Nov 2024 17:05:02 +0800 Subject: [PATCH 2/2] upd: version api --- src/app/api/version-app/route.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/api/version-app/route.ts b/src/app/api/version-app/route.ts index ad998ca..936433f 100644 --- a/src/app/api/version-app/route.ts +++ b/src/app/api/version-app/route.ts @@ -2,7 +2,7 @@ import { NextResponse } from "next/server"; export async function GET(request: Request) { try { - return NextResponse.json({ success: true, version: "0.2.1", mode: "staging" }, { status: 200 }); + return NextResponse.json({ success: true, version: "0.2.2", mode: "staging" }, { status: 200 }); } catch (error) { console.error(error); return NextResponse.json({ success: false, version: "Gagal mendapatkan version, coba lagi nanti (error: 500)", reason: (error as Error).message, }, { status: 500 });