"use client"
import { useAppSelector } from "@/lib/hooks";
import { useGetAttendanceRangeQuery, useGetMonthlyAttendanceQuery, useGetOrganizationAttendanceQuery } from "@/services/api";
import { ExclamationCircleIcon } from "@heroicons/react/24/outline";
import { ComposedChart, Bar, Line, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer, PieChart, Pie, Cell, BarChart } from 'recharts';
import { formatDate } from "date-fns";
import { PageLoader } from "@/components/Loader";
import {CustomLegendHorizontal, CustomLegendVertical} from "@/components/CustomLegendPie";
import { useLocale } from "@/lib/hooks/useLocale";
export default function AbsensiPage() {
const { t } = useLocale();
const filter = useAppSelector(state => state.filter.filter);
const {data: attendanceSummary, isLoading: isLoadingAttendanceSummary, isFetching: isFetchingAttendanceSummary} = useGetOrganizationAttendanceQuery(filter);
const {data: attendanceRangeStaff, isLoading: isLoadingAttendanceRangeStaff, isFetching: isFetchingAttendanceRangeStaff} = useGetAttendanceRangeQuery({
...filter,
job_name: "STAFF"
});
const {data: attendanceRangeNonStaff, isLoading: isLoadingAttendanceRangeNonStaff, isFetching: isFetchingAttendanceRangeNonStaff} = useGetAttendanceRangeQuery({
...filter,
job_name: "NON-STAFF"
});
const {data: attendanceRangeHarvester, isLoading: isLoadingAttendanceRangeHarvester, isFetching: isFetchingAttendanceRangeHarvester} = useGetAttendanceRangeQuery({
...filter,
job_name: "HARVESTER"
});
const {data: attendanceRangeMaintenance, isLoading: isLoadingAttendanceRangeMaintenance, isFetching: isFetchingAttendanceRangeMaintenance} = useGetAttendanceRangeQuery({
...filter,
job_name: "MAINTENANCE"
});
const {data: montlyAttendance, isLoading: isLoadingMonthlyAttendance, isFetching: isFetchingMonthlyAttendance} = useGetMonthlyAttendanceQuery(filter);
// Combine all loading states (both initial loading and refetching)
const isLoading = isLoadingAttendanceSummary || isLoadingAttendanceRangeStaff ||
isLoadingAttendanceRangeNonStaff || isLoadingAttendanceRangeHarvester ||
isLoadingAttendanceRangeMaintenance || isLoadingMonthlyAttendance ||
isFetchingAttendanceSummary || isFetchingAttendanceRangeStaff ||
isFetchingAttendanceRangeNonStaff || isFetchingAttendanceRangeHarvester ||
isFetchingAttendanceRangeMaintenance || isFetchingMonthlyAttendance;
// Show loader while any data is loading
if (isLoading) {
return ;
}
return (
{t('attendance.kehadiranStaff')}
{attendanceRangeStaff ? (
({name: e.range, value: e.count, label: `${e.range} HK`}))}
cx="50%"
cy="50%"
innerRadius="40%"
outerRadius="70%"
paddingAngle={0}
dataKey="value"
// label={({name, value}) => `${name} HK`}
labelLine={false}
>
{attendanceRangeStaff.map((entry, index) => {
const colors = ["#E65550","#8A5FB1","#69C9C9","#F08431","#F6C421", "#3B82F6"];
return | ;
})}
[`${Number(value).toLocaleString('id-ID')} ${t('common.employees')}`, name]}
/>
) : (
{t('common.dataNotAvailable')}
)}
{t('attendance.kehadiranNonStaff')}
{attendanceRangeNonStaff ? (
({name: e.range, value: e.count, label: `${e.range} HK`}))}
cx="50%"
cy="50%"
innerRadius="40%"
outerRadius="70%"
paddingAngle={0}
dataKey="value"
// label={({name, value}) => `${name} HK`}
labelLine={false}
>
{attendanceRangeNonStaff.map((entry, index) => {
const colors = ["#E65550","#8A5FB1","#69C9C9","#F08431","#F6C421", "#3B82F6"];
return | ;
})}
[`${Number(value).toLocaleString('id-ID')} ${t('common.employees')}`, name]}
/>
) : (
{t('common.dataNotAvailable')}
)}
{t('attendance.kehadiranPemanen')}
{attendanceRangeHarvester ? (
({name: e.range, value: e.count, label: `${e.range} HK`}))}
cx="50%"
cy="50%"
innerRadius="65%"
outerRadius="90%"
paddingAngle={0}
dataKey="value"
// label={({name, value}) => `${name} HK`}
labelLine={false}
>
{attendanceRangeHarvester.map((entry, index) => {
const colors = ["#E65550","#8A5FB1","#69C9C9","#F08431","#F6C421","#3B82F6"];
return | ;
})}
[`${value} ${t('common.employees')}`, name]}
/>
) : (
{t('common.dataNotAvailable')}
)}
{t('attendance.kehadiranPerawatan')}
{attendanceRangeMaintenance ? (
({name: e.range, value: e.count, label: `${e.range} HK`}))}
cx="50%"
cy="50%"
innerRadius="65%"
outerRadius="90%"
paddingAngle={0}
dataKey="value"
// label={({name, value}) => `${name} HK`}
labelLine={false}
>
{attendanceRangeMaintenance.map((entry, index) => {
const colors = ["#E65550","#8A5FB1","#69C9C9","#F08431","#F6C421","#3B82F6"];
return | ;
})}
[`${Number(value).toLocaleString('id-ID')} ${t('common.employees')}`, name]}
/>
) : (
{t('common.dataNotAvailable')}
)}
{t('attendance.dataKehadiranKaryawan')}
{attendanceSummary ? (
({
...item,
countPercent: item.workdays > 0 ? (item.count / item.workdays) * 100 : 0,
absentPercent: item.workdays > 0 ? (item.absent / item.workdays) * 100 : 0
})).sort((a, b) => b.countPercent - a.countPercent)}
margin={{ top: 20, right: 30, left: 20, bottom: 5 }}
>
{/* */}
`${value}%`}
domain={[0, 100]}
hide
/>
{
const orgData = attendanceSummary.find(e => e.organization_code === props.payload.organization_code);
if (name === t('attendance.hadir')) {
return [`${Number(orgData?.count || 0).toLocaleString('id-ID')} ${t('common.hariKerja')}`, t('attendance.hadir')];
} else {
return [`${Number(orgData?.absent || 0).toLocaleString('id-ID')} ${t('common.hariKerja')}`, t('attendance.tidakHadir')];
}
}}
labelFormatter={(label) => {
const orgData = attendanceSummary.find(e => e.organization_code === label);
const percentage = Math.round(orgData?.count! / orgData?.workdays! * 100);
return `${orgData?.organization_name} (${percentage}%)`;
}}
/>
) : (
{t('common.dataNotAvailable')}
)}
{t('attendance.dataAbsensiPerbulan')}
{montlyAttendance && (
({
...item,
percentage: item.workdays > 0 ? Math.round((item.count / item.workdays) * 100) : 0,
month: formatDate(new Date(item.date), "MMM")
}))}
margin={{ top: 20, right: 30, left: 20, bottom: 5 }}
>
{/* */}
{
if (payload && payload[0]) {
return formatDate(new Date(payload[0].payload.date), "MMMM yyyy");
}
return value;
}}
formatter={(value, name) => {
if (name === t('attendance.persentase')) {
return [`${value}%`, name];
}
return [value, name];
}}
/>
)}
);
}