Files
auto-charger/web/components/ChargesTable.tsx
T
admin 7dd3215520 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>
2026-07-03 19:12:04 +02:00

87 lines
2.8 KiB
TypeScript

import { Charge } from "@/lib/db";
const WEEKDAYS = ["So", "Mo", "Di", "Mi", "Do", "Fr", "Sa"];
function parts(iso: string) {
// erwartet "YYYY-MM-DDTHH:MM:SS" (lokale Zeit vom Collector)
const [date = "", time = ""] = iso.split("T");
const [y, m, d] = date.split("-");
return { y, m, d, hm: time.slice(0, 5) };
}
function formatDate(iso: string): string {
const { y, m, d } = parts(iso);
return y && m && d ? `${d}.${m}.${y}` : iso;
}
function weekday(iso: string): string {
const { y, m, d } = parts(iso);
if (!y || !m || !d) return "-";
return WEEKDAYS[new Date(Number(y), Number(m) - 1, Number(d)).getDay()];
}
function formatTime(iso: string): string {
return parts(iso).hm || "-";
}
function formatDuration(seconds: number): string {
const h = Math.floor(seconds / 3600);
const min = Math.floor((seconds % 3600) / 60);
return `${h}:${String(min).padStart(2, "0")}`;
}
export default function ChargesTable({ charges }: { charges: Charge[] }) {
if (charges.length === 0) {
return (
<div className="text-center py-8 text-gray-500">
Noch keine Ladungen erfasst
</div>
);
}
return (
<div className="overflow-x-auto">
<table className="w-full border-collapse">
<thead>
<tr className="bg-[#CCCCFF] border-b-2 border-gray-400">
<th className="p-2 text-center">Datum</th>
<th className="p-2 text-center">Tag</th>
<th className="p-2 text-center">Start</th>
<th className="p-2 text-center">Ende</th>
<th className="p-2 text-center">
Dauer<br />
<span className="text-xs font-normal">h:mm</span>
</th>
<th className="p-2 text-center">
Energie<br />
<span className="text-xs font-normal">kWh</span>
</th>
</tr>
</thead>
<tbody>
{charges.map((c, index) => (
<tr
key={c.id}
className={`border-b border-gray-300 hover:bg-gray-50 ${
index % 2 === 0 ? "bg-white" : "bg-gray-50"
}`}
>
<td className="p-2 text-center">{formatDate(c.start_time)}</td>
<td className="p-2 text-center">{weekday(c.start_time)}</td>
<td className="p-2 text-center">{formatTime(c.start_time)}</td>
<td className="p-2 text-center">{formatTime(c.end_time)}</td>
<td className="p-2 text-center">{formatDuration(c.duration_s)}</td>
<td className="p-2 text-center">
{(c.energy_wh / 1000).toLocaleString("de-DE", {
minimumFractionDigits: 2,
maximumFractionDigits: 2,
})}
</td>
</tr>
))}
</tbody>
</table>
</div>
);
}