Summen-Statistik der Kategorien
Eigenes 'Löschen' PopUp
This commit is contained in:
120
components/MonatsStatistik.tsx
Normal file
120
components/MonatsStatistik.tsx
Normal file
@@ -0,0 +1,120 @@
|
||||
'use client';
|
||||
|
||||
import { useState, useEffect, useCallback } from 'react';
|
||||
import { MonthlyStats } from '@/types/ausgaben';
|
||||
import { Category } from '@/app/api/categories/route';
|
||||
|
||||
interface MonatsStatistikProps {
|
||||
typ: number;
|
||||
refreshKey?: number;
|
||||
}
|
||||
|
||||
export default function MonatsStatistik({ typ, refreshKey }: MonatsStatistikProps) {
|
||||
const [stats, setStats] = useState<MonthlyStats | null>(null);
|
||||
const [month, setMonth] = useState('');
|
||||
const [year, setYear] = useState('');
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [categories, setCategories] = useState<Category[]>([]);
|
||||
|
||||
// Initialize month/year
|
||||
useEffect(() => {
|
||||
const now = new Date();
|
||||
setMonth(String(now.getMonth() + 1).padStart(2, '0'));
|
||||
setYear(String(now.getFullYear()));
|
||||
}, []);
|
||||
|
||||
// Fetch categories once
|
||||
useEffect(() => {
|
||||
fetch('/api/categories')
|
||||
.then((r) => r.json())
|
||||
.then((data) => { if (data.success) setCategories(data.data); })
|
||||
.catch(() => {});
|
||||
}, []);
|
||||
|
||||
const fetchStats = useCallback(async (y: string, m: string) => {
|
||||
if (!y || !m) return;
|
||||
setIsLoading(true);
|
||||
try {
|
||||
const response = await fetch(`/api/ausgaben/stats?year=${y}&month=${m}&typ=${typ}`);
|
||||
const data = await response.json();
|
||||
if (data.success) setStats(data.data);
|
||||
} catch (error) {
|
||||
console.error('Error fetching stats:', error);
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
}, [typ]);
|
||||
|
||||
useEffect(() => {
|
||||
if (month && year) fetchStats(year, month);
|
||||
}, [month, year, typ, refreshKey, fetchStats]);
|
||||
|
||||
const formatAmount = (amount: number) =>
|
||||
new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(amount);
|
||||
|
||||
const getCatLabel = (code: string) => {
|
||||
const cat = categories.find((c) => c.value === code);
|
||||
return cat ? `${cat.label}` : code;
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="mt-4 bg-[#E0E0FF] border border-black rounded-lg shadow-md p-4">
|
||||
{/* Zeile 1: Monat/Jahr + Gesamtsumme */}
|
||||
<div className="flex items-center justify-between flex-wrap gap-2">
|
||||
<div className="flex gap-4 items-center">
|
||||
<label className="font-semibold">Monat:</label>
|
||||
<select
|
||||
value={month}
|
||||
onChange={(e) => setMonth(e.target.value)}
|
||||
className="border border-gray-400 rounded px-3 py-1"
|
||||
>
|
||||
<option value="01">Januar</option>
|
||||
<option value="02">Februar</option>
|
||||
<option value="03">März</option>
|
||||
<option value="04">April</option>
|
||||
<option value="05">Mai</option>
|
||||
<option value="06">Juni</option>
|
||||
<option value="07">Juli</option>
|
||||
<option value="08">August</option>
|
||||
<option value="09">September</option>
|
||||
<option value="10">Oktober</option>
|
||||
<option value="11">November</option>
|
||||
<option value="12">Dezember</option>
|
||||
</select>
|
||||
|
||||
<label className="font-semibold">Jahr:</label>
|
||||
<input
|
||||
type="number"
|
||||
value={year}
|
||||
onChange={(e) => setYear(e.target.value)}
|
||||
className="border border-gray-400 rounded px-3 py-1 w-24"
|
||||
min="2013"
|
||||
max="2099"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
{isLoading ? (
|
||||
<span>Lade...</span>
|
||||
) : stats ? (
|
||||
<span className="font-bold text-lg">
|
||||
Summe: {formatAmount(stats.totalAusgaben)}
|
||||
</span>
|
||||
) : null}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Zeile 2+: Kategorien */}
|
||||
{!isLoading && stats?.katStats && Object.keys(stats.katStats).length > 0 && (
|
||||
<div className="mt-3 pt-3 border-t border-gray-400 flex flex-wrap gap-x-6 gap-y-1">
|
||||
{Object.entries(stats.katStats).map(([code, total]) => (
|
||||
<div key={code} className="flex gap-2 text-sm">
|
||||
<span className="font-medium">{getCatLabel(code)}:</span>
|
||||
<span>{formatAmount(total)}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user