From b39f3981fc692a211a46ccda6c4b0d9ad7366780 Mon Sep 17 00:00:00 2001 From: sazzadulalambd Date: Sat, 16 May 2026 12:19:54 +0600 Subject: [PATCH] feat: implement battery editing functionality with modal and state management --- src/app/admin/batteries/[id]/page.tsx | 207 +++++++++++++++++++++++++- 1 file changed, 205 insertions(+), 2 deletions(-) diff --git a/src/app/admin/batteries/[id]/page.tsx b/src/app/admin/batteries/[id]/page.tsx index 81e146e..50ef70d 100644 --- a/src/app/admin/batteries/[id]/page.tsx +++ b/src/app/admin/batteries/[id]/page.tsx @@ -4,7 +4,7 @@ import { useState, use } from 'react'; import Link from 'next/link'; import { Battery, ArrowLeft, X, BatteryCharging, Activity, Gauge, MapPin, Bike, User, History, - Calendar, DollarSign, CheckCircle, Clock, ArrowRightLeft, Handshake, TrendingUp + Calendar, DollarSign, CheckCircle, Clock, ArrowRightLeft, Handshake, TrendingUp, Edit, RefreshCw } from 'lucide-react'; interface BMSData { @@ -124,8 +124,37 @@ const typeLabels: Record = { export default function BatteryDetailPage({ params }: { params: Promise<{ id: string }> }) { const { id } = use(params); - const battery = mockBattery; + const [battery, setBattery] = useState(mockBattery); const [activeTab, setActiveTab] = useState<'info' | 'bms' | 'history' | 'rent'>('info'); + const [showEditModal, setShowEditModal] = useState(false); + const [refreshing, setRefreshing] = useState(false); + + const handleSaveEdit = (updatedBattery: Battery) => { + setBattery(updatedBattery); + setShowEditModal(false); + }; + + const handleRefreshBMS = () => { + setRefreshing(true); + setTimeout(() => { + setBattery({ + ...battery, + bmsData: { + ...battery.bmsData!, + voltage: Math.round((60 + Math.random() * 10) * 10) / 10, + current: Math.round((-3 + Math.random() * 4) * 10) / 10, + soc: Math.floor(Math.random() * 40) + 60, + temperature: 25 + Math.floor(Math.random() * 15), + cycles: battery.bmsData!.cycles + 1, + health: Math.max(70, Math.min(100, battery.bmsData!.health + (Math.random() > 0.7 ? 1 : 0))), + timestamp: new Date().toISOString().replace('T', ' ').substring(0, 19) + }, + currentSoc: Math.floor(Math.random() * 40) + 60, + health: Math.max(70, Math.min(100, battery.health + (Math.random() > 0.7 ? 1 : 0))) + }); + setRefreshing(false); + }, 1000); + }; return (
@@ -137,6 +166,12 @@ export default function BatteryDetailPage({ params }: { params: Promise<{ id: st

Battery Details

ID: {battery.id}

+ @@ -426,6 +461,174 @@ export default function BatteryDetailPage({ params }: { params: Promise<{ id: st )} + + {showEditModal && ( + setShowEditModal(false)} + /> + )} + + ); +} + +function EditBatteryModal({ + battery, + onSave, + onClose +}: { + battery: Battery; + onSave: (battery: Battery) => void; + onClose: () => void; +}) { + const [formData, setFormData] = useState({ ...battery }); + + const handleChange = (field: keyof Battery, value: any) => { + setFormData({ ...formData, [field]: value }); + }; + + return ( +
+
+
+

Edit Battery

+ +
+
+
+
+ + handleChange('brand', e.target.value)} + className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm" + /> +
+
+ + handleChange('model', e.target.value)} + className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm" + /> +
+
+ + handleChange('serialNumber', e.target.value)} + className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm" + /> +
+
+ + +
+
+ + handleChange('capacity', parseInt(e.target.value))} + className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm" + /> +
+
+ + handleChange('voltage', parseInt(e.target.value))} + className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm" + /> +
+
+ + handleChange('purchaseDate', e.target.value)} + className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm" + /> +
+
+ + handleChange('purchasePrice', parseInt(e.target.value))} + className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm" + /> +
+
+ + handleChange('warrantyExpiry', e.target.value)} + className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm" + /> +
+
+ + handleChange('monthlyRent', parseInt(e.target.value))} + className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm" + /> +
+
+ + +
+
+ + handleChange('currentSoc', parseInt(e.target.value))} + className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm" + /> +
+
+
+
+ + +
+
); } \ No newline at end of file