feat: analytic
This commit is contained in:
@@ -1,123 +1,56 @@
|
||||
'use client'
|
||||
|
||||
// Next Imports
|
||||
import dynamic from 'next/dynamic'
|
||||
|
||||
// MUI Imports
|
||||
import Card from '@mui/material/Card'
|
||||
import Typography from '@mui/material/Typography'
|
||||
import CardContent from '@mui/material/CardContent'
|
||||
import CardHeader from '@mui/material/CardHeader'
|
||||
import { useTheme } from '@mui/material/styles'
|
||||
|
||||
// Third-party Imports
|
||||
import type { ApexOptions } from 'apexcharts'
|
||||
import classnames from 'classnames'
|
||||
import CustomAvatar, { CustomAvatarProps } from '../../../@core/components/mui/Avatar'
|
||||
import { ThemeColor } from '../../../@core/types'
|
||||
import { Skeleton, Typography } from '@mui/material'
|
||||
import { formatShortCurrency } from '../../../utils/transform'
|
||||
|
||||
// Styled Component Imports
|
||||
const AppReactApexCharts = dynamic(() => import('@/libs/styles/AppReactApexCharts'))
|
||||
type Props = {
|
||||
title: string
|
||||
value: number
|
||||
isLoading: boolean
|
||||
avatarIcon: string
|
||||
avatarSkin?: CustomAvatarProps['skin']
|
||||
avatarSize?: number
|
||||
avatarColor?: ThemeColor
|
||||
}
|
||||
|
||||
// Vars
|
||||
const series = [{ data: [77, 55, 23, 43, 77, 55, 89] }]
|
||||
const DistributedBarChartOrder = ({
|
||||
title,
|
||||
value,
|
||||
isLoading,
|
||||
avatarIcon,
|
||||
avatarSkin,
|
||||
avatarColor
|
||||
}: Props) => {
|
||||
|
||||
const DistributedBarChartOrder = () => {
|
||||
// Hooks
|
||||
const theme = useTheme()
|
||||
|
||||
// Vars
|
||||
const actionSelectedColor = 'var(--mui-palette-action-selected)'
|
||||
|
||||
const options: ApexOptions = {
|
||||
chart: {
|
||||
type: 'bar',
|
||||
stacked: false,
|
||||
parentHeightOffset: 0,
|
||||
toolbar: { show: false },
|
||||
sparkline: { enabled: true }
|
||||
},
|
||||
tooltip: { enabled: false },
|
||||
legend: { show: false },
|
||||
dataLabels: { enabled: false },
|
||||
colors: ['var(--mui-palette-primary-main)'],
|
||||
states: {
|
||||
hover: {
|
||||
filter: { type: 'none' }
|
||||
},
|
||||
active: {
|
||||
filter: { type: 'none' }
|
||||
}
|
||||
},
|
||||
plotOptions: {
|
||||
bar: {
|
||||
borderRadius: 3,
|
||||
horizontal: false,
|
||||
columnWidth: '32%',
|
||||
colors: {
|
||||
backgroundBarRadius: 5,
|
||||
backgroundBarColors: [
|
||||
actionSelectedColor,
|
||||
actionSelectedColor,
|
||||
actionSelectedColor,
|
||||
actionSelectedColor,
|
||||
actionSelectedColor
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
grid: {
|
||||
show: false,
|
||||
padding: {
|
||||
left: -3,
|
||||
right: 5,
|
||||
top: 15,
|
||||
bottom: 18
|
||||
}
|
||||
},
|
||||
xaxis: {
|
||||
labels: { show: false },
|
||||
axisTicks: { show: false },
|
||||
axisBorder: { show: false }
|
||||
},
|
||||
yaxis: { show: false },
|
||||
responsive: [
|
||||
{
|
||||
breakpoint: 1350,
|
||||
options: {
|
||||
plotOptions: {
|
||||
bar: { columnWidth: '45%' }
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
breakpoint: theme.breakpoints.values.lg,
|
||||
options: {
|
||||
plotOptions: {
|
||||
bar: { columnWidth: '20%' }
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
breakpoint: 600,
|
||||
options: {
|
||||
plotOptions: {
|
||||
bar: { columnWidth: '15%' }
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
if (isLoading) {
|
||||
return <Skeleton sx={{ bgcolor: 'grey.100' }} variant='rectangular' width={300} height={118} />
|
||||
}
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader title='Order' subheader='Last Week' className='pbe-0' />
|
||||
<CardContent className='flex flex-col'>
|
||||
<AppReactApexCharts type='bar' height={84} width='100%' options={options} series={series} />
|
||||
<div className='flex items-center justify-between flex-wrap gap-x-4 gap-y-0.5'>
|
||||
<Typography variant='h4' color='text.primary'>
|
||||
124k
|
||||
</Typography>
|
||||
<Typography variant='body2' color='success.main'>
|
||||
+12.6%
|
||||
</Typography>
|
||||
<CardContent>
|
||||
<div className='flex items-start justify-between'>
|
||||
<div className='flex-1'>
|
||||
<Typography variant='h6' color='text.disabled'>
|
||||
{title}
|
||||
</Typography>
|
||||
<Typography color='text.primary' variant='h4'>
|
||||
{formatShortCurrency(value)}
|
||||
</Typography>
|
||||
</div>
|
||||
<CustomAvatar variant='rounded' skin={avatarSkin} size={52} color={avatarColor}>
|
||||
<i className={classnames(avatarIcon, 'text-[28px]')} />
|
||||
</CustomAvatar>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
@@ -1,31 +1,33 @@
|
||||
'use client'
|
||||
|
||||
// React Imports
|
||||
import { useState } from 'react'
|
||||
import type { SyntheticEvent } from 'react'
|
||||
import { useState } from 'react'
|
||||
|
||||
// Next Imports
|
||||
import dynamic from 'next/dynamic'
|
||||
|
||||
// MUI Imports
|
||||
import Card from '@mui/material/Card'
|
||||
import CardHeader from '@mui/material/CardHeader'
|
||||
import CardContent from '@mui/material/CardContent'
|
||||
import Tab from '@mui/material/Tab'
|
||||
import TabContext from '@mui/lab/TabContext'
|
||||
import TabList from '@mui/lab/TabList'
|
||||
import TabPanel from '@mui/lab/TabPanel'
|
||||
import TabContext from '@mui/lab/TabContext'
|
||||
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 classnames from 'classnames'
|
||||
import type { ApexOptions } from 'apexcharts'
|
||||
import classnames from 'classnames'
|
||||
|
||||
// Components Imports
|
||||
import OptionMenu from '@core/components/option-menu'
|
||||
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'))
|
||||
@@ -33,39 +35,14 @@ const AppReactApexCharts = dynamic(() => import('@/libs/styles/AppReactApexChart
|
||||
type ApexChartSeries = NonNullable<ApexOptions['series']>
|
||||
type ApexChartSeriesData = Exclude<ApexChartSeries[0], number>
|
||||
|
||||
type TabCategory = 'orders' | 'sales' | 'profit' | 'income'
|
||||
|
||||
type TabType = {
|
||||
type: TabCategory
|
||||
type: string
|
||||
avatarIcon: string
|
||||
date: any
|
||||
series: ApexChartSeries
|
||||
}
|
||||
|
||||
// Vars
|
||||
const tabData: TabType[] = [
|
||||
{
|
||||
type: 'orders',
|
||||
avatarIcon: 'tabler-shopping-cart',
|
||||
series: [{ data: [28, 10, 46, 38, 15, 30, 35, 28, 8] }]
|
||||
},
|
||||
{
|
||||
type: 'sales',
|
||||
avatarIcon: 'tabler-chart-bar',
|
||||
series: [{ data: [35, 25, 15, 40, 42, 25, 48, 8, 30] }]
|
||||
},
|
||||
{
|
||||
type: 'profit',
|
||||
avatarIcon: 'tabler-currency-dollar',
|
||||
series: [{ data: [10, 22, 27, 33, 42, 32, 27, 22, 8] }]
|
||||
},
|
||||
{
|
||||
type: 'income',
|
||||
avatarIcon: 'tabler-chart-pie-2',
|
||||
series: [{ data: [5, 9, 12, 18, 20, 25, 30, 36, 48] }]
|
||||
}
|
||||
]
|
||||
|
||||
const renderTabs = (value: TabCategory) => {
|
||||
const renderTabs = (tabData: TabType[], value: string) => {
|
||||
return tabData.map((item, index) => (
|
||||
<Tab
|
||||
key={index}
|
||||
@@ -90,7 +67,7 @@ const renderTabs = (value: TabCategory) => {
|
||||
))
|
||||
}
|
||||
|
||||
const renderTabPanels = (value: TabCategory, theme: Theme, options: ApexOptions, colors: string[]) => {
|
||||
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)
|
||||
@@ -101,7 +78,7 @@ const renderTabPanels = (value: TabCategory, theme: Theme, options: ApexOptions,
|
||||
<TabPanel key={index} value={item.type} className='!p-0'>
|
||||
<AppReactApexCharts
|
||||
type='bar'
|
||||
height={233}
|
||||
height={360}
|
||||
width='100%'
|
||||
options={{ ...options, colors: finalColors }}
|
||||
series={item.series}
|
||||
@@ -111,9 +88,9 @@ const renderTabPanels = (value: TabCategory, theme: Theme, options: ApexOptions,
|
||||
})
|
||||
}
|
||||
|
||||
const EarningReportsWithTabs = () => {
|
||||
const EarningReportsWithTabs = ({ data }: { data: TabType[] }) => {
|
||||
// States
|
||||
const [value, setValue] = useState<TabCategory>('orders')
|
||||
const [value, setValue] = useState(data[0].type)
|
||||
|
||||
// Hooks
|
||||
const theme = useTheme()
|
||||
@@ -121,7 +98,7 @@ const EarningReportsWithTabs = () => {
|
||||
// Vars
|
||||
const disabledText = 'var(--mui-palette-text-disabled)'
|
||||
|
||||
const handleChange = (event: SyntheticEvent, newValue: TabCategory) => {
|
||||
const handleChange = (event: SyntheticEvent, newValue: string) => {
|
||||
setValue(newValue)
|
||||
}
|
||||
|
||||
@@ -145,7 +122,7 @@ const EarningReportsWithTabs = () => {
|
||||
tooltip: { enabled: false },
|
||||
dataLabels: {
|
||||
offsetY: -11,
|
||||
formatter: val => `${val}k`,
|
||||
formatter: val => formatShortCurrency(Number(val)),
|
||||
style: {
|
||||
fontWeight: 500,
|
||||
colors: ['var(--mui-palette-text-primary)'],
|
||||
@@ -173,7 +150,7 @@ const EarningReportsWithTabs = () => {
|
||||
xaxis: {
|
||||
axisTicks: { show: false },
|
||||
axisBorder: { color: 'var(--mui-palette-divider)' },
|
||||
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep'],
|
||||
categories: data.find(item => item.type === value)?.date,
|
||||
labels: {
|
||||
style: {
|
||||
colors: disabledText,
|
||||
@@ -185,7 +162,7 @@ const EarningReportsWithTabs = () => {
|
||||
yaxis: {
|
||||
labels: {
|
||||
offsetX: -18,
|
||||
formatter: val => `$${val}k`,
|
||||
formatter: val => `${formatShortCurrency(Number(val))}`,
|
||||
style: {
|
||||
colors: disabledText,
|
||||
fontFamily: theme.typography.fontFamily,
|
||||
@@ -235,31 +212,33 @@ const EarningReportsWithTabs = () => {
|
||||
/>
|
||||
<CardContent>
|
||||
<TabContext value={value}>
|
||||
<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(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(value, theme, options, colors)}
|
||||
{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>
|
||||
|
||||
@@ -88,12 +88,12 @@ const statusObj: StatusObj = {
|
||||
verified: { text: 'Verified', color: 'success' }
|
||||
}
|
||||
|
||||
const LastTransaction = ({ serverMode }: { serverMode: SystemMode }) => {
|
||||
const LastTransaction = () => {
|
||||
// Hooks
|
||||
const { mode } = useColorScheme()
|
||||
|
||||
// Vars
|
||||
const _mode = (mode === 'system' ? serverMode : mode) || serverMode
|
||||
const _mode = mode as SystemMode
|
||||
|
||||
return (
|
||||
<Card>
|
||||
|
||||
Reference in New Issue
Block a user