import React from "react"; import { useEffect, useState } from "react"; import { useSelector } from "react-redux"; import { useEmployeesByProjectAllocated, useProjects, } from "../../hooks/useProjects"; import ReactApexChart from "react-apexcharts"; import Chart from "react-apexcharts"; const ProjectOverview = ({ project }) => { const { projects } = useProjects(); const [current_project, setCurrentProject] = useState( projects.find((pro) => pro.id == project) ); const selectedProject = useSelector( (store) => store.localVariables.projectId ); const getProgressInPercentage = (planned, completed) => { if (completed && planned) return (completed * 100) / planned; else return 0; }; //let project_detail = projects.find((pro) => pro.id == project); // Utility function to check if a number has a decimal part const hasDecimal = (num) => { // Convert to string and check for a decimal point // Or, check if the number is not equal to its integer part return num % 1 !== 0; }; // FormattedNumber component to display numbers with conditional decimal places function FormattedNumber(value, locale = "en-US") { // Ensure the value is a number const numericValue = parseFloat(value); // Handle non-numeric values gracefully if (isNaN(numericValue)) { return 0; } let options = {}; // Determine formatting options based on whether the number has a decimal part if (hasDecimal(numericValue)) { // If it has a decimal, format to exactly two decimal places options = { minimumFractionDigits: 2, maximumFractionDigits: 2, }; } else { // If it's a whole number, format to zero decimal places options = { minimumFractionDigits: 0, maximumFractionDigits: 0, }; } // Use Intl.NumberFormat for robust and locale-aware formatting const formattedString = new Intl.NumberFormat(locale, options).format( numericValue ); return formattedString; } const getRadialBarOptions = (percentage) => { return { chart: { height: 350, type: "radialBar", sparkline: { // Often used with gauges for a minimalist look enabled: true, }, }, plotOptions: { radialBar: { startAngle: -90, // Start the gauge from the left (bottom-left) endAngle: 90, // End the gauge at the right (bottom-right) hollow: { size: "70%", // Size of the hollow part of the bar }, dataLabels: { show: true, name: { show: true, fontSize: "16px", fontFamily: "Inter, sans-serif", color: "#6B7280", // Tailwind gray-500 offsetY: -10, }, value: { show: true, fontSize: "28px", fontFamily: "Inter, sans-serif", color: "#374151", // Tailwind gray-700 offsetY: 20, formatter: function (val) { return FormattedNumber(val) + "%"; // Format value as percentage }, }, }, track: { background: "#E5E7EB", // Tailwind gray-200 for the track strokeWidth: "97%", margin: 5, // margin in between segments dropShadow: { enabled: true, top: 2, left: 0, blur: 4, opacity: 0.15, }, }, }, }, fill: { type: "gradient", gradient: { shade: "dark", type: "horizontal", shadeIntensity: 0.5, gradientToColors: ["#6366F1"], // Tailwind indigo-500 inverseColors: true, opacityFrom: 1, opacityTo: 1, stops: [0, 100], }, }, stroke: { lineCap: "round", }, labels: ["Progress"], series: [percentage], }; }; const [radialPercentage, setRadialPercentage] = useState(75); // Initial percentage const radialBarOptions = getRadialBarOptions(radialPercentage); useEffect(() => { if (current_project) { let val = getProgressInPercentage( current_project.plannedWork, current_project.completedWork ); setRadialPercentage(val); } else setRadialPercentage(0); }, [current_project]); useEffect(() => { setCurrentProject(projects.find((pro) => pro.id == selectedProject)); if (current_project) { let val = getProgressInPercentage( current_project.plannedWork, current_project.completedWork ); setRadialPercentage(val); } else setRadialPercentage(0); }, [selectedProject]); return (
{" "} Project Statistics
); }; export default ProjectOverview;