mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-24 15:25:46 +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 Card from '@/components/Card';
|
||||||
import UniformityBarChart from '@/components/pages/uniformity/chart/UniformityBarChart';
|
import UniformityBarChart from '@/components/pages/uniformity/chart/UniformityBarChart';
|
||||||
import UniformityGaugeChart from '@/components/pages/uniformity/chart/UniformityGaugeChart';
|
import UniformityGaugeChart from '@/components/pages/uniformity/chart/UniformityGaugeChart';
|
||||||
|
import UniformityBarChartSkeleton from './skeleton/UniformityBarChartSkeleton';
|
||||||
|
|
||||||
interface BarChartData {
|
interface BarChartData {
|
||||||
name: string;
|
name: string;
|
||||||
@@ -20,50 +21,50 @@ interface GaugeChartData {
|
|||||||
const UniformityChart = () => {
|
const UniformityChart = () => {
|
||||||
// TODO: Replace with actual API call
|
// TODO: Replace with actual API call
|
||||||
const barChartData: BarChartData[] = [
|
const barChartData: BarChartData[] = [
|
||||||
{
|
// {
|
||||||
name: '48-52',
|
// name: '48-52',
|
||||||
uv: 80,
|
// uv: 80,
|
||||||
},
|
// },
|
||||||
{
|
// {
|
||||||
name: '52-56',
|
// name: '52-56',
|
||||||
uv: 120,
|
// uv: 120,
|
||||||
},
|
// },
|
||||||
{
|
// {
|
||||||
name: '56-60',
|
// name: '56-60',
|
||||||
uv: 160,
|
// uv: 160,
|
||||||
},
|
// },
|
||||||
{
|
// {
|
||||||
name: '60-64',
|
// name: '60-64',
|
||||||
uv: 200,
|
// uv: 200,
|
||||||
},
|
// },
|
||||||
{
|
// {
|
||||||
name: '64-68',
|
// name: '64-68',
|
||||||
uv: 160,
|
// uv: 160,
|
||||||
},
|
// },
|
||||||
{
|
// {
|
||||||
name: '68-72',
|
// name: '68-72',
|
||||||
uv: 120,
|
// uv: 120,
|
||||||
},
|
// },
|
||||||
{
|
// {
|
||||||
name: '72-76',
|
// name: '72-76',
|
||||||
uv: 80,
|
// uv: 80,
|
||||||
},
|
// },
|
||||||
{
|
// {
|
||||||
name: '76-80',
|
// name: '76-80',
|
||||||
uv: 120,
|
// uv: 120,
|
||||||
},
|
// },
|
||||||
{
|
// {
|
||||||
name: '84-88',
|
// name: '84-88',
|
||||||
uv: 160,
|
// uv: 160,
|
||||||
},
|
// },
|
||||||
{
|
// {
|
||||||
name: '88-92',
|
// name: '88-92',
|
||||||
uv: 200,
|
// uv: 200,
|
||||||
},
|
// },
|
||||||
{
|
// {
|
||||||
name: '92-96',
|
// name: '92-96',
|
||||||
uv: 160,
|
// uv: 160,
|
||||||
},
|
// },
|
||||||
];
|
];
|
||||||
|
|
||||||
// TODO: Replace with actual API call
|
// TODO: Replace with actual API call
|
||||||
@@ -87,26 +88,43 @@ const UniformityChart = () => {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div className='w-full h-full flex items-center justify-center'>
|
<div className='w-full h-full flex items-center justify-center'>
|
||||||
<UniformityBarChart data={barChartData} />
|
{barChartData.length === 0 ? (
|
||||||
|
<UniformityBarChartSkeleton />
|
||||||
|
) : (
|
||||||
|
<UniformityBarChart data={barChartData} />
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</Card>
|
</Card>
|
||||||
<Card
|
{gaugeChartData.value === 0 ? (
|
||||||
variant='bordered'
|
<Card
|
||||||
title='Weekly Performance ⓘ'
|
variant='bordered'
|
||||||
className={{
|
title='Weekly Performance ⓘ'
|
||||||
wrapper: 'xl:col-span-1 2xl:col-span-1 w-full',
|
className={{
|
||||||
body: 'p-4',
|
wrapper: 'xl:col-span-1 2xl:col-span-1 w-full',
|
||||||
}}
|
body: 'h-96',
|
||||||
>
|
}}
|
||||||
<UniformityGaugeChart
|
>
|
||||||
value={gaugeChartData.value}
|
<UniformityBarChartSkeleton />
|
||||||
label={gaugeChartData.label}
|
</Card>
|
||||||
kandang={gaugeChartData.kandang}
|
) : (
|
||||||
week={gaugeChartData.week}
|
<Card
|
||||||
currentValue={gaugeChartData.currentValue}
|
variant='bordered'
|
||||||
totalValue={gaugeChartData.totalValue}
|
title='Weekly Performance ⓘ'
|
||||||
/>
|
className={{
|
||||||
</Card>
|
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>
|
</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