import { Box, Card, Flex, H3, Skeleton, styled, Text } from '@traefiklabs/faency'
import { Chart as ChartJs, ArcElement, Tooltip } from 'chart.js'
import { ReactNode, useEffect, useMemo, useState } from 'react'
import { Doughnut } from 'react-chartjs-2'
import { FaArrowRightLong } from 'react-icons/fa6'
import { Link as RouterLink, useNavigate } from 'react-router-dom'
import Status, { colorByStatus, StatusType } from './Status'
import { capitalizeFirstLetter } from 'utils/string'
ChartJs.register(ArcElement, Tooltip)
const Link = styled(RouterLink, {
textDecoration: 'none',
'&:hover': {
textDecoration: 'none',
},
})
type StatsCardType = {
children: ReactNode
}
const StatsCard = ({ children, ...props }: StatsCardType) => (
{children}
)
export type TraefikResourceStatsType = {
title?: string
errors: number
total: number
warnings: number
}
export type TraefikResourceStatsCardProps = TraefikResourceStatsType & {
linkTo: string
}
export type DataType = {
datasets: {
backgroundColor: string[]
data: (string | number)[]
}[]
labels?: string[]
}
const getPercent = (total: number, value: number) => (total > 0 ? ((value * 100) / total).toFixed(0) : 0)
const STATS_ATTRIBUTES: { status: StatusType; label: string }[] = [
{
status: 'enabled',
label: 'success',
},
{
status: 'warning',
label: 'warnings',
},
{
status: 'disabled',
label: 'errors',
},
]
const CustomLegend = ({
status,
label,
count,
total,
linkTo,
}: {
status: StatusType
label: string
count: number
total: number
linkTo: string
}) => {
return (
{capitalizeFirstLetter(label)}
{getPercent(total, count)}%
{count}
)
}
const TraefikResourceStatsCard = ({ title, errors, total, warnings, linkTo }: TraefikResourceStatsCardProps) => {
const navigate = useNavigate()
const defaultData = {
datasets: [
{
backgroundColor: [colorByStatus.enabled],
data: [1],
},
],
}
const [data, setData] = useState(defaultData)
const counts = useMemo(
() => ({
success: total - (errors + warnings),
warnings,
errors,
}),
[errors, total, warnings],
)
useEffect(() => {
if (counts.success + counts.warnings + counts.errors === 0) {
setData(defaultData)
return
}
const newData = {
datasets: [
{
backgroundColor: [colorByStatus.enabled, colorByStatus.warning, colorByStatus.error],
data: [counts.success, counts.warnings, counts.errors],
},
],
labels: ['Success', 'Warnings', 'Errors'],
}
setData(newData)
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [errors, warnings, total, counts])
const options = {
animation: {
duration: 1000,
},
plugins: {
legend: {
display: false,
},
},
tooltips: {
enabled: true,
},
maintainAspectRatio: false,
onClick: (_, activeEl) => {
navigate(`${linkTo}?status=${STATS_ATTRIBUTES[activeEl[0].index].status}`)
},
}
if (!errors && !total && !warnings) return null
return (
{title && (
{title && (
{title}
Explore
)}
)}
{STATS_ATTRIBUTES.map((i) => (
))}
)
}
export const StatsCardSkeleton = () => {
return (
)
}
export default TraefikResourceStatsCard