From f54b1cb25bcd04fe7916c81dcbb75b5f8deb56b2 Mon Sep 17 00:00:00 2001 From: amel Date: Tue, 28 Jan 2025 12:42:27 +0800 Subject: [PATCH 1/7] upd: button unduh dokumen divisi --- .../document/ui/navbar_document_division.tsx | 37 ++++++++++--------- 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/src/module/document/ui/navbar_document_division.tsx b/src/module/document/ui/navbar_document_division.tsx index c464d9d..1cbdeac 100644 --- a/src/module/document/ui/navbar_document_division.tsx +++ b/src/module/document/ui/navbar_document_division.tsx @@ -345,24 +345,25 @@ export default function NavbarDocumentDivision() { > - { - if (selectedFiles.length > 0 && copyAllowed) { - onDownload("selected"); - } - }} - > - 0 && copyAllowed - ? "white" - : "#656060" - } - /> + + { + if (selectedFiles.length > 0 && copyAllowed) { + onDownload("selected"); + } + }} + > + 0 && copyAllowed + ? "white" + : "#656060" + } + /> + Date: Tue, 28 Jan 2025 14:17:03 +0800 Subject: [PATCH 2/7] rev: jumlah total file pada detail divisi --- src/app/api/division/[id]/detail/route.ts | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/app/api/division/[id]/detail/route.ts b/src/app/api/division/[id]/detail/route.ts index b018447..61434c5 100644 --- a/src/app/api/division/[id]/detail/route.ts +++ b/src/app/api/division/[id]/detail/route.ts @@ -50,6 +50,17 @@ export async function GET(request: Request, context: { params: { id: string } }) } }) + const dokumenShare = await prisma.divisionDocumentShare.count({ + where: { + idDivision: String(id), + isActive: true, + DivisionDocumentFolderFile: { + isActive: true, + category: "FILE" + } + } + }) + const diskusi = await prisma.divisionDisscussion.count({ where: { idDivision: String(id), @@ -74,7 +85,7 @@ export async function GET(request: Request, context: { params: { id: string } }) allData = { tugas: tugas, - dokumen: dokumen, + dokumen: dokumen + dokumenShare, diskusi: diskusi, kalender: kalender } From ec79379e7841fbe8aaf82d0eb5bf9bc772cb5c5f Mon Sep 17 00:00:00 2001 From: amel Date: Tue, 28 Jan 2025 14:38:02 +0800 Subject: [PATCH 3/7] revisi: dokumen divisi Deskripsi: - update on click pada flex selected file - file share boleh di unduh No Issues --- .../document/ui/navbar_document_division.tsx | 92 +++++++++---------- 1 file changed, 41 insertions(+), 51 deletions(-) diff --git a/src/module/document/ui/navbar_document_division.tsx b/src/module/document/ui/navbar_document_division.tsx index 1cbdeac..701f082 100644 --- a/src/module/document/ui/navbar_document_division.tsx +++ b/src/module/document/ui/navbar_document_division.tsx @@ -106,7 +106,7 @@ export default function NavbarDocumentDivision() { } const cek = selectedFiles.some((i: any) => i?.category == "FOLDER"); - if (cek || shareSelected || selectedFiles.length > 1) { + if (cek || selectedFiles.length > 1) { setCopyAllowed(false); } else { setCopyAllowed(true); @@ -345,16 +345,14 @@ export default function NavbarDocumentDivision() { > - - { - if (selectedFiles.length > 0 && copyAllowed) { - onDownload("selected"); - } - }} - > + { + if (selectedFiles.length > 0 && copyAllowed) { + onDownload("selected"); + } + }} + > + - - 0 && !shareSelected - ? () => setIsDelete(true) - : undefined - } - > + 0 && !shareSelected + ? () => setIsDelete(true) + : undefined + } + > + - - onChooseRename() - : undefined - } - > + onChooseRename() + : undefined + } + > + - - 0 && !shareSelected - ? () => setShare(true) - : undefined - } - > + 0 && !shareSelected + ? () => setShare(true) + : undefined + } + > + - - 0 && !shareSelected) - ? () => setMore(true) - : undefined - } - > + 0 && !shareSelected) + ? () => setMore(true) + : undefined + } + > + Date: Thu, 30 Jan 2025 14:39:00 +0800 Subject: [PATCH 4/7] rev: fitur unshare dokumen divisi Deskripsi: - unshare dokumen - modal drawer dokumen - update api - cuma bisa share 1 dokumen terpilih No Issues --- src/app/api/document/more/route.ts | 107 ++++++++++-------- src/module/document/lib/type_document.ts | 3 +- .../document/ui/drawer_info_document.tsx | 55 ++++----- src/module/document/ui/drawer_more.tsx | 2 +- .../document/ui/drawer_share_document.tsx | 14 ++- .../document/ui/navbar_document_division.tsx | 8 +- 6 files changed, 98 insertions(+), 91 deletions(-) diff --git a/src/app/api/document/more/route.ts b/src/app/api/document/more/route.ts index de13d09..1279bfc 100644 --- a/src/app/api/document/more/route.ts +++ b/src/app/api/document/more/route.ts @@ -214,6 +214,7 @@ export async function GET(request: Request) { const { searchParams } = new URL(request.url); const idItem = searchParams.get("item"); + const category = searchParams.get("cat"); const cekItem = await prisma.divisionDocumentFolderFile.count({ where: { @@ -225,66 +226,72 @@ export async function GET(request: Request) { 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 - } + let fixData + if (category == 'share') { + const share = await prisma.divisionDocumentShare.findMany({ + where: { + idDocument: String(idItem), + isActive: true }, - User: { - select: { - name: true + select: { + idDivision: true, + Division: { + select: { + name: true + } } } - } - }) + }) - const dataPath = await prisma.divisionDocumentFolderFile.findUnique({ - where: { - id: data?.path - } - }) + fixData = share.map((v: any) => ({ + ..._.omit(v, ["idDivision", "Division"]), + id: v.idDivision, + name: v.Division.name + })) - const share = await prisma.divisionDocumentShare.findMany({ - where: { - idDocument: String(idItem), - isActive: true - }, - select: { - Division: { - select: { - name: true + } else { + 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 + } + }) + + + fixData = { + 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 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 }); + return NextResponse.json({ success: true, message: "Berhasil mendapatkan item", data: fixData }, { status: 200 }); } catch (error) { console.error(error); diff --git a/src/module/document/lib/type_document.ts b/src/module/document/lib/type_document.ts index d9432aa..cc05512 100644 --- a/src/module/document/lib/type_document.ts +++ b/src/module/document/lib/type_document.ts @@ -23,7 +23,8 @@ export interface IInfoDocument { } export interface IInfoShare { - division: string + id: string + name: string } export interface IFormFolder { diff --git a/src/module/document/ui/drawer_info_document.tsx b/src/module/document/ui/drawer_info_document.tsx index 19cd6ff..1f394aa 100644 --- a/src/module/document/ui/drawer_info_document.tsx +++ b/src/module/document/ui/drawer_info_document.tsx @@ -4,17 +4,13 @@ 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 { PiCalendarBlankLight, PiMapPinSimpleLight, PiShapesLight, PiShareNetworkLight, PiUsersThreeLight } from "react-icons/pi"; import { funGetInfoDocument } from "../lib/api_document"; import { IFormDetailMoreItem, IInfoDocument, IInfoShare } from "../lib/type_document"; -export default function DrawerInfoDocument({ data }: { data: IFormDetailMoreItem[] }) { +export default function DrawerInfoDocument({ data }: { data: IFormDetailMoreItem }) { const [dataInfo, setDataInfo] = useState(); const [dataShare, setDataShare] = useState([]) const [loading, setLoading] = useState(true); @@ -24,16 +20,17 @@ export default function DrawerInfoDocument({ data }: { data: IFormDetailMoreItem async function getOneData(loading: boolean) { try { setLoading(loading); - const respon = await funGetInfoDocument("?item=" + data[0].id); + const respon = await funGetInfoDocument(`?item=${data.id}&cat=utama`); + const responShare = await funGetInfoDocument(`?item=${data.id}&cat=share`); if (respon.success) { setDataInfo(respon.data); - setDataShare(respon.share) + setDataShare(responShare.data) } else { toast.error(respon.message); } } catch (error) { console.error(error); - toast.error("Gagal mendapatkan item, coba lagi nanti"); + toast.error("Gagal mendapatkan data, coba lagi nanti"); } finally { setLoading(false); } @@ -61,7 +58,7 @@ export default function DrawerInfoDocument({ data }: { data: IFormDetailMoreItem } - + > */} {loading ? ( ) : ( @@ -89,7 +86,7 @@ export default function DrawerInfoDocument({ data }: { data: IFormDetailMoreItem - {dataInfo?.category == "FOLDER" ? dataInfo?.name : dataInfo?.name + '.' + dataInfo?.extension} + {dataInfo?.category == "FOLDER" ? dataInfo?.name : `${dataInfo?.name}.${dataInfo?.extension}`} @@ -98,7 +95,7 @@ export default function DrawerInfoDocument({ data }: { data: IFormDetailMoreItem { !isMobile ? - + : '' } Tipe @@ -114,14 +111,14 @@ export default function DrawerInfoDocument({ data }: { data: IFormDetailMoreItem { !isMobile ? - + : '' } Lokasi - {dataInfo?.path} + {dataInfo?.path} @@ -130,14 +127,14 @@ export default function DrawerInfoDocument({ data }: { data: IFormDetailMoreItem { !isMobile ? - + : '' } Pemilik - {dataInfo?.division} + {dataInfo?.division} @@ -146,7 +143,7 @@ export default function DrawerInfoDocument({ data }: { data: IFormDetailMoreItem { !isMobile ? - + : '' } Tanggal Dibuat @@ -163,25 +160,23 @@ export default function DrawerInfoDocument({ data }: { data: IFormDetailMoreItem + : '' - } fz={15}>Yang Memiliki Akses + } fz={15}>Telah dibagikan ke divisi - } + icon={dataShare.length > 0 ? : <>} > - {dataInfo?.division} { - dataShare.map((i: any) => { - return ( - {i.division} - ) - }) + dataShare.length === 0 ? Tidak ada data : + dataShare.map((i: any) => { + return ( + {i.name} + ) + }) } @@ -189,7 +184,7 @@ export default function DrawerInfoDocument({ data }: { data: IFormDetailMoreItem )} - + {/* */} ); diff --git a/src/module/document/ui/drawer_more.tsx b/src/module/document/ui/drawer_more.tsx index 4a5817d..90d80a8 100644 --- a/src/module/document/ui/drawer_more.tsx +++ b/src/module/document/ui/drawer_more.tsx @@ -150,7 +150,7 @@ export default function DrawerMore({ data, share }: { data: IDataDocument[], sha setIsInfo(false)} title={'Informasi Dokumen'} size="lg"> - + ); diff --git a/src/module/document/ui/drawer_share_document.tsx b/src/module/document/ui/drawer_share_document.tsx index 77640ca..3da0e00 100644 --- a/src/module/document/ui/drawer_share_document.tsx +++ b/src/module/document/ui/drawer_share_document.tsx @@ -7,24 +7,23 @@ import { useParams } from "next/navigation"; import { useState } from "react"; import toast from "react-hot-toast"; import { FaCheck, FaUsers } from "react-icons/fa6"; -import { funShareDocument } from "../lib/api_document"; +import { funGetInfoDocument, funShareDocument } from "../lib/api_document"; import { IShareDivision } from "../lib/type_document"; import { globalRefreshDocument } from "../lib/val_document"; -export default function DrawerShareDocument({ data, }: { data: IShareDivision[]; }) { +export default function DrawerShareDocument({ data }: { data: IShareDivision[]; }) { const [selectedFiles, setSelectedFiles] = useState([]); const [isData, setData] = useState([]); const param = useParams<{ id: string }>(); const refresh = useHookstate(globalRefreshDocument); const tema = useHookstate(TEMA); const [loading, setLoading] = useState(true); + const [loadingBtn, setLoadingBtn] = useState(false) const isMobile2 = useMediaQuery("(max-width: 438px)"); async function onShare() { try { - if (selectedFiles.length == 0) { - return toast.error("Pilih divisi terlebih dahulu"); - } + setLoadingBtn(true) const respon = await funShareDocument({ dataDivision: selectedFiles, @@ -39,6 +38,8 @@ export default function DrawerShareDocument({ data, }: { data: IShareDivision[]; } catch (error) { console.error(error); toast.error("Gagal membagikan item, coba lagi nanti"); + } finally { + setLoadingBtn(false) } } @@ -48,8 +49,10 @@ export default function DrawerShareDocument({ data, }: { data: IShareDivision[]; const response = await funGetListDivisionByIdDivision( "?division=" + param.id ); + const shared = await funGetInfoDocument(`?item=${data[0].id}&cat=share`); if (response.success) { setData(response.data.filter((i: any) => i.id != param.id)); + setSelectedFiles(shared.data) } else { toast.error(response.message); } @@ -202,6 +205,7 @@ export default function DrawerShareDocument({ data, }: { data: IShareDivision[]; radius={30} fullWidth onClick={() => onShare()} + loading={loadingBtn} > Simpan diff --git a/src/module/document/ui/navbar_document_division.tsx b/src/module/document/ui/navbar_document_division.tsx index 701f082..3c1f1b4 100644 --- a/src/module/document/ui/navbar_document_division.tsx +++ b/src/module/document/ui/navbar_document_division.tsx @@ -434,16 +434,16 @@ export default function NavbarDocumentDivision() { 0 && !shareSelected + selectedFiles.length == 1 && !shareSelected ? () => setShare(true) : undefined } > - + 0 && !shareSelected + selectedFiles.length == 1 && !shareSelected ? "white" : "#656060" } @@ -453,7 +453,7 @@ export default function NavbarDocumentDivision() { fz={12} ta={"center"} c={ - selectedFiles.length > 0 && !shareSelected + selectedFiles.length == 1 && !shareSelected ? "white" : "#656060" } From cd3cd6e0c054f3a65be1619cc6a2bf7d19cf5ce9 Mon Sep 17 00:00:00 2001 From: amel Date: Thu, 30 Jan 2025 14:50:53 +0800 Subject: [PATCH 5/7] upd: log user dokumen divisi share --- src/app/api/document/more/route.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/api/document/more/route.ts b/src/app/api/document/more/route.ts index 1279bfc..42cc186 100644 --- a/src/app/api/document/more/route.ts +++ b/src/app/api/document/more/route.ts @@ -192,10 +192,10 @@ export async function DELETE(request: Request) { data: omitData }) + // create log user + const log = await createLogUser({ act: 'CREATE', desc: 'User membagikan item', table: 'divisionDocumentShare', data: dataItem[i].id }) } - // create log user - const log = await createLogUser({ act: 'CREATE', desc: 'User membagikan item', table: 'divisionDocumentShare', data: '' }) return NextResponse.json({ success: true, message: "Berhasil membagikan item" }, { status: 200 }); } catch (error) { console.error(error); From 293abfb258bdf7643ef2b186a60fc37a92d3347f Mon Sep 17 00:00:00 2001 From: amel Date: Thu, 30 Jan 2025 16:30:14 +0800 Subject: [PATCH 6/7] rev: divisi detail Deskripsi: - menampilkan file share pada dokumen terkini No Issues --- src/app/api/division/[id]/detail/route.ts | 51 +++++++++++++++++++- src/module/division_new/lib/type_division.ts | 3 +- src/module/division_new/ui/list_document.tsx | 35 +++++++++++--- 3 files changed, 80 insertions(+), 9 deletions(-) diff --git a/src/app/api/division/[id]/detail/route.ts b/src/app/api/division/[id]/detail/route.ts index 61434c5..c65c4fc 100644 --- a/src/app/api/division/[id]/detail/route.ts +++ b/src/app/api/division/[id]/detail/route.ts @@ -133,7 +133,43 @@ export async function GET(request: Request, context: { params: { id: string } }) projectTitle: v.DivisionProject.title })) } else if (kategori == "new-file") { - allData = await prisma.divisionDocumentFolderFile.findMany({ + const dataShare = await prisma.divisionDocumentShare.findMany({ + skip: 0, + take: 5, + where: { + isActive: true, + idDivision: String(id), + DivisionDocumentFolderFile: { + isActive: true, + category: "FILE" + } + }, + select: { + DivisionDocumentFolderFile: { + select: { + id: true, + name: true, + extension: true, + path: true, + } + }, + createdAt: true + }, + orderBy: { + createdAt: 'desc' + } + }) + + const fixShare = dataShare.map((v: any) => ({ + ..._.omit(v, ["DivisionDocumentFolderFile"]), + id: v.DivisionDocumentFolderFile.id, + name: v.DivisionDocumentFolderFile.name, + extension: v.DivisionDocumentFolderFile.extension, + path: 'home', + share: true + })) + + const dataDokumen = await prisma.divisionDocumentFolderFile.findMany({ skip: 0, take: 5, where: { @@ -146,11 +182,24 @@ export async function GET(request: Request, context: { params: { id: string } }) name: true, extension: true, path: true, + createdAt: true }, orderBy: { createdAt: "desc" } }) + + const fixData = dataDokumen.map((v: any) => ({ + ..._.omit(v, [""]), + share: false + })) + + if (fixShare.length > 0) { + fixData.push(...fixShare) + } + + allData = _.orderBy(fixData, ['createdAt'], ['desc']); + } else if (kategori == "new-discussion") { const diskusi = await prisma.divisionDisscussion.findMany({ skip: 0, diff --git a/src/module/division_new/lib/type_division.ts b/src/module/division_new/lib/type_division.ts index 4846b1f..9b6273e 100644 --- a/src/module/division_new/lib/type_division.ts +++ b/src/module/division_new/lib/type_division.ts @@ -42,7 +42,8 @@ export interface IDataKalenderOnDetailDivision { id: string, name: string, extension: string, - path: string + path: string, + share:boolean } export interface IDataDiscussionOnDetailDivision { diff --git a/src/module/division_new/ui/list_document.tsx b/src/module/division_new/ui/list_document.tsx index 7409732..a2e2c6b 100644 --- a/src/module/division_new/ui/list_document.tsx +++ b/src/module/division_new/ui/list_document.tsx @@ -2,7 +2,7 @@ import { TEMA, } from "@/module/_global"; import { useHookstate } from "@hookstate/core"; import { Carousel } from "@mantine/carousel"; -import { Box, Center, Group, Image, Skeleton, Stack, Text, UnstyledButton } from "@mantine/core"; +import { Box, Center, Flex, Group, Image, Indicator, Skeleton, Stack, Text, UnstyledButton } from "@mantine/core"; import { useMediaQuery, useShallowEffect } from "@mantine/hooks"; import { useParams, useRouter } from "next/navigation"; import { useState } from "react"; @@ -10,6 +10,7 @@ import toast from "react-hot-toast"; import { funGetDetailDivisionById } from "../lib/api_division"; import * as ICON from '../lib/file_icon'; import { IDataKalenderOnDetailDivision } from "../lib/type_division"; +import { FaShare } from "react-icons/fa6"; const iconContainer = (icon: string) => 'data:image/svg+xml;base64,' + btoa(icon) @@ -44,7 +45,7 @@ export default function ListDocumentOnDetailDivision() { return ( - Dokumen Terbaru + Dokumen Terkini { loading @@ -70,11 +71,31 @@ export default function ListDocumentOnDetailDivision() { router.push(`/division/${param.id}/document?path=${v.path}`)}> - -
- image -
-
+ { + v.share ? + } + size={25} + > + +
+ image +
+
+
+ : + +
+ image +
+
+ } + {v.name + '.' + v.extension} From 170783ba0bb11870784f11f4dc706bcfdb08f14f Mon Sep 17 00:00:00 2001 From: amel Date: Thu, 30 Jan 2025 16:57:03 +0800 Subject: [PATCH 7/7] upd: api version --- 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 524f12b..4b37af9 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: "1.1.4", tahap: "beta", update:"-resize profile image user (create anggota, edit anggota, edit profile) -menghilangkan image extensi heic" }, { status: 200 }); + return NextResponse.json({ success: true, version: "1.2.0", tahap: "beta", update:"-unshare dokumen divisi -jumlah dokumen pada detail divisi -tampil dokumen share pada detail divisi -loguser pada saat share dokumen divisi -boleh unduh file share" }, { 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 });