From 14bb3fd2cd55f3aff1e446311f8ffbf3a0269850 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Reinhard=20X=2E=20F=C3=BCrst?= Date: Fri, 27 Feb 2026 16:14:40 +0000 Subject: [PATCH] ? --- README.md | 24 ++---- app/page.tsx | 7 +- components/AusgabenForm.tsx | 145 +++++++++++++++++------------------- components/AusgabenList.tsx | 2 +- docker-compose.prod.yml | 37 +++++++++ 5 files changed, 119 insertions(+), 96 deletions(-) create mode 100644 docker-compose.prod.yml diff --git a/README.md b/README.md index d0db749..c7b51ac 100644 --- a/README.md +++ b/README.md @@ -9,29 +9,19 @@ Dies ist die modernisierte Version des alten PHP/jQuery-basierten Ausgaben-Progr ## Features - **Zwei Tabs für verschiedene Ausgabenkategorien:** - - **Haushalt (TYP=0)**: Zahlungsarten EC-R, EC-B, bar-R, bar-B, Einnahme, Überweisung - - **Privat (TYP=1)**: Zahlungsarten bar, EC, VISA, Master, Einnahme, Überweisung + - **Haushalt (TYP=0)**: Zahlungsarten ECR, ECB, barR, barB, Ein(nahme), Uber(weisung) + - **Privat (TYP=1)**: Zahlungsarten bar, EC, VISA, MASTER, Einnahme, Uber(weisung) -- **Eingabe**: Erfassen von Ausgaben mit: +- **Eingabeformular mit integrierten Features:** - Datum (mit automatischem Wochentag) - Wo (Geschäft/Ort) - Was (Beschreibung) - Wieviel (Betrag in Euro) - Wie (Zahlungsart - abhängig vom aktiven Tab) - - Monatsstatistiken (TYP-spezifisch) - - Letzte 10 Einträge des aktiven TYPs - -- **Listen-Ansicht**: Vollständige Auflistung aller Einträge mit: - - Bearbeiten-Funktion - - Löschen-Funktion - - Sortierung nach Datum (absteigend) - - Filterung nach TYP (Haushalt/Privat) - -- **Monatliche Statistiken**: - - Gesamtausgaben pro TYP - - Aufschlüsselung nach Zahlungsart - - Einnahmen - - Überweisungen + - Monatliche Statistiken im Formular (Gesamtsumme, aufgeschlüsselt nach Zahlungsart) + - Letzte 10 Einträge direkt unter dem Formular mit Bearbeiten/Löschen-Funktion + - Bearbeiten-Funktion: Klick auf Eintrag lädt ihn ins Formular + - Filterung nach aktivem TYP (Haushalt/Privat) ## Technologie-Stack diff --git a/app/page.tsx b/app/page.tsx index c2753ff..39eea5b 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -13,6 +13,7 @@ export default function Home() { const [selectedEntry, setSelectedEntry] = useState(null); const version = packageJson.version; + const buildDate = process.env.NEXT_PUBLIC_BUILD_DATE || new Date().toLocaleDateString('de-DE', { day: '2-digit', month: '2-digit', year: 'numeric' }); useEffect(() => { fetchRecentEntries(); @@ -22,7 +23,7 @@ export default function Home() { const fetchRecentEntries = async () => { setIsLoading(true); try { - const response = await fetch(`/api/ausgaben?limit=10&typ=${activeTab}`, { + const response = await fetch(`/api/ausgaben?limit=20&typ=${activeTab}`, { cache: 'no-store', headers: { 'Cache-Control': 'no-cache', @@ -89,7 +90,7 @@ export default function Home() {
-

Letzte 10 Einträge

+

Letzte 20 Einträge

{isLoading ? (
Lade Daten...
) : ( @@ -106,7 +107,7 @@ export default function Home() {
- Version {version} + Version {version} - {buildDate}
diff --git a/components/AusgabenForm.tsx b/components/AusgabenForm.tsx index 87b7410..5d2571e 100644 --- a/components/AusgabenForm.tsx +++ b/components/AusgabenForm.tsx @@ -264,83 +264,78 @@ export default function AusgabenForm({ onSuccess, selectedEntry, typ }: Ausgaben - - {formData.WochTag} - - - - - - - - -
- - -
- - - - -
-
- - - - - 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} -
-
- - + + {/* 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} +
+
+
); diff --git a/components/AusgabenList.tsx b/components/AusgabenList.tsx index f26f15b..9d99169 100644 --- a/components/AusgabenList.tsx +++ b/components/AusgabenList.tsx @@ -67,7 +67,7 @@ export default function AusgabenList({ entries, onDelete, onEdit }: AusgabenList ) : ( entries.map((entry, index) => ( - + {formatDate(entry.Datum)} diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml new file mode 100644 index 0000000..70b1cd5 --- /dev/null +++ b/docker-compose.prod.yml @@ -0,0 +1,37 @@ +# Docker Compose für Production Server mit Traefik +services: + ausgaben-app: + image: docker.citysensor.de/ausgaben-next:latest + container_name: ausgaben-next-app + restart: unless-stopped + expose: + - 3000 + environment: + - NODE_ENV=production + - DB_HOST=${DB_HOST} + - DB_USER=${DB_USER} + - DB_PASS=${DB_PASS} + - DB_NAME=${DB_NAME} + labels: + - traefik.enable=true + - traefik.http.routers.ausgaben.entrypoints=http + - traefik.http.routers.ausgaben.rule=Host(`ausgaben.fuerst-stuttgart.de`) + - traefik.http.middlewares.ausgaben-https-redirect.redirectscheme.scheme=https + - traefik.http.routers.ausgaben.middlewares=ausgaben-https-redirect + - traefik.http.routers.ausgaben-secure.entrypoints=https + - traefik.http.routers.ausgaben-secure.rule=Host(`ausgaben.fuerst-stuttgart.de`) + - traefik.http.routers.ausgaben-secure.tls=true + - traefik.http.routers.ausgaben-secure.tls.certresolver=letsencrypt + - traefik.http.routers.ausgaben-secure.service=ausgaben + - traefik.http.services.ausgaben.loadbalancer.server.port=3000 + networks: + - proxy + - gitea-internal + +networks: + proxy: + name: dockge_default + external: true + gitea-internal: + name: gitea_gitea-internal + external: true