From 309f0f17e0fbce283dd08f543777bf6c76cd2f31 Mon Sep 17 00:00:00 2001 From: amel Date: Tue, 3 Sep 2024 10:46:11 +0800 Subject: [PATCH 1/2] upd: home Deskripsi: - chart jumlah dokumen di halaman home No Issues" --- src/app/api/home/route.ts | 31 +++++++++++++++++-- src/module/home/ui/chart_document.tsx | 44 ++++++++++----------------- 2 files changed, 44 insertions(+), 31 deletions(-) diff --git a/src/app/api/home/route.ts b/src/app/api/home/route.ts index 3b00121..a22962e 100644 --- a/src/app/api/home/route.ts +++ b/src/app/api/home/route.ts @@ -150,7 +150,7 @@ export async function GET(request: Request) { for (let index = 0; index < dataStatus.length; index++) { const cek = data.some((i: any) => i.status == dataStatus[index].status) if (cek) { - const find = ((Number(data.find((i: any) => i.status == dataStatus[index].status)?._count) * 100)/ data.reduce((n, {_count}) => n + _count, 0)).toFixed(2) + const find = ((Number(data.find((i: any) => i.status == dataStatus[index].status)?._count) * 100) / data.reduce((n, { _count }) => n + _count, 0)).toFixed(2) input = { name: dataStatus[index].name, value: find @@ -195,14 +195,39 @@ export async function GET(request: Request) { where: kondisi, }) - allData = _.map(_.groupBy(data, "extension"), (v: any) => ({ + const groupData = _.map(_.groupBy(data, "extension"), (v: any) => ({ file: v[0].extension, jumlah: v.length, })) - // console.log(allData) + const image = ['jpg', 'jpeg', 'png', 'heic'] + let hasilImage = { + name: 'Gambar', + value: 0 + } + + let hasilFile = { + name: 'Dokumen', + value: 0 + } + + groupData.map((v: any) => { + if (image.some((i: any) => i == v.file)) { + hasilImage = { + name: 'Gambar', + value: hasilImage.value + v.jumlah + } + } else { + hasilFile = { + name: 'Dokumen', + value: hasilFile.value + v.jumlah + } + } + }) + + allData = [hasilImage, hasilFile] } else if (kategori == "event") { let kondisi diff --git a/src/module/home/ui/chart_document.tsx b/src/module/home/ui/chart_document.tsx index ab5c9ed..036df19 100644 --- a/src/module/home/ui/chart_document.tsx +++ b/src/module/home/ui/chart_document.tsx @@ -9,12 +9,13 @@ import toast from "react-hot-toast"; import { funGetHome } from "../lib/api_home"; export default function ChartDocumentHome() { - const [options, setOptions] = useState({}); + const [options, setOptions] = useState({}) const [isData, setData] = useState([]) - const [loading, setLoading] = useState(true); + const [loading, setLoading] = useState(true) + const color = ["#F3C96B", "#9EC97F", "#5971C0"] useShallowEffect(() => { - loadData() + // loadData() fetchData() }, []) @@ -28,6 +29,7 @@ export default function ChartDocumentHome() { if (response.success) { setData(response.data) + loadData(response.data) } else { toast.error(response.message); } @@ -40,7 +42,7 @@ export default function ChartDocumentHome() { } }; - const loadData = () => { + const loadData = (value: any) => { const option: EChartsOption = { title: { text: "DOKUMEN", @@ -65,7 +67,7 @@ export default function ChartDocumentHome() { xAxis: [ { type: 'category', - data: ['File', 'Folder', 'Documen'], + data: value.map(({ name }: any) => name), axisLabel: { fontSize: 14 }, @@ -94,30 +96,16 @@ export default function ChartDocumentHome() { name: 'Direct', type: 'bar', barWidth: '70%', - data: [ - { - value: 78, - name: 'File', + data: value.map( + (v: any, i: any) => + ({ + name: v.name, + value: v.value, itemStyle: { - color: "#F3C96B" - } - }, - { - value: 35, - name: 'Folder', - itemStyle: { - color: "#9EC97F" - } - }, - { - value: 58, - name: 'Documen', - itemStyle: { - color: "#5971C0" - } - }, - - ], + color: color[i] + }, + }) + ), } ] }; From a4b2cf64c59b007ad0dedbee4038370949c6779d Mon Sep 17 00:00:00 2001 From: amel Date: Tue, 3 Sep 2024 14:15:14 +0800 Subject: [PATCH 2/2] upd: report divisi Deskripsi: - report semua divisi - report 1 divisi No Issues --- src/app/api/division/report/route.ts | 198 ++++++++++++++++++ src/module/division_new/lib/api_division.ts | 5 + src/module/division_new/lib/type_division.ts | 14 ++ src/module/division_new/ui/create_report.tsx | 193 ++++++++++++----- .../division_new/ui/echart_bar_report.tsx | 36 ++-- .../division_new/ui/echart_pai_report.tsx | 15 +- src/module/division_new/ui/event_report.tsx | 129 ++++-------- .../division_new/ui/report_division_id.tsx | 164 ++++++++++----- src/module/home/ui/chart_document.tsx | 1 - 9 files changed, 525 insertions(+), 230 deletions(-) create mode 100644 src/app/api/division/report/route.ts diff --git a/src/app/api/division/report/route.ts b/src/app/api/division/report/route.ts new file mode 100644 index 0000000..d05eb48 --- /dev/null +++ b/src/app/api/division/report/route.ts @@ -0,0 +1,198 @@ +import { prisma } from "@/module/_global"; +import { funGetUserByCookies } from "@/module/auth"; +import _, { ceil } from "lodash"; +import moment from "moment"; +import { NextResponse } from "next/server"; + +export async function GET(request: Request) { + try { + + const user = await funGetUserByCookies() + const { searchParams } = new URL(request.url) + const group = searchParams.get("group") + const division = searchParams.get("division") + const date = searchParams.get("date") + + if (user.id == undefined) { + return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 401 }) + } + + + // CHART PROGRESS + let kondisiProgress + if (division == "undefined") { + kondisiProgress = { + isActive: true, + updatedAt: { + lte: new Date(String(date)) + }, + Division: { + idGroup: String(group) + } + } + } else { + kondisiProgress = { + isActive: true, + idDivision: String(division), + updatedAt: { + lte: new Date(String(date)) + }, + } + } + + const data = await prisma.divisionProject.groupBy({ + where: kondisiProgress, + by: ["status"], + _count: true + }) + + const dataStatus = [{ name: 'Segera dikerjakan', status: 0 }, { name: 'Dikerjakan', status: 1 }, { name: 'Selesai dikerjakan', status: 2 }, { name: 'Dibatalkan', status: 3 }] + const hasilProgres: any[] = [] + let input + for (let index = 0; index < dataStatus.length; index++) { + const cek = data.some((i: any) => i.status == dataStatus[index].status) + if (cek) { + const find = ((Number(data.find((i: any) => i.status == dataStatus[index].status)?._count) * 100) / data.reduce((n, { _count }) => n + _count, 0)).toFixed(2) + input = { + name: dataStatus[index].name, + value: find + } + } else { + input = { + name: dataStatus[index].name, + value: 0 + } + } + hasilProgres.push(input) + } + + + + + // CHART DOKUMEN + let kondisi + if (division == "undefined") { + kondisi = { + isActive: true, + category: 'FILE', + Division: { + idGroup: String(group) + }, + createdAt: { + lte: new Date(String(date)) + }, + } + } else { + kondisi = { + isActive: true, + category: 'FILE', + idDivision: String(division), + createdAt: { + lte: new Date(String(date)) + }, + } + } + + const dataDokumen = await prisma.divisionDocumentFolderFile.findMany({ + where: kondisi, + }) + + const groupData = _.map(_.groupBy(dataDokumen, "extension"), (v: any) => ({ + file: v[0].extension, + jumlah: v.length, + })) + + const image = ['jpg', 'jpeg', 'png', 'heic'] + + let hasilImage = { + name: 'Gambar', + value: 0 + } + + let hasilFile = { + name: 'Dokumen', + value: 0 + } + + groupData.map((v: any) => { + if (image.some((i: any) => i == v.file)) { + hasilImage = { + name: 'Gambar', + value: hasilImage.value + v.jumlah + } + } else { + hasilFile = { + name: 'Dokumen', + value: hasilFile.value + v.jumlah + } + } + }) + + const hasilDokumen = [hasilImage, hasilFile] + + + + // CHART EVENT + let kondisiEvent + if (division == "undefined") { + kondisiEvent = { + isActive: true, + Division: { + idGroup: String(group) + }, + dateStart: new Date(String(date)) + } + } else { + kondisiEvent = { + isActive: true, + idDivision: String(division), + dateStart: new Date(String(date)) + } + } + + const dataEvent = await prisma.divisionCalendar.findMany({ + where: kondisiEvent, + select: { + id: true, + idDivision: true, + title: true, + desc: true, + status: true, + timeStart: true, + dateStart: true, + timeEnd: true, + dateEnd: true, + createdAt: true, + User: { + select: { + name: true + } + } + }, + orderBy: { + createdAt: 'desc' + } + }) + + const hasilEvent = dataEvent.map((v: any) => ({ + ..._.omit(v, ["User"]), + user_name: v.User.name, + timeStart: moment.utc(v.timeStart).format('HH:mm'), + timeEnd: moment.utc(v.timeEnd).format('HH:mm') + })) + + + const allData = { + progress: hasilProgres, + dokumen: hasilDokumen, + event: hasilEvent + } + + return NextResponse.json({ success: true, message: "Berhasil mendapatkan data", data: allData }, { status: 200 }); + + } + catch (error) { + console.log(error); + return NextResponse.json({ success: false, message: "Gagal mendapatkan data, coba lagi nanti", reason: (error as Error).message, }, { status: 500 }); + } +} \ No newline at end of file diff --git a/src/module/division_new/lib/api_division.ts b/src/module/division_new/lib/api_division.ts index 3142169..7448e1f 100644 --- a/src/module/division_new/lib/api_division.ts +++ b/src/module/division_new/lib/api_division.ts @@ -77,4 +77,9 @@ export const funAddDivisionMember = async (path: string, data: IFormMemberDivisi export const funGetListDivisionByIdDivision = async (path: string) => { const response = await fetch(`/api/division/more${path}`); return await response.json().catch(() => null); +} + +export const funGetReportDivision = async (path?: string) => { + const response = await fetch(`/api/division/report${(path) ? path : ''}`, { next: { tags: ['discussion'] } }); + return await response.json().catch(() => null); } \ No newline at end of file diff --git a/src/module/division_new/lib/type_division.ts b/src/module/division_new/lib/type_division.ts index ea6bbf0..ef4184d 100644 --- a/src/module/division_new/lib/type_division.ts +++ b/src/module/division_new/lib/type_division.ts @@ -57,4 +57,18 @@ export interface IDataMemberDivision { isLeader: string, name: string, img: string +} + +export interface IDataReportDivision{ + id: string + idDivision: string + title: string + desc: string + status: number + timeStart: string + timeEnd: string + dateStart: string + dateEnd: string + createdAt: string + user_name: string } \ No newline at end of file diff --git a/src/module/division_new/ui/create_report.tsx b/src/module/division_new/ui/create_report.tsx index 407c6e6..3ac3ae7 100644 --- a/src/module/division_new/ui/create_report.tsx +++ b/src/module/division_new/ui/create_report.tsx @@ -1,18 +1,86 @@ "use client"; import { LayoutNavbarNew, WARNA } from "@/module/_global"; -import { Box, Select, Stack, Text } from "@mantine/core"; +import { Box, Select, Skeleton, Stack, Text } from "@mantine/core"; import { DateInput } from "@mantine/dates"; import React, { useState } from "react"; import EchartPaiReport from "./echart_pai_report"; import EchartBarReport from "./echart_bar_report"; import EventReport from "./event_report"; import DiscussionReport from "./discussion_report"; +import { funGetAllGroup, IDataGroup } from "@/module/group"; +import toast from "react-hot-toast"; +import { useShallowEffect } from "@mantine/hooks"; +import { funGetReportDivision } from "../lib/api_division"; +import { useParams } from "next/navigation"; +import moment from "moment"; export default function CreateReport() { const [value, setValue] = useState(null); + const [dataGroup, setDataGroup] = useState([]); + const [loading, setLoading] = useState(false); + const [tampil, setTampil] = useState(false); + const [isGroup, setIsGroup] = useState(""); + const param = useParams<{ id: string }>() + const [report, setReport] = useState({ + progress: [], + dokumen: [], + event: [], + }) + + async function loadData() { + const loadGroup = await funGetAllGroup('?active=true') + if (loadGroup.success) { + setDataGroup(loadGroup.data); + } else { + toast.error(loadGroup.message); + } + } + + async function onReport(group: string, date: any) { + try { + setReport({ + progress: [], + dokumen: [], + event: [], + }) + setTampil(true) + setLoading(true) + const res = await funGetReportDivision(`?group=${group}&division=${param.id}&date=${moment(date).format("YYYY-MM-DD")}`) + if (res.success) { + setReport(res.data) + } else { + toast.error(res.message) + } + } catch (error) { + console.log(error) + toast.error("Gagal mendapatkan data, coba lagi nanti"); + } finally { + setLoading(false) + } + } + + function onChooseGroup(val: any) { + if (val != null && val != "" && value != null && value != undefined) { + onReport(val, value) + } + + setIsGroup(String(val)) + } + + function onChangeDate(val: any) { + if (val != null && val != "" && isGroup != "" && isGroup != null) { + onReport(isGroup, val) + } + setValue(val) + } + + useShallowEffect(() => { + loadData(); + }, []); + return ( - +