import { ArrowUp, DocumentDownload, ArrowDown } from 'iconsax-react' import { type FC, useState, useMemo } from 'react' import { Area, AreaChart, CartesianGrid, ResponsiveContainer, Tooltip, XAxis, YAxis } from 'recharts' import DatePicker from '@/components/DatePicker' import Button from '@/components/Button' import { useGetPaymentsChart } from '../hooks/useStatsData' import { formatPrice } from '@/helpers/func' import PageLoading from '@/components/PageLoading' import moment from 'moment-jalaali' const RevenueChart: FC = () => { const [selectedTab] = useState< 'daily' | 'monthly' | 'yearly' >('monthly') const [startDate, setStartDate] = useState('') const [endDate, setEndDate] = useState('') const convertToPersian = (gregorianDate: string | null | undefined): string | undefined => { if (!gregorianDate) return undefined const persianDate = moment(gregorianDate, 'YYYY-MM-DD').format('jYYYY-jMM-jDD') return persianDate } const apiParams = useMemo(() => { const params: { period?: 'daily' | 'monthly' | 'yearly'; startDate?: string; endDate?: string; } = {} // فقط اگر تاریخ انتخاب شده باشد ارسال شود if (startDate && startDate.trim() !== '') params.startDate = startDate if (endDate && endDate.trim() !== '') params.endDate = endDate return params }, [startDate, endDate]) const { data: paymentsChartData, isLoading } = useGetPaymentsChart(apiParams) const formatDateLabel = (dateString: string, period: 'daily' | 'monthly' | 'yearly'): string => { const date = new Date(dateString) const options: Intl.DateTimeFormatOptions = { year: 'numeric', } if (period === 'monthly') { options.month = 'long' } else if (period === 'daily') { options.month = 'short' options.day = 'numeric' } const persianDate = new Intl.DateTimeFormat('fa-IR', options).format(date) return persianDate } const chartData = useMemo(() => { if (!paymentsChartData?.data) return [] return paymentsChartData.data.map((item) => ({ month: formatDateLabel(item.date, selectedTab), online: item.online, cash: item.cash, })) }, [paymentsChartData?.data, selectedTab]) const xAxisInterval = useMemo(() => { const dataLength = chartData.length if (dataLength <= 7) return 0 if (dataLength <= 15) return 1 if (dataLength <= 30) return 2 if (dataLength <= 60) return 4 return Math.floor(dataLength / 12) }, [chartData.length]) const totalRevenue = useMemo(() => { return chartData.reduce((sum, item) => sum + item.online + item.cash, 0) }, [chartData]) const revenueChange = useMemo(() => { if (chartData.length < 2) return null const currentPeriod = chartData[chartData.length - 1] const previousPeriod = chartData[chartData.length - 2] const currentTotal = currentPeriod.online + currentPeriod.cash const previousTotal = previousPeriod.online + previousPeriod.cash if (previousTotal === 0) return null const change = ((currentTotal - previousTotal) / previousTotal) * 100 return change }, [chartData]) const formatYAxis = (value: number) => { if (value === 0) return '۰' if (value >= 1000000) { const millions = value / 1000000 const formatted = millions .toFixed(1) .replace(/\d/g, (d) => '۰۱۲۳۴۵۶۷۸۹'[parseInt(d)]) return `${formatted} میلیون` } return value.toLocaleString('fa-IR') } const CustomTooltip = (props: { active?: boolean payload?: Array<{ dataKey?: string value?: number color?: string payload?: { cash?: number online?: number month?: string } }> label?: string }) => { const { active, payload, label } = props if (!active || !payload || payload.length === 0 || !label) { return null } // استفاده از paymentsChartData.data مستقیم برای دریافت داده‌های واقعی // پیدا کردن آخرین آیتمی که label آن با formatDateLabel match می‌کند let dataPoint: { cash: number; online: number } | null = null if (paymentsChartData?.data) { // پیدا کردن همه آیتم‌های match شده و استفاده از آخرین const matchingItems: Array<{ cash: number; online: number }> = [] for (const item of paymentsChartData.data) { const formattedLabel = formatDateLabel(item.date, selectedTab) if (formattedLabel === label) { matchingItems.push({ cash: item.cash, online: item.online }) } } if (matchingItems.length > 0) { dataPoint = matchingItems[matchingItems.length - 1] } } // اگر پیدا نکردیم، از chartData استفاده می‌کنیم if (!dataPoint) { const matchingItems = chartData.filter((item) => item.month === label) if (matchingItems.length > 0) { dataPoint = matchingItems[matchingItems.length - 1] } } if (!dataPoint) { return null } const cashValue = dataPoint.cash const onlineValue = dataPoint.online return (

{label}

پرداخت نقدی: {cashValue.toLocaleString('fa-IR')} تومان
پرداخت آنلاین: {onlineValue.toLocaleString('fa-IR')} تومان
جمع: {(cashValue + onlineValue).toLocaleString('fa-IR')} تومان
) } return (
{/* Header */}

مجموع درآمد

{/* Tabs */} {/*
*/} {/* مبلغ و درصد */}
مجموع درآمد

{formatPrice(totalRevenue)}

{revenueChange !== null && (
= 0 ? 'bg-green-50' : 'bg-red-50' }`} > {revenueChange >= 0 ? ( ) : ( )} = 0 ? 'text-green-600' : 'text-red-600' }`} > {Math.abs(revenueChange).toFixed(1)}%
)}
پرداخت آنلاین
پرداخت نقدی
{/* نمودار */} {isLoading ? (
) : chartData.length === 0 ? (
داده‌ای برای نمایش وجود ندارد
) : (
15 ? -45 : 0} textAnchor={chartData.length > 15 ? 'end' : 'middle'} height={chartData.length > 15 ? 60 : 40} minTickGap={10} /> } />
)}
) } export default RevenueChart