done
This commit is contained in:
parent
68022ff5f1
commit
c8a982bd33
|
@ -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>
|
||||
|
|
|
@ -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
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue