feat(api): add stats chart endpoint for admin access with time series data

feat(dayjs): integrate dayjs for date handling and formatting across the application
refactor(routes): update date handling in id-tags, transactions, users, and dashboard routes to use dayjs
style(globals): improve CSS variable definitions for better readability and consistency
deps: add dayjs as a dependency for date manipulation
This commit is contained in:
2026-03-11 21:34:21 +08:00
parent 73f0c6243a
commit 02a361488b
27 changed files with 502 additions and 110 deletions

View File

@@ -1,4 +1,5 @@
import { eq } from "drizzle-orm";
import dayjs from "dayjs";
import { useDrizzle } from "@/lib/db.js";
import { chargePoint, connector, transaction } from "@/db/schema.js";
import type {
@@ -35,16 +36,16 @@ export async function handleStartTransaction(
connectorId: payload.connectorId,
status: "Charging",
errorCode: "NoError",
lastStatusAt: new Date(),
lastStatusAt: dayjs().toDate(),
})
.onConflictDoUpdate({
target: [connector.chargePointId, connector.connectorId],
set: { status: "Charging", updatedAt: new Date() },
set: { status: "Charging", updatedAt: dayjs().toDate() },
})
.returning({ id: connector.id });
const rejected = idTagInfo.status !== "Accepted";
const now = new Date();
const now = dayjs();
// Insert transaction record regardless of auth status (OCPP spec requirement)
const [tx] = await db
@@ -55,12 +56,12 @@ export async function handleStartTransaction(
connectorNumber: payload.connectorId,
idTag: payload.idTag,
idTagStatus: idTagInfo.status,
startTimestamp: new Date(payload.timestamp),
startTimestamp: dayjs(payload.timestamp).toDate(),
startMeterValue: payload.meterStart,
reservationId: payload.reservationId ?? null,
// If rejected, immediately close the transaction so it doesn't appear as in-progress
...(rejected && {
stopTimestamp: now,
stopTimestamp: now.toDate(),
stopMeterValue: payload.meterStart,
chargeAmount: 0,
stopReason: "DeAuthorized",