'use client'; import { useState, useEffect, useCallback } from 'react'; import { CreateAusgabenEntry, AusgabenEntry, ZAHLUNGSARTEN_HAUSHALT, ZAHLUNGSARTEN_PRIVAT, MonthlyStats } from '@/types/ausgaben'; interface AusgabenFormProps { onSuccess: () => void; selectedEntry?: AusgabenEntry | null; typ: number; // 0 = Haushalt, 1 = Privat } export default function AusgabenForm({ onSuccess, selectedEntry, typ }: AusgabenFormProps) { const zahlungsarten = typ === 0 ? ZAHLUNGSARTEN_HAUSHALT : ZAHLUNGSARTEN_PRIVAT; const defaultZahlungsart = typ === 0 ? 'ECR' : 'bar'; const [formData, setFormData] = useState({ Datum: '', WochTag: '', Wo: '', Was: '', Wieviel: '', Wie: defaultZahlungsart, TYP: typ, OK: 0, }); const [isSubmitting, setIsSubmitting] = useState(false); const [editId, setEditId] = useState(null); // Monthly stats const [stats, setStats] = useState(null); const [month, setMonth] = useState(''); const [year, setYear] = useState(''); const [isLoadingStats, setIsLoadingStats] = useState(false); const fetchStats = useCallback(async (y: string, m: string) => { if (!y || !m) return; setIsLoadingStats(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 { setIsLoadingStats(false); } }, [typ]); // Initialize month/year on first load useEffect(() => { const now = new Date(); const currentMonth = String(now.getMonth() + 1).padStart(2, '0'); const currentYear = String(now.getFullYear()); setMonth(currentMonth); setYear(currentYear); }, []); // Fetch stats when month, year, or typ changes useEffect(() => { if (month && year) { fetchStats(year, month); } }, [month, year, typ, fetchStats]); const handleMonthChange = (newMonth: string) => { setMonth(newMonth); }; const handleYearChange = (newYear: string) => { setYear(newYear); }; const formatAmount = (amount: number | null) => { if (amount === null || amount === undefined) return '0,00 €'; return new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR', }).format(amount); }; useEffect(() => { if (selectedEntry) { // Load selected entry for editing const dateStr = selectedEntry.Datum.toString().split('T')[0]; setFormData({ Datum: dateStr, WochTag: selectedEntry.WochTag, Wo: selectedEntry.Wo, Was: selectedEntry.Was, Wieviel: selectedEntry.Wieviel.toString(), Wie: selectedEntry.Wie, TYP: selectedEntry.TYP, OK: selectedEntry.OK || 0, }); setEditId(selectedEntry.ID); } else { // Initialize with current date for new entry const now = new Date(); const dateStr = now.toISOString().split('T')[0]; const weekday = getWeekday(now); setFormData(prev => ({ ...prev, Datum: dateStr, WochTag: weekday, TYP: typ, })); setEditId(null); } }, [selectedEntry, typ]); const getWeekday = (date: Date): string => { const weekdays = ['Sonntag', 'Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag', 'Samstag']; return weekdays[date.getDay()]; }; const handleDateChange = (dateStr: string) => { const [year, month, day] = dateStr.split('-'); const date = new Date(Number(year), Number(month) - 1, Number(day)); const weekday = getWeekday(date); setFormData(prev => ({ ...prev, Datum: dateStr, WochTag: weekday })); }; const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); if (!formData.Wo || !formData.Was || !formData.Wieviel) { alert('Bitte alle Pflichtfelder ausfüllen!'); return; } setIsSubmitting(true); try { const url = editId ? `/api/ausgaben/${editId}` : '/api/ausgaben'; const method = editId ? 'PUT' : 'POST'; const response = await fetch(url, { method: method, headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(formData), }); if (response.ok) { handleReset(); onSuccess(); // Refresh stats after successful save fetchStats(year, month); } else { alert('Fehler beim Speichern!'); } } catch (error) { console.error('Error:', error); alert('Fehler beim Speichern!'); } finally { setIsSubmitting(false); } }; const handleReset = () => { const now = new Date(); const dateStr = now.toISOString().split('T')[0]; const weekday = getWeekday(now); setFormData({ Datum: dateStr, WochTag: weekday, Wo: '', Was: '', Wieviel: '', Wie: defaultZahlungsart, TYP: typ, OK: 0, }); setEditId(null); }; return (
{editId && (
ℹ️ Bearbeitungsmodus: Sie bearbeiten einen bestehenden Eintrag.
)}
Datum Wo Was Wieviel Wie
handleDateChange(e.target.value)} className="w-full px-2 py-1 text-base rounded border-2 border-gray-400 bg-white focus:border-blue-500 focus:outline-none" required /> setFormData({ ...formData, Wo: e.target.value })} className="w-full px-2 py-1 text-base rounded border-2 border-gray-400 bg-white focus:border-blue-500 focus:outline-none" placeholder="Geschäft/Ort" required /> setFormData({ ...formData, Was: e.target.value })} className="w-full px-2 py-1 text-base rounded border-2 border-gray-400 bg-white focus:border-blue-500 focus:outline-none" placeholder="Beschreibung" required /> setFormData({ ...formData, Wieviel: e.target.value })} className="w-full px-2 py-1 text-base rounded border-2 border-gray-400 bg-white focus:border-blue-500 focus:outline-none [appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none" placeholder="0.00" required />
{/* Wochentag */}
{formData.WochTag}
{/* Buttons */}
{/* Monatsstatistiken */}
handleYearChange(e.target.value)} className="border border-gray-400 rounded px-3 py-1 w-24" min="2013" max="2099" />
{isLoadingStats ? ( Lade... ) : stats ? ( Summe: {formatAmount(stats.totalAusgaben)} ) : null}
); }