249 lines
6.8 KiB
TypeScript
249 lines
6.8 KiB
TypeScript
'use client'
|
|
|
|
// React Imports
|
|
import type { SyntheticEvent } from 'react'
|
|
import { useState } from 'react'
|
|
|
|
// Next Imports
|
|
import dynamic from 'next/dynamic'
|
|
|
|
// MUI Imports
|
|
import TabContext from '@mui/lab/TabContext'
|
|
import TabList from '@mui/lab/TabList'
|
|
import TabPanel from '@mui/lab/TabPanel'
|
|
import Card from '@mui/material/Card'
|
|
import CardContent from '@mui/material/CardContent'
|
|
import CardHeader from '@mui/material/CardHeader'
|
|
import Tab from '@mui/material/Tab'
|
|
import Typography from '@mui/material/Typography'
|
|
import type { Theme } from '@mui/material/styles'
|
|
import { useTheme } from '@mui/material/styles'
|
|
|
|
// Third Party Imports
|
|
import type { ApexOptions } from 'apexcharts'
|
|
import classnames from 'classnames'
|
|
|
|
// Components Imports
|
|
import CustomAvatar from '@core/components/mui/Avatar'
|
|
import OptionMenu from '@core/components/option-menu'
|
|
import Loading from '../../../components/layout/shared/Loading'
|
|
import { formatShortCurrency } from '../../../utils/transform'
|
|
|
|
// Styled Component Imports
|
|
const AppReactApexCharts = dynamic(() => import('@/libs/styles/AppReactApexCharts'))
|
|
|
|
type ApexChartSeries = NonNullable<ApexOptions['series']>
|
|
type ApexChartSeriesData = Exclude<ApexChartSeries[0], number>
|
|
|
|
type TabType = {
|
|
type: string
|
|
avatarIcon: string
|
|
date: any
|
|
series: ApexChartSeries
|
|
}
|
|
|
|
const renderTabs = (tabData: TabType[], value: string) => {
|
|
return tabData.map((item, index) => (
|
|
<Tab
|
|
key={index}
|
|
value={item.type}
|
|
className='mie-4'
|
|
label={
|
|
<div
|
|
className={classnames(
|
|
'flex flex-col items-center justify-center gap-2 is-[110px] bs-[100px] border rounded-xl',
|
|
item.type === value ? 'border-solid border-[var(--mui-palette-primary-main)]' : 'border-dashed'
|
|
)}
|
|
>
|
|
<CustomAvatar variant='rounded' skin='light' size={38} {...(item.type === value && { color: 'primary' })}>
|
|
<i className={classnames('text-[22px]', { 'text-textSecondary': item.type !== value }, item.avatarIcon)} />
|
|
</CustomAvatar>
|
|
<Typography className='font-medium capitalize' color='text.primary'>
|
|
{item.type}
|
|
</Typography>
|
|
</div>
|
|
}
|
|
/>
|
|
))
|
|
}
|
|
|
|
const renderTabPanels = (tabData: TabType[], theme: Theme, options: ApexOptions, colors: string[]) => {
|
|
return tabData.map((item, index) => {
|
|
const max = Math.max(...((item.series[0] as ApexChartSeriesData).data as number[]))
|
|
const seriesIndex = ((item.series[0] as ApexChartSeriesData).data as number[]).indexOf(max)
|
|
|
|
const finalColors = colors.map((color, i) => (seriesIndex === i ? 'var(--mui-palette-primary-main)' : color))
|
|
|
|
return (
|
|
<TabPanel key={index} value={item.type} className='!p-0'>
|
|
<AppReactApexCharts
|
|
type='bar'
|
|
height={360}
|
|
width='100%'
|
|
options={{ ...options, colors: finalColors }}
|
|
series={item.series}
|
|
/>
|
|
</TabPanel>
|
|
)
|
|
})
|
|
}
|
|
|
|
const EarningReportsWithTabs = ({ data }: { data: TabType[] }) => {
|
|
// States
|
|
const [value, setValue] = useState(data[0].type)
|
|
|
|
// Hooks
|
|
const theme = useTheme()
|
|
|
|
// Vars
|
|
const disabledText = 'var(--mui-palette-text-disabled)'
|
|
|
|
const handleChange = (event: SyntheticEvent, newValue: string) => {
|
|
setValue(newValue)
|
|
}
|
|
|
|
const colors = Array(9).fill('var(--mui-palette-primary-lightOpacity)')
|
|
|
|
const options: ApexOptions = {
|
|
chart: {
|
|
parentHeightOffset: 0,
|
|
toolbar: { show: false }
|
|
},
|
|
plotOptions: {
|
|
bar: {
|
|
borderRadius: 6,
|
|
distributed: true,
|
|
columnWidth: '33%',
|
|
borderRadiusApplication: 'end',
|
|
dataLabels: { position: 'top' }
|
|
}
|
|
},
|
|
legend: { show: false },
|
|
tooltip: { enabled: false },
|
|
dataLabels: {
|
|
offsetY: -11,
|
|
formatter: val => formatShortCurrency(Number(val)),
|
|
style: {
|
|
fontWeight: 500,
|
|
colors: ['var(--mui-palette-text-primary)'],
|
|
fontSize: theme.typography.body1.fontSize as string
|
|
}
|
|
},
|
|
colors,
|
|
states: {
|
|
hover: {
|
|
filter: { type: 'none' }
|
|
},
|
|
active: {
|
|
filter: { type: 'none' }
|
|
}
|
|
},
|
|
grid: {
|
|
show: false,
|
|
padding: {
|
|
top: -19,
|
|
left: -4,
|
|
right: 0,
|
|
bottom: -11
|
|
}
|
|
},
|
|
xaxis: {
|
|
axisTicks: { show: false },
|
|
axisBorder: { color: 'var(--mui-palette-divider)' },
|
|
categories: data.find(item => item.type === value)?.date,
|
|
labels: {
|
|
style: {
|
|
colors: disabledText,
|
|
fontFamily: theme.typography.fontFamily,
|
|
fontSize: theme.typography.body2.fontSize as string
|
|
}
|
|
}
|
|
},
|
|
yaxis: {
|
|
labels: {
|
|
offsetX: -18,
|
|
formatter: val => `${formatShortCurrency(Number(val))}`,
|
|
style: {
|
|
colors: disabledText,
|
|
fontFamily: theme.typography.fontFamily,
|
|
fontSize: theme.typography.body2.fontSize as string
|
|
}
|
|
}
|
|
},
|
|
responsive: [
|
|
{
|
|
breakpoint: 1450,
|
|
options: {
|
|
plotOptions: {
|
|
bar: { columnWidth: '35%' }
|
|
}
|
|
}
|
|
},
|
|
{
|
|
breakpoint: 600,
|
|
options: {
|
|
dataLabels: {
|
|
style: {
|
|
fontSize: theme.typography.body2.fontSize as string
|
|
}
|
|
},
|
|
plotOptions: {
|
|
bar: { columnWidth: '58%' }
|
|
}
|
|
}
|
|
},
|
|
{
|
|
breakpoint: 500,
|
|
options: {
|
|
plotOptions: {
|
|
bar: { columnWidth: '70%' }
|
|
}
|
|
}
|
|
}
|
|
]
|
|
}
|
|
|
|
return (
|
|
<Card>
|
|
<CardHeader
|
|
title='Product Reports'
|
|
subheader='Yearly Earnings Overview'
|
|
action={<OptionMenu options={['Last Week', 'Last Month', 'Last Year']} />}
|
|
/>
|
|
<CardContent>
|
|
<TabContext value={value}>
|
|
{data.length > 1 && (
|
|
<TabList
|
|
variant='scrollable'
|
|
scrollButtons='auto'
|
|
onChange={handleChange}
|
|
aria-label='earning report tabs'
|
|
className='!border-0 mbe-10'
|
|
sx={{
|
|
'& .MuiTabs-indicator': { display: 'none !important' },
|
|
'& .MuiTab-root': { padding: '0 !important', border: '0 !important' }
|
|
}}
|
|
>
|
|
{renderTabs(data, value)}
|
|
<Tab
|
|
disabled
|
|
value='add'
|
|
label={
|
|
<div className='flex flex-col items-center justify-center is-[110px] bs-[100px] border border-dashed rounded-xl'>
|
|
<CustomAvatar variant='rounded' size={34}>
|
|
<i className='tabler-plus text-textSecondary' />
|
|
</CustomAvatar>
|
|
</div>
|
|
}
|
|
/>
|
|
</TabList>
|
|
)}
|
|
{renderTabPanels(data, theme, options, colors)}
|
|
</TabContext>
|
|
</CardContent>
|
|
</Card>
|
|
)
|
|
}
|
|
|
|
export default EarningReportsWithTabs
|