'use client' // 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 Typography from '@mui/material/Typography' import Box from '@mui/material/Box' import Button from '@mui/material/Button' // Third-party Imports import type { ApexOptions } from 'apexcharts' import Link from 'next/link' // Styled Component Imports const AppReactApexCharts = dynamic(() => import('@/libs/styles/AppReactApexCharts')) // Types interface Balance { amount: string | number label: string } interface ChartData { name: string data: number[] } interface CashBankCardProps { title: string accountNumber: string balances: Balance[] chartData: ChartData[] categories: string[] buttonText?: string buttonIcon?: string href?: string chartColor?: string height?: number currency?: 'IDR' | 'USD' | 'EUR' showButton?: boolean maxValue?: number enableHover?: boolean } const CashBankCard = ({ title, accountNumber, balances, chartData, categories, href, chartColor = '#ff6b9d', height = 300, currency = 'IDR', showButton = true, maxValue, enableHover = true }: CashBankCardProps) => { // Vars const divider = 'var(--mui-palette-divider)' const disabledText = 'var(--mui-palette-text-disabled)' const primaryText = 'var(--mui-palette-text-primary)' // Auto calculate maxValue if not provided const calculatedMaxValue = maxValue || Math.max(...chartData.flatMap(series => series.data)) * 1.2 // Currency formatter const formatCurrency = (value: number) => { const formatters = { IDR: new Intl.NumberFormat('id-ID', { style: 'currency', currency: 'IDR', minimumFractionDigits: 0 }), USD: new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', minimumFractionDigits: 0 }), EUR: new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR', minimumFractionDigits: 0 }) } return formatters[currency].format(value) } // Format balance display const formatBalance = (amount: string | number) => { if (typeof amount === 'string') return amount return new Intl.NumberFormat('id-ID').format(amount) } // Y-axis label formatter based on currency const formatYAxisLabel = (val: number) => { if (currency === 'IDR') { return (val / 1000000).toFixed(0) + '.000.000' } return (val / 1000).toFixed(0) + 'K' } const options: ApexOptions = { chart: { height: height, type: 'area', parentHeightOffset: 0, zoom: { enabled: false }, toolbar: { show: false } }, colors: [chartColor], fill: { type: 'gradient', gradient: { shade: 'light', type: 'vertical', shadeIntensity: 0.4, gradientToColors: [chartColor], inverseColors: false, opacityFrom: 0.8, opacityTo: 0.1, stops: [0, 100] } }, stroke: { curve: 'smooth', width: 3 }, dataLabels: { enabled: false }, grid: { show: true, borderColor: divider, strokeDashArray: 3, padding: { top: -10, bottom: -10, left: 20, right: 20 }, xaxis: { lines: { show: true } }, yaxis: { lines: { show: true } } }, tooltip: { enabled: true, y: { formatter: function (val: number) { return formatCurrency(val) } } }, yaxis: { min: 0, max: calculatedMaxValue, tickAmount: 7, labels: { style: { colors: disabledText, fontSize: '12px', fontWeight: '400' }, formatter: function (val: number) { return formatYAxisLabel(val) } } }, xaxis: { axisBorder: { show: false }, axisTicks: { show: false }, crosshairs: { stroke: { color: divider } }, labels: { style: { colors: disabledText, fontSize: '12px', fontWeight: '400' } }, categories: categories }, legend: { show: false } } return ( {title} {accountNumber} {showButton && ( )} {balances.map((balance, index) => ( {formatBalance(balance.amount)} {balance.label} ))} } sx={{ pb: 0, '& .MuiCardHeader-content': { width: '100%' } }} /> ) } export default CashBankCard