import { useState, useEffect, useRef, useLayoutEffect, useMemo, lazy, Suspense, } from 'react'; import { PieChart, Pie, Cell, Tooltip, ResponsiveContainer } from 'recharts'; import { TrendingUp, Package, IndianRupee } from 'lucide-react'; import './TopSellingProductsChart.scss'; import { useDispatch } from 'react-redux'; import { getSession } from '../../Services/Others'; import { changeBreadCrumb } from '../../Features/AppPage/CenterPage'; import dayjs from 'dayjs'; const DropDowns = lazy(() => import('../../Components/Forms/DropDown').then((module) => ({ default: module.DropDowns, })) ); const subDirectory = import.meta.env.BASE_URL; const items = [ { name: 'Home', link: `${subDirectory}app-page/home`, }, ]; const TopSellingProducts = ({ dates = [null, null], products = [], loading = false, totalPages, page = 1, setPage = () => {}, fetchProducts = () => {}, initialDate = true, }) => { const today = new Date(); const year = today.getFullYear(); const month = today.getMonth(); const formatDate = (date) => `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`; const intialFromDate = `${year}-${String(month + 1).padStart(2, '0')}-01`; const intialToDate = formatDate(today); const dispatch = useDispatch(); const AppId = getSession('AppId'); const CompId = getSession('CompId'); const BranchId = getSession('BranchId'); const [chartType, setChartType] = useState('bar'); const [metric, setMetric] = useState('sales'); const chartWrapperRef = useRef(null); const [containerWidth, setContainerWidth] = useState(800); // fallback const [windowWidth, setWindowWidth] = useState(window.innerWidth); const [hoveredItem, setHoveredItem] = useState(null); const [mousePosition, setMousePosition] = useState({ x: 0, y: 0 }); console.log(products?.[0]?.TotalCount, 'products'); const options = useMemo(() => { const total = products?.[0]?.TotalCount || 0; const perPage = 10; const totalPages = Math.ceil(total / perPage); const arr = []; for (let page = 1; page <= totalPages; page++) { const start = (page - 1) * perPage + 1; const end = Math.min(page * perPage, total); arr.push({ label: `${start}-${end}`, value: page, }); } return arr; }, [products?.[0]?.TotalCount]); useLayoutEffect(() => { if (!chartWrapperRef.current) return; const el = chartWrapperRef.current; // set initial width setContainerWidth(el.clientWidth || 800); // ResizeObserver to update container width precisely const ro = new ResizeObserver((entries) => { for (const entry of entries) { const w = Math.floor(entry.contentRect.width); if (w && w !== containerWidth) setContainerWidth(w); } }); ro.observe(el); return () => ro.disconnect(); // eslint-disable-next-line react-hooks/exhaustive-deps }, [chartWrapperRef.current]); // breakpoints const mobileBreakpoint = 430; // you said < 430px is problematic const isNarrow = containerWidth <= mobileBreakpoint; // compute sizes based on actual container width // make pie fill a good portion of container (leave some padding) const pieOuterRadius = Math.max( 48, Math.floor(containerWidth * (isNarrow ? 0.36 : 0.28)) ); const pieInnerRadius = Math.floor(pieOuterRadius * (isNarrow ? 0.5 : 0.55)); // height for ResponsiveContainer: tether to containerWidth so chart stays proportional const responsiveHeight = Math.max( 220, Math.floor(containerWidth * (isNarrow ? 0.62 : 0.5)) ); // tweak minAngle: small screens should allow smaller minAngle so slices remain visible const minAngle = isNarrow ? 4 : 8; console.log(pieOuterRadius, 'pieOuterRadius'); // const COLORS = ['#2563eb', '#7c3aed', '#db2777', '#ea580c', '#16a34a', '#0891b2', '#d97706', '#65a30d', '#4f46e5', '#0d9488']; const COLORS = [ '#4f8df5', // lighter blue (was #2563eb) '#9a6df3', // lighter violet (was #7c3aed) '#e95b96', // lighter pink (was #db2777) '#f48b3c', // lighter orange (was #ea580c) '#34c86a', // lighter green (was #16a34a) '#33bcd4', // lighter cyan (was #0891b2) '#e39a1a', // lighter amber (was #d97706) '#8bc329', // lighter lime (was #65a30d) '#6d63ef', // lighter indigo (was #4f46e5) '#35bfa9', // lighter teal (was #0d9488) ]; useEffect(() => { try { dispatch(changeBreadCrumb({ items: items })); } catch (error) { console.log(error?.message, 'error displaying breadcrumbs'); } }, []); const CustomTooltip = ({ active, payload }) => { if (active && payload && payload?.[0]) { const product = payload?.[0]?.payload; return (
{product?.ProdName} - {product?.UOMName}
{product?.BrandName ? (Brand: {product?.BrandName}
) : null}Variants:
{product?.variantDetails?.map((variant, idx) => (Total Products
{products?.length}
Total Sales
{products?.reduce( (sum, p) => sum + (p?.TotalSoldQty || 0), 0 )}
Total Revenue
₹ {products ?.reduce((sum, p) => sum + (p?.TotalRevenue || 0), 0) ?.toFixed(2)}