This commit is contained in:
Muhammad Eko 2024-10-04 16:09:30 +07:00
parent 68022ff5f1
commit c8a982bd33
3 changed files with 74 additions and 10 deletions

View File

@ -1,16 +1,40 @@
"use client"
import { useAppSelector } from "@/lib/hooks";
import { useGetEmployeeSummaryQuery, useGetMonthlyEmployeeQuery } from "@/services/api";
import { useGetEmployeeSummaryQuery, useGetMonthlyEmployeeQuery, useGetSanctionSummaryQuery } from "@/services/api";
import { ExclamationCircleIcon } from "@heroicons/react/24/outline";
import { BarChart, ChartsLegend, ChartsTooltip, ChartsXAxis, ChartsYAxis, LineChart } from "@mui/x-charts";
import { formatDate } from "date-fns";
import { useEffect } from "react";
import { useEffect, useState } from "react";
export default function KaryawanPage() {
const filter = useAppSelector(state => state.filter.filter);
const {data: employeeSummary} = useGetEmployeeSummaryQuery(filter);
const {data: montlyEmployee} = useGetMonthlyEmployeeQuery(filter);
const {data: employeeSummary, isFetching : loadingSummary} = useGetEmployeeSummaryQuery(filter);
const {data: montlyEmployee, isFetching : loadingMonthly} = useGetMonthlyEmployeeQuery(filter);
const {data: sanctionSummary, isFetching: loadingSanction} = useGetSanctionSummaryQuery(filter);
const [totalSanctions, setTotalSanctions] = useState<{
type: string;
count: number;
}[]>([]);
useEffect(() => {
if (sanctionSummary) {
const tmp = sanctionSummary.reduce((acc, curr) => {
acc.push({type: "st", count: curr.st});
acc.push({type: "sp1", count: curr.sp1});
acc.push({type: "sp2", count: curr.sp2});
acc.push({type: "sp3", count: curr.sp3});
acc.push({type: "phk", count: curr.phk});
return acc;
}, [] as {type: string; count: number}[]);
//add total
const total = tmp.reduce((acc, curr) => {
acc[curr.type] = (acc[curr.type] || 0) + curr.count;
return acc;
}, {} as {[key: string]: number});
setTotalSanctions(Object.keys(total).map(key => ({type: key, count: total[key]})))
}
}, [sanctionSummary]);
useEffect(() => {
console.log(filter);
@ -20,22 +44,32 @@ export default function KaryawanPage() {
<div className="grid grid-cols-12 gap-4">
<div className="col-span-8 bg-white py-4 pl-4 rounded-lg max-h-[420px] flex flex-col">
<div className="text-xl font-bold">Data Karyawan</div>
<div className="flex-1 min-h-[300px]">
<div className="flex-1 min-h-[300px] relative">
{employeeSummary && <BarChart className="w-full" dataset={employeeSummary} series={[
{dataKey: "count", label: (v) => v === "tooltip" ? "Jumlah Karyawan" : undefined!, color: "#2385DE"}
]} xAxis={[
{dataKey: "organization_code", label: "Nama Perusahaan", scaleType: "band", valueFormatter: (v, context) => context.location === "tooltip" ? employeeSummary.find(e => e.organization_code === v)?.organization_name : v}
]} />}
{(!employeeSummary || employeeSummary.length === 0) && !loadingSummary && <div className="absolute inset-0 flex justify-center items-center">
<div className="text-gray-400 flex flex-col items-center">
<span className="text-gray-600">Data belum tersedia</span>
</div>
</div>}
</div>
</div>
<div className="col-span-4 bg-white rounded-lg py-4 pl-4 max-h-[420px] flex flex-col">
<div className="text-xl font-bold">Data Karyawan Perbulan</div>
<div className="flex-1 min-h-[300px]">
<div className="flex-1 min-h-[300px] relative">
{montlyEmployee && <LineChart className="w-full" dataset={montlyEmployee} series={[
{dataKey: "count", label: (v) => v === "tooltip" ? "Jumlah Karyawan" : undefined!, area: true, color: "#F7CAA9"}
]} xAxis={[
{dataKey: "date", label: "Bulan", scaleType: "band", valueFormatter: (v, context) => formatDate(new Date(v), context.location === "tooltip" ? "MMMM yyyy" : "MMM")}
]} />}
{(!montlyEmployee || montlyEmployee.length === 0) && !loadingMonthly && <div className="absolute inset-0 flex justify-center items-center">
<div className="text-gray-400 flex flex-col items-center">
<span className="text-gray-600">Data belum tersedia</span>
</div>
</div>}
</div>
</div>
<div className="col-span-4 bg-white rounded-lg py-4 pl-4 max-h-[420px] flex flex-col">
@ -53,13 +87,25 @@ export default function KaryawanPage() {
<div className="col-span-4 bg-white rounded-lg py-4 pl-4 max-h-[420px] flex flex-col">
<div className="text-xl font-bold">Penjatuhan Sanksi</div>
<div className="flex-1 min-h-[300px] flex justify-center items-center flex-col">
<span className="text-gray-600">Data belum tersedia</span>
<BarChart className="w-full" dataset={totalSanctions} series={[
{dataKey: "count", label: (v) => v === "tooltip" ? "Total" : undefined!, color: "#F5C322"}
]} xAxis={[
{dataKey: "type", label: "Jenis Sanksi", scaleType: "band", valueFormatter: (v, context) => v.toUpperCase()}
]} />
</div>
</div>
<div className="col-span-8 bg-white rounded-lg py-4 pl-4 max-h-[420px] flex flex-col">
<div className="text-xl font-bold">Ranking (Top 10) Total Penjatuhan Sanksi Setiap Perusahaan</div>
<div className="flex-1 min-h-[300px] flex justify-center items-center flex-col">
<span className="text-gray-600">Data belum tersedia</span>
<BarChart className="w-full" dataset={sanctionSummary ?? []} series={[
{dataKey: "st", label: "ST", color: "#F5C322"},
{dataKey: "sp1", label: "SP1", color: "#F3832D"},
{dataKey: "sp2", label: "SP2", color: "#F6CBAB"},
{dataKey: "sp3", label: "SP3", color: "#E65551"},
{dataKey: "phk", label: "PHK", color: "#D32F2F"}
]} xAxis={[
{dataKey: "organization_code", label: "Nama Perusahaan", scaleType: "band", valueFormatter: (v, context) => context.location === "tooltip" ? sanctionSummary?.find(e => e.organization_code === v)?.organization_name : v}
]} />
</div>
</div>
</div>

View File

@ -1,5 +1,5 @@
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'
import { AttendanceRange, AttendanceSummary, EmployeeSummary, FilterOptions, MonthlyAttendance, MonthlyEmployee, ResignationCategory, ResignationReason, ResignationType as ResignationType, ResignSummary, User } from './types'
import { AttendanceRange, AttendanceSummary, EmployeeSummary, FilterOptions, MonthlyAttendance, MonthlyEmployee, ResignationCategory, ResignationReason, ResignationType as ResignationType, ResignSummary, SanctionSummary, User } from './types'
import { Response , Filter} from './types'
import { config } from '@/config';
@ -59,6 +59,14 @@ export const api = createApi({
}
},
}),
getSanctionSummary: builder.query<SanctionSummary[], Filter>({
query: (params) => ({ url: '/dashboard/sanction-summary', params }),
transformResponse: (response: Response) => {
if (response.status === "success") {
return response.data!;
}
},
}),
getOrganizationAttendance: builder.query<AttendanceSummary[], Filter>({
query: (params) => ({ url: '/dashboard/organization-attendance', params }),
transformResponse: (response: Response) => {
@ -120,5 +128,5 @@ export const api = createApi({
export const { useGetFilterOptionsQuery, useGetEmployeeSummaryQuery, useGetMonthlyEmployeeQuery, useGetMonthlyAttendanceQuery,
useGetOrganizationAttendanceQuery, useGetAttendanceRangeQuery, useGetResignSummaryQuery, useGetResignTypeQuery,
useLoginMutation, useAuthCheckQuery,
useLoginMutation, useAuthCheckQuery, useGetSanctionSummaryQuery,
useGetResignCategoryQuery, useGetResignReasonQuery } = api

View File

@ -50,6 +50,16 @@ export type AttendanceSummary = {
count: number;
}
export type SanctionSummary = {
organization_code: string;
organization_name: string;
st: number;
sp1: number;
sp2: number;
sp3: number;
phk: number;
}
export type MonthlyEmployee = {
date: string;
count: number;