Initial commit: Auto-Charger Logging Web-App

MQTT-Collector (Python/paho-mqtt) speichert abgeschlossene go-e
Wallbox-Ladungen in SQLite; Next.js-Web-App zeigt sie als Tabelle mit
Energie-Summen (Monat/Jahr/gesamt) im werte-next-Design. Zwei
Docker-Container mit gemeinsamem DB-Volume.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-03 19:12:04 +02:00
commit 7dd3215520
26 changed files with 8022 additions and 0 deletions
+22
View File
@@ -0,0 +1,22 @@
/* stylelint-disable at-rule-no-unknown */
@import "tailwindcss";
@source "../components/**/*.tsx";
@source "../app/**/*.tsx";
:root {
--background: #ffffff;
--foreground: #171717;
}
@theme inline {
--color-background: var(--background);
--color-foreground: var(--foreground);
--font-sans: var(--font-geist-sans);
--font-mono: var(--font-geist-mono);
}
body {
background: var(--background);
color: var(--foreground);
font-family: Arial, Helvetica, sans-serif;
}
+32
View File
@@ -0,0 +1,32 @@
import type { Metadata } from "next";
import { Geist, Geist_Mono } from "next/font/google";
import "./globals.css";
const geistSans = Geist({
variable: "--font-geist-sans",
subsets: ["latin"],
});
const geistMono = Geist_Mono({
variable: "--font-geist-mono",
subsets: ["latin"],
});
export const metadata: Metadata = {
title: "Auto-Charger Log",
description: "Protokoll der Auto-Ladevorgänge (go-e Wallbox)",
};
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="de">
<body className={`${geistSans.variable} ${geistMono.variable} antialiased`}>
{children}
</body>
</html>
);
}
+20
View File
@@ -0,0 +1,20 @@
import AppLayout from "@/components/AppLayout";
import ChargesTable from "@/components/ChargesTable";
import Totals from "@/components/Totals";
import { getCharges, getTotals } from "@/lib/db";
// Immer frisch aus der DB lesen (kein Caching).
export const dynamic = "force-dynamic";
export default function Home() {
const charges = getCharges();
const totals = getTotals();
return (
<AppLayout>
<h2 className="text-xl font-semibold mb-4">Ladungen</h2>
<ChargesTable charges={charges} />
<Totals totals={totals} />
</AppLayout>
);
}