feat(dashboard): add transactions and users management pages with CRUD functionality

feat(auth): implement login page and authentication middleware
feat(sidebar): create sidebar component with user info and navigation links
feat(api): establish API client for interacting with backend services
This commit is contained in:
2026-03-10 15:17:32 +08:00
parent 9a2668fae5
commit 2cb89c74b3
32 changed files with 4648 additions and 83 deletions

View File

@@ -6,19 +6,41 @@ import {
type OcppErrorCode,
type OcppMessage,
type OcppConnectionContext,
type AuthorizeRequest,
type AuthorizeResponse,
type BootNotificationRequest,
type BootNotificationResponse,
type HeartbeatRequest,
type HeartbeatResponse,
type MeterValuesRequest,
type MeterValuesResponse,
type StartTransactionRequest,
type StartTransactionResponse,
type StatusNotificationRequest,
type StatusNotificationResponse,
type StopTransactionRequest,
type StopTransactionResponse,
} from './types.ts'
/**
* Global registry of active OCPP WebSocket connections.
* Key = chargePointIdentifier, Value = WSContext
*/
export const ocppConnections = new Map<string, WSContext>()
import { handleAuthorize } from './actions/authorize.ts'
import { handleBootNotification } from './actions/boot-notification.ts'
import { handleHeartbeat } from './actions/heartbeat.ts'
import { handleMeterValues } from './actions/meter-values.ts'
import { handleStartTransaction } from './actions/start-transaction.ts'
import { handleStatusNotification } from './actions/status-notification.ts'
import { handleStopTransaction } from './actions/stop-transaction.ts'
// Typed dispatch map — only registered actions are accepted
type ActionHandlerMap = {
Authorize: (
payload: AuthorizeRequest,
ctx: OcppConnectionContext,
) => Promise<AuthorizeResponse>
BootNotification: (
payload: BootNotificationRequest,
ctx: OcppConnectionContext,
@@ -27,16 +49,32 @@ type ActionHandlerMap = {
payload: HeartbeatRequest,
ctx: OcppConnectionContext,
) => Promise<HeartbeatResponse>
MeterValues: (
payload: MeterValuesRequest,
ctx: OcppConnectionContext,
) => Promise<MeterValuesResponse>
StartTransaction: (
payload: StartTransactionRequest,
ctx: OcppConnectionContext,
) => Promise<StartTransactionResponse>
StatusNotification: (
payload: StatusNotificationRequest,
ctx: OcppConnectionContext,
) => Promise<StatusNotificationResponse>
StopTransaction: (
payload: StopTransactionRequest,
ctx: OcppConnectionContext,
) => Promise<StopTransactionResponse>
}
const actionHandlers: ActionHandlerMap = {
Authorize: handleAuthorize,
BootNotification: handleBootNotification,
Heartbeat: handleHeartbeat,
MeterValues: handleMeterValues,
StartTransaction: handleStartTransaction,
StatusNotification: handleStatusNotification,
StopTransaction: handleStopTransaction,
}
function sendCallResult(ws: WSContext, uniqueId: string, payload: unknown): void {
@@ -74,6 +112,7 @@ export function createOcppHandler(chargePointIdentifier: string, remoteAddr?: st
ws.close(1002, 'Unsupported subprotocol')
return
}
ocppConnections.set(chargePointIdentifier, ws)
console.log(
`[OCPP] ${chargePointIdentifier} connected` +
(remoteAddr ? ` from ${remoteAddr}` : ''),
@@ -136,6 +175,7 @@ export function createOcppHandler(chargePointIdentifier: string, remoteAddr?: st
},
onClose(evt: CloseEvent, _ws: WSContext) {
ocppConnections.delete(chargePointIdentifier)
console.log(`[OCPP] ${chargePointIdentifier} disconnected (code=${evt.code})`)
},
}