import { useEffect, useState } from 'react'; import { useQuery } from '@tanstack/react-query'; import { useNavigate } from 'react-router-dom'; import { api } from '../lib/api'; import { translations, getLang } from '../lib/i18n'; import { useTelegramTheme } from '../hooks/useTelegramTheme'; import { useMainButton } from '../hooks/useTelegramUI'; import { Amount } from '../components/Amount'; function todayMonth(): string { const d = new Date(); return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}`; } function monthLabel(month: string): string { const [y, m] = month.split('-').map(Number); return new Date(y, m - 1).toLocaleDateString('tr-TR', { month: 'long', year: 'numeric' }); } function todayStr(): string { const d = new Date(); return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`; } function minDateStr(): string { const d = new Date(); d.setFullYear(d.getFullYear() - 5); return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`; } export function Ozet() { useTelegramTheme(); const navigate = useNavigate(); const lang = getLang(); const t = translations[lang]; const { setMainButton } = useMainButton(); const [month, setMonth] = useState(todayMonth()); const [exporting, setExporting] = useState(false); const [rangeFrom, setRangeFrom] = useState(`${todayMonth()}-01`); const [rangeTo, setRangeTo] = useState(todayStr()); const [exportMsg, setExportMsg] = useState(null); const { data: summary } = useQuery({ queryKey: ['summary', month], queryFn: () => api.summary(month), }); const { data: months } = useQuery({ queryKey: ['months'], queryFn: api.months }); const { data: topExpenses } = useQuery({ queryKey: ['top3', month], queryFn: async () => { const res = await api.listExpenses({ from: `${month}-01`, to: `${month}-31`, limit: 3, }); return res.items; }, }); const navMonths = Array.from(new Set([...(months ?? []), todayMonth()])).sort((a, b) => a < b ? 1 : -1 ); // MainButton: Excel indir — effect içinde, render sırasında değil useEffect(() => { setMainButton(t.excelDownload, async () => { setExporting(true); setExportMsg(null); try { await api.exportRange(rangeFrom, rangeTo); setExportMsg('EXPORT_SENT'); window.Telegram?.WebApp.HapticFeedback.notificationOccurred('success'); } catch { setExportMsg('EXPORT_FAILED'); } finally { setExporting(false); } }); }, [setMainButton, t.excelDownload, rangeFrom, rangeTo]); // Günlük çubuk serisi — en yüksek güne göre normalize const maxDay = Math.max(1, ...(summary?.byDay.map((d) => d.totalMinor) ?? [1])); const activeDays = summary?.byDay.filter((d) => d.totalMinor > 0) ?? []; return (
{/* Ay seçici */}
{monthLabel(month)}
{/* Ay toplamı */}
{t.count}: {summary?.count ?? 0}
{/* Günlük çubuk serisi */} {activeDays.length > 0 && (
{summary?.byDay.map((d) => (
0 ? Math.max((d.totalMinor / maxDay) * 100, 8) : 0}%`, opacity: d.totalMinor > 0 ? 1 : 0.15, }} title={`${d.date}: ${(d.totalMinor / 100).toFixed(2)} ₺`} /> ))}
)} {/* Kategori listesi */}

{t.summary}

{summary?.byCategory.length === 0 && (
{t.emptyMonth(monthLabel(month))}
)} {summary?.byCategory.map((c) => (
{c.emoji ?? '📦'}
{c.nameTr} %{(c.share * 100).toFixed(0)} · {c.count} {t.count}
))}
{/* En yüksek 3 */} {topExpenses && topExpenses.length > 0 && (

{t.top3}

{topExpenses.map((e, i) => ( ))}
)} {/* Excel dışa aktarma */}

{t.excelDownload}

{exportMsg === 'EXPORT_SENT' && (

{t.exportSent}

)} {exportMsg === 'EXPORT_FAILED' && (

{t.exportFailed}

)} {exporting &&

{t.loading}

}

Excel dosyası bot sohbetine gönderilir — indirmene gerek yok, Telegram'da kalıcı olur.

); }