feat: integrate React Query for data fetching and state management across dashboard components

This commit is contained in:
2026-03-11 00:15:07 +08:00
parent 984274bfb7
commit eac81d2fab
9 changed files with 121 additions and 154 deletions

View File

@@ -1,6 +1,7 @@
"use client";
import { useCallback, useEffect, useRef, useState } from "react";
import { useState } from "react";
import { useQuery } from "@tanstack/react-query";
import {
Button,
Chip,
@@ -67,26 +68,17 @@ const EMPTY_FORM: FormData = {
};
export default function ChargePointsPage() {
const [chargePoints, setChargePoints] = useState<ChargePoint[]>([]);
const [formOpen, setFormOpen] = useState(false);
const [formTarget, setFormTarget] = useState<ChargePoint | null>(null);
const [formData, setFormData] = useState<FormData>(EMPTY_FORM);
const [formBusy, setFormBusy] = useState(false);
const [deleteTarget, setDeleteTarget] = useState<ChargePoint | null>(null);
const [deleting, setDeleting] = useState(false);
const hasFetched = useRef(false);
const load = useCallback(async () => {
const data = await api.chargePoints.list().catch(() => []);
setChargePoints(data);
}, []);
useEffect(() => {
if (!hasFetched.current) {
hasFetched.current = true;
load();
}
}, [load]);
const { data: chargePoints = [], refetch: refetchList } = useQuery({
queryKey: ["chargePoints"],
queryFn: () => api.chargePoints.list().catch(() => []),
refetchInterval: 3_000,
});
const openCreate = () => {
setFormTarget(null);
@@ -113,28 +105,23 @@ export default function ChargePointsPage() {
const fee = Math.max(0, Math.round(Number(formData.feePerKwh) || 0));
if (formTarget) {
// Edit
const updated = await api.chargePoints.update(String(formTarget.id), {
await api.chargePoints.update(String(formTarget.id), {
chargePointVendor: formData.chargePointVendor,
chargePointModel: formData.chargePointModel,
registrationStatus: formData.registrationStatus,
feePerKwh: fee,
});
setChargePoints((prev) =>
prev.map((cp) =>
cp.id === formTarget.id ? { ...updated, connectors: cp.connectors } : cp,
),
);
} else {
// Create
const created = await api.chargePoints.create({
await api.chargePoints.create({
chargePointIdentifier: formData.chargePointIdentifier.trim(),
chargePointVendor: formData.chargePointVendor.trim() || undefined,
chargePointModel: formData.chargePointModel.trim() || undefined,
registrationStatus: formData.registrationStatus,
feePerKwh: fee,
});
setChargePoints((prev) => [created, ...prev]);
}
await refetchList();
setFormOpen(false);
} finally {
setFormBusy(false);
@@ -146,7 +133,7 @@ export default function ChargePointsPage() {
setDeleting(true);
try {
await api.chargePoints.delete(String(deleteTarget.id));
setChargePoints((prev) => prev.filter((cp) => cp.id !== deleteTarget.id));
await refetchList();
setDeleteTarget(null);
} finally {
setDeleting(false);