refactor(FE): Highlight ideal ranges in Uniformity charts

This commit is contained in:
rstubryan
2026-01-05 15:29:52 +07:00
parent fd32b55ad9
commit c24aebe02d
2 changed files with 73 additions and 21 deletions
@@ -1,13 +1,15 @@
import React from 'react'; import React, { useMemo } from 'react';
import Card from '@/components/Card'; import Card from '@/components/Card';
import UniformityBarChart from '@/components/pages/production/uniformity/chart/UniformityBarChart'; import UniformityBarChart from '@/components/pages/production/uniformity/chart/UniformityBarChart';
import UniformityGaugeChart from '@/components/pages/production/uniformity/chart/UniformityGaugeChart'; import UniformityGaugeChart from '@/components/pages/production/uniformity/chart/UniformityGaugeChart';
import UniformityBarChartSkeleton from '@/components/pages/production/uniformity/skeleton/UniformityBarChartSkeleton'; import UniformityBarChartSkeleton from '@/components/pages/production/uniformity/skeleton/UniformityBarChartSkeleton';
import UniformityGaugeChartSkeleton from '@/components/pages/production/uniformity/skeleton/UniformityGaugeChartSkeleton'; import UniformityGaugeChartSkeleton from '@/components/pages/production/uniformity/skeleton/UniformityGaugeChartSkeleton';
import { UniformityDetailItem } from '@/types/api/production/uniformity';
interface BarChartData { interface BarChartData {
name: string; name: string;
uv: number; uv: number;
isIdeal?: boolean;
} }
interface GaugeChartData { interface GaugeChartData {
@@ -19,9 +21,18 @@ interface GaugeChartData {
totalValue?: number; totalValue?: number;
} }
const UniformityChart = () => { interface UniformityChartProps {
// TODO: Replace with actual API call barChartData?: BarChartData[];
const barChartData: BarChartData[] = [ gaugeChartData?: GaugeChartData;
uniformityDetails?: UniformityDetailItem[];
}
const UniformityChart = ({
barChartData: initialBarChartData,
gaugeChartData: initialGaugeChartData,
uniformityDetails,
}: UniformityChartProps) => {
const defaultBarChartData: BarChartData[] = [
{ {
name: '48-52', name: '48-52',
uv: 80, uv: 80,
@@ -68,16 +79,7 @@ const UniformityChart = () => {
}, },
]; ];
// TODO: Replace with actual API call const defaultGaugeChartData: GaugeChartData = {
// const gaugeChartData: GaugeChartData = {
// value: 0,
// label: '',
// week: 'Week 2',
// currentValue: 512,
// totalValue: 1024,
// };
const gaugeChartData: GaugeChartData = {
value: 52, value: 52,
label: 'Uniformity', label: 'Uniformity',
week: 'Week 2', week: 'Week 2',
@@ -85,6 +87,48 @@ const UniformityChart = () => {
totalValue: 1024, totalValue: 1024,
}; };
const defaultUniformityDetails: UniformityDetailItem[] = [
{ id: 1, weight: 61, range: 'Ideal' },
{ id: 2, weight: 62, range: 'Ideal' },
{ id: 3, weight: 63, range: 'Ideal' },
{ id: 4, weight: 64, range: 'Ideal' },
{ id: 5, weight: 65, range: 'Ideal' },
{ id: 6, weight: 66, range: 'Ideal' },
{ id: 7, weight: 67, range: 'Ideal' },
];
const detailsToUse = uniformityDetails || defaultUniformityDetails;
const barChartData = useMemo(() => {
const dataToProcess = initialBarChartData || defaultBarChartData;
if (!detailsToUse || detailsToUse.length === 0) {
return dataToProcess;
}
return dataToProcess.map((bar) => {
const rangeMatch = bar.name.match(/(\d+)-(\d+)/);
if (!rangeMatch) return bar;
const minWeight = parseInt(rangeMatch[1], 10);
const maxWeight = parseInt(rangeMatch[2], 10);
const hasIdealWeight = detailsToUse.some((detail) => {
const weight = detail.weight;
return (
detail.range === 'Ideal' && weight >= minWeight && weight <= maxWeight
);
});
return {
...bar,
isIdeal: hasIdealWeight,
};
});
}, [initialBarChartData, detailsToUse]);
const gaugeChartData = initialGaugeChartData || defaultGaugeChartData;
return ( return (
<section className='w-full grid grid-cols-1 xl:grid-cols-2 2xl:grid-cols-4 gap-4'> <section className='w-full grid grid-cols-1 xl:grid-cols-2 2xl:grid-cols-4 gap-4'>
<Card <Card
@@ -103,7 +147,7 @@ const UniformityChart = () => {
)} )}
</div> </div>
</Card> </Card>
{gaugeChartData.value === 0 ? ( {gaugeChartData && gaugeChartData.value === 0 ? (
<Card <Card
variant='bordered' variant='bordered'
title='Weekly Performance ⓘ' title='Weekly Performance ⓘ'
@@ -114,7 +158,7 @@ const UniformityChart = () => {
> >
<UniformityGaugeChartSkeleton /> <UniformityGaugeChartSkeleton />
</Card> </Card>
) : ( ) : gaugeChartData ? (
<Card <Card
variant='bordered' variant='bordered'
title='Weekly Performance ⓘ' title='Weekly Performance ⓘ'
@@ -131,7 +175,7 @@ const UniformityChart = () => {
totalValue={gaugeChartData.totalValue} totalValue={gaugeChartData.totalValue}
/> />
</Card> </Card>
)} ) : null}
</section> </section>
); );
}; };
@@ -3,6 +3,7 @@ import {
Bar, Bar,
BarChart, BarChart,
CartesianGrid, CartesianGrid,
Cell,
Rectangle, Rectangle,
ResponsiveContainer, ResponsiveContainer,
Tooltip, Tooltip,
@@ -25,6 +26,7 @@ interface CustomTooltipProps {
interface BarChartData { interface BarChartData {
name: string; name: string;
uv: number; uv: number;
isIdeal?: boolean;
} }
interface UniformityBarChartProps { interface UniformityBarChartProps {
@@ -105,9 +107,6 @@ const UniformityBarChart: React.FC<UniformityBarChartProps> = ({ data }) => {
<Bar <Bar
name='Birds' name='Birds'
dataKey='uv' dataKey='uv'
fill='#FFFFFF'
stroke='#DDD'
strokeWidth={2}
radius={[25, 25, 0, 0]} radius={[25, 25, 0, 0]}
activeBar={ activeBar={
<Rectangle <Rectangle
@@ -117,7 +116,16 @@ const UniformityBarChart: React.FC<UniformityBarChartProps> = ({ data }) => {
radius={[25, 25, 0, 0]} radius={[25, 25, 0, 0]}
/> />
} }
/> >
{data.map((entry, index) => (
<Cell
key={`cell-${index}`}
fill={entry.isIdeal ? 'url(#activeBarGradient)' : '#FFFFFF'}
stroke={entry.isIdeal ? '#18181B' : '#DDD'}
strokeWidth={entry.isIdeal ? 0 : 2}
/>
))}
</Bar>
</BarChart> </BarChart>
</ResponsiveContainer> </ResponsiveContainer>
); );