mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-20 21:41:57 +00:00
feat(FE-438): Add UniformityBarChartSkeleton and use it
This commit is contained in:
@@ -2,6 +2,7 @@ import React from 'react';
|
||||
import Card from '@/components/Card';
|
||||
import UniformityBarChart from '@/components/pages/uniformity/chart/UniformityBarChart';
|
||||
import UniformityGaugeChart from '@/components/pages/uniformity/chart/UniformityGaugeChart';
|
||||
import UniformityBarChartSkeleton from './skeleton/UniformityBarChartSkeleton';
|
||||
|
||||
interface BarChartData {
|
||||
name: string;
|
||||
@@ -20,50 +21,50 @@ interface GaugeChartData {
|
||||
const UniformityChart = () => {
|
||||
// TODO: Replace with actual API call
|
||||
const barChartData: BarChartData[] = [
|
||||
{
|
||||
name: '48-52',
|
||||
uv: 80,
|
||||
},
|
||||
{
|
||||
name: '52-56',
|
||||
uv: 120,
|
||||
},
|
||||
{
|
||||
name: '56-60',
|
||||
uv: 160,
|
||||
},
|
||||
{
|
||||
name: '60-64',
|
||||
uv: 200,
|
||||
},
|
||||
{
|
||||
name: '64-68',
|
||||
uv: 160,
|
||||
},
|
||||
{
|
||||
name: '68-72',
|
||||
uv: 120,
|
||||
},
|
||||
{
|
||||
name: '72-76',
|
||||
uv: 80,
|
||||
},
|
||||
{
|
||||
name: '76-80',
|
||||
uv: 120,
|
||||
},
|
||||
{
|
||||
name: '84-88',
|
||||
uv: 160,
|
||||
},
|
||||
{
|
||||
name: '88-92',
|
||||
uv: 200,
|
||||
},
|
||||
{
|
||||
name: '92-96',
|
||||
uv: 160,
|
||||
},
|
||||
// {
|
||||
// name: '48-52',
|
||||
// uv: 80,
|
||||
// },
|
||||
// {
|
||||
// name: '52-56',
|
||||
// uv: 120,
|
||||
// },
|
||||
// {
|
||||
// name: '56-60',
|
||||
// uv: 160,
|
||||
// },
|
||||
// {
|
||||
// name: '60-64',
|
||||
// uv: 200,
|
||||
// },
|
||||
// {
|
||||
// name: '64-68',
|
||||
// uv: 160,
|
||||
// },
|
||||
// {
|
||||
// name: '68-72',
|
||||
// uv: 120,
|
||||
// },
|
||||
// {
|
||||
// name: '72-76',
|
||||
// uv: 80,
|
||||
// },
|
||||
// {
|
||||
// name: '76-80',
|
||||
// uv: 120,
|
||||
// },
|
||||
// {
|
||||
// name: '84-88',
|
||||
// uv: 160,
|
||||
// },
|
||||
// {
|
||||
// name: '88-92',
|
||||
// uv: 200,
|
||||
// },
|
||||
// {
|
||||
// name: '92-96',
|
||||
// uv: 160,
|
||||
// },
|
||||
];
|
||||
|
||||
// TODO: Replace with actual API call
|
||||
@@ -87,26 +88,43 @@ const UniformityChart = () => {
|
||||
}}
|
||||
>
|
||||
<div className='w-full h-full flex items-center justify-center'>
|
||||
<UniformityBarChart data={barChartData} />
|
||||
{barChartData.length === 0 ? (
|
||||
<UniformityBarChartSkeleton />
|
||||
) : (
|
||||
<UniformityBarChart data={barChartData} />
|
||||
)}
|
||||
</div>
|
||||
</Card>
|
||||
<Card
|
||||
variant='bordered'
|
||||
title='Weekly Performance ⓘ'
|
||||
className={{
|
||||
wrapper: 'xl:col-span-1 2xl:col-span-1 w-full',
|
||||
body: 'p-4',
|
||||
}}
|
||||
>
|
||||
<UniformityGaugeChart
|
||||
value={gaugeChartData.value}
|
||||
label={gaugeChartData.label}
|
||||
kandang={gaugeChartData.kandang}
|
||||
week={gaugeChartData.week}
|
||||
currentValue={gaugeChartData.currentValue}
|
||||
totalValue={gaugeChartData.totalValue}
|
||||
/>
|
||||
</Card>
|
||||
{gaugeChartData.value === 0 ? (
|
||||
<Card
|
||||
variant='bordered'
|
||||
title='Weekly Performance ⓘ'
|
||||
className={{
|
||||
wrapper: 'xl:col-span-1 2xl:col-span-1 w-full',
|
||||
body: 'h-96',
|
||||
}}
|
||||
>
|
||||
<UniformityBarChartSkeleton />
|
||||
</Card>
|
||||
) : (
|
||||
<Card
|
||||
variant='bordered'
|
||||
title='Weekly Performance ⓘ'
|
||||
className={{
|
||||
wrapper: 'xl:col-span-1 2xl:col-span-1 w-full',
|
||||
body: 'p-4',
|
||||
}}
|
||||
>
|
||||
<UniformityGaugeChart
|
||||
value={gaugeChartData.value}
|
||||
label={gaugeChartData.label}
|
||||
kandang={gaugeChartData.kandang}
|
||||
week={gaugeChartData.week}
|
||||
currentValue={gaugeChartData.currentValue}
|
||||
totalValue={gaugeChartData.totalValue}
|
||||
/>
|
||||
</Card>
|
||||
)}
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
import Button from '@/components/Button';
|
||||
import { Icon } from '@iconify/react';
|
||||
|
||||
const LeftLegend = () => {
|
||||
return (
|
||||
<>
|
||||
<div className='w-4 h-30 bg-gray-200 rounded animate-pulse flex items-center justify-center self-center'></div>
|
||||
|
||||
<div className='grid grid-cols-1 justify-center items-center'>
|
||||
<div className='shrink-0 flex flex-col justify-center'>
|
||||
<div className='h-4 w-8 bg-gray-200 rounded animate-pulse' />
|
||||
</div>
|
||||
<div className='shrink-0 flex flex-col justify-center'>
|
||||
<div className='h-4 w-8 bg-gray-200 rounded animate-pulse' />
|
||||
</div>
|
||||
<div className='shrink-0 flex flex-col justify-center'>
|
||||
<div className='h-4 w-8 bg-gray-200 rounded animate-pulse' />
|
||||
</div>
|
||||
<div className='shrink-0 flex flex-col justify-center'>
|
||||
<div className='h-4 w-8 bg-gray-200 rounded animate-pulse' />
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const ChartArea = () => {
|
||||
const ranges = [
|
||||
'48-52',
|
||||
'52-56',
|
||||
'56-60',
|
||||
'60-64',
|
||||
'64-68',
|
||||
'68-72',
|
||||
'72-76',
|
||||
];
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className='flex-1 flex flex-col relative'>
|
||||
<div className='flex-1 ml-6 flex flex-col'>
|
||||
<div className='flex-1 relative flex flex-col justify-between py-4'>
|
||||
{[...Array(5)].map((_, index) => (
|
||||
<div
|
||||
key={`grid-${index}`}
|
||||
className='w-full border-b border-gray-200 absolute'
|
||||
style={{ top: `${(index / 4) * 100}%` }}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className='flex justify-between gap-10 px-4 py-2'>
|
||||
{ranges.map((range) => (
|
||||
<div
|
||||
key={range}
|
||||
className='flex-1 h-3 bg-gray-200 rounded animate-pulse'
|
||||
style={{ animationDelay: '0.5s' }}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className='flex justify-center pb-1'>
|
||||
<div className='h-3 w-28 bg-gray-200 rounded animate-pulse' />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const EmptyState = () => {
|
||||
return (
|
||||
<>
|
||||
<div className='absolute inset-0 flex flex-col items-center justify-center z-10 gap-2'>
|
||||
<div className='border border-[#18181B]/25 rounded-2xl p-1 flex items-center justify-center my-2'>
|
||||
<Button className='rounded-2xl border border-sky-500 bg-[#0069E0] text-white'>
|
||||
<Icon icon={'heroicons:funnel'} className='text-4xl text-whitd' />
|
||||
</Button>
|
||||
</div>
|
||||
<span className='text-xl font-semibold text-[#18181B80] leading-5'>
|
||||
No Filters Selected
|
||||
</span>
|
||||
<span className='text-xs font-light text-[#18181B80] leading-4 text-center max-w-xs px-4'>
|
||||
Please choose filters to narrow down your results and make your search
|
||||
easier.
|
||||
</span>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const UniformityBarChartSkeleton = () => {
|
||||
return (
|
||||
<div className='relative w-full h-full min-h-[300px] xl:min-h-[350px]'>
|
||||
<div className='flex h-full gap-4'>
|
||||
<LeftLegend />
|
||||
<ChartArea />
|
||||
</div>
|
||||
<EmptyState />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default UniformityBarChartSkeleton;
|
||||
Reference in New Issue
Block a user