'use client'; 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, Edit, RefreshCw, AlertTriangle, Wrench, Plus, Trash2 } from 'lucide-react'; interface BMSData { voltage: number; current: number; soc: number; temperature: number; cycles: number; health: number; timestamp: string; } interface OwnershipLog { id: string; batteryId: string; fromOwner: string; fromOwnerType: 'company' | 'biker' | 'hub' | 'swap-station'; toOwner: string; toOwnerType: 'company' | 'biker' | 'hub' | 'swap-station'; fromBikeId?: string; fromBikeModel?: string; toBikeId?: string; toBikeModel?: string; fromHubId?: string; fromHubName?: string; toHubId?: string; toHubName?: string; fromStationId?: string; fromStationName?: string; toStationId?: string; toStationName?: string; action: 'assigned' | 'rented' | 'swapped' | 'returned' | 'retired'; rentAmount?: number; notes?: string; timestamp: string; } interface DamageRecord { id: string; date: string; type: string; description: string; reportedBy: string; estimatedCost: number; actualCost?: number; status: 'reported' | 'in-progress' | 'resolved'; } interface MaintenanceRecord { id: string; date: string; type: 'routine' | 'repair' | 'replacement' | 'inspection'; description: string; cost: number; performedBy: string; nextDueDate?: string; status: 'completed' | 'pending' | 'overdue'; } interface Battery { id: string; serialNumber: string; brand: string; model: string; type: 'lithium-ion' | 'lifepo4' | 'lead-acid'; capacity: number; voltage: number; purchaseDate: string; purchasePrice: number; warrantyExpiry: string; status: 'available' | 'in-use' | 'maintenance' | 'retired' | 'charging'; currentSoc: number; health: number; cycleCount: number; assignedBikeId?: string; assignedBikeModel?: string; assignedBikePlate?: string; assignedBikerId?: string; assignedBikerName?: string; assignedBikerPhone?: string; currentHubId?: string; currentHubName?: string; currentStationId?: string; currentStationName?: string; lastMaintenance?: string; nextMaintenance?: string; bmsData?: BMSData; monthlyRent?: number; ownershipLogs: OwnershipLog[]; damageHistory?: DamageRecord[]; maintenanceHistory?: MaintenanceRecord[]; } const mockBattery: Battery = { id: 'BAT-001', serialNumber: 'SN-2024-00001', brand: 'EVE Energy', model: 'Li-Ion 60V50Ah', type: 'lithium-ion', capacity: 50, voltage: 60, purchaseDate: '2024-01-15', purchasePrice: 45000, warrantyExpiry: '2027-01-15', status: 'in-use', currentSoc: 78, health: 95, cycleCount: 156, assignedBikeId: 'EV001', assignedBikeModel: 'Etron ET50', assignedBikePlate: 'Dhaka Metro Cha-A-1234', assignedBikerId: 'BK-001', assignedBikerName: 'Rahim Ahmed', assignedBikerPhone: '01712345678', currentHubId: 'HUB-001', currentHubName: 'JAIBEN Head Office', monthlyRent: 1500, lastMaintenance: '2024-03-01', nextMaintenance: '2024-06-01', bmsData: { voltage: 67.2, current: -2.5, soc: 78, temperature: 32, cycles: 156, health: 95, timestamp: '2024-03-28 12:00:00' }, ownershipLogs: [ { id: 'OL-001', batteryId: 'BAT-001', fromOwner: 'JAIBEN Hub', fromOwnerType: 'hub', toOwner: 'Rahim Ahmed', toOwnerType: 'biker', toBikeId: 'EV001', toBikeModel: 'Etron ET50', toHubId: 'HUB-001', toHubName: 'JAIBEN Head Office', action: 'rented', rentAmount: 1500, timestamp: '2024-03-15 08:30:00' }, { id: 'OL-002', batteryId: 'BAT-001', fromOwner: 'Rahim Ahmed', fromOwnerType: 'biker', toOwner: 'JAIBEN Hub', toOwnerType: 'hub', fromBikeId: 'EV001', fromBikeModel: 'Etron ET50', fromHubId: 'HUB-001', fromHubName: 'JAIBEN Head Office', action: 'returned', timestamp: '2024-03-28 18:00:00', notes: 'Returned for charging' }, { id: 'OL-003', batteryId: 'BAT-001', fromOwner: 'JAIBEN Hub', fromOwnerType: 'hub', toOwner: 'Rahim Ahmed', toOwnerType: 'biker', toBikeId: 'EV001', toBikeModel: 'Etron ET50', toHubId: 'HUB-001', toHubName: 'JAIBEN Head Office', action: 'rented', rentAmount: 1500, timestamp: '2024-03-28 18:30:00' }, ], damageHistory: [ { id: 'DMG-001', date: '2024-02-15', type: 'Physical Damage', description: 'Battery casing cracked due to drop', reportedBy: 'Rahim Ahmed', estimatedCost: 5000, actualCost: 4500, status: 'resolved' }, { id: 'DMG-002', date: '2024-03-20', type: 'Connector Damage', description: 'Charging connector bent', reportedBy: 'Tech Staff', estimatedCost: 1500, status: 'in-progress' }, ], maintenanceHistory: [ { id: 'MNT-001', date: '2024-01-20', type: 'routine', description: 'General inspection and cleaning', cost: 500, performedBy: 'Tech Team', nextDueDate: '2024-04-20', status: 'completed' }, { id: 'MNT-002', date: '2024-03-01', type: 'inspection', description: 'BMS calibration and cell balancing', cost: 800, performedBy: 'Engineer Team', nextDueDate: '2024-06-01', status: 'completed' }, { id: 'MNT-003', date: '2024-04-15', type: 'repair', description: 'Replaced faulty connector', cost: 1500, performedBy: 'Tech Team', status: 'pending' }, ], }; const statusColors: Record = { available: 'bg-green-100 text-green-700', 'in-use': 'bg-blue-100 text-blue-700', maintenance: 'bg-amber-100 text-amber-700', retired: 'bg-slate-100 text-slate-500', charging: 'bg-purple-100 text-purple-700', }; const typeLabels: Record = { 'lithium-ion': 'Lithium-Ion', 'lifepo4': 'LiFePO4', 'lead-acid': 'Lead Acid', }; export default function BatteryDetailPage({ params }: { params: Promise<{ id: string }> }) { const { id } = use(params); const [battery, setBattery] = useState(mockBattery); const [activeTab, setActiveTab] = useState<'info' | 'bms' | 'history' | 'rent' | 'damage' | 'maintenance'>('info'); const [showEditModal, setShowEditModal] = useState(false); const [refreshing, setRefreshing] = useState(false); // Damage History State const [showDamageModal, setShowDamageModal] = useState(false); const [editingDamage, setEditingDamage] = useState(null); const [damageForm, setDamageForm] = useState({ date: '', type: '', description: '', reportedBy: '', estimatedCost: 0, actualCost: 0, status: 'reported' as 'reported' | 'in-progress' | 'resolved', hubId: '', hubName: '', }); // Maintenance State const [showMaintenanceModal, setShowMaintenanceModal] = useState(false); const [editingMaintenance, setEditingMaintenance] = useState(null); const [maintenanceForm, setMaintenanceForm] = useState({ date: '', type: 'routine' as 'routine' | 'repair' | 'replacement' | 'inspection', description: '', cost: 0, performedBy: '', nextDueDate: '', status: 'pending' as 'completed' | 'pending' | 'overdue', hubId: '', hubName: '', }); const mockHubs = [ { id: 'HUB-001', name: 'Gulshan Hub' }, { id: 'HUB-002', name: 'Banani Hub' }, { id: 'HUB-003', name: 'Uttara Hub' }, { id: 'HUB-004', name: 'Mirpur Hub' }, ]; const damageTypes = ['Physical Damage', 'Connector Damage', 'Battery Cell Damage', 'Charging Port Damage', 'Water Damage', 'Software Issue', 'Other']; const maintenanceTypes = ['routine', 'repair', 'replacement', 'inspection'] as const; const handleSaveEdit = (updatedBattery: Battery) => { setBattery(updatedBattery); setShowEditModal(false); }; const handleRefreshBMS = () => { if (!battery.bmsData) return; setRefreshing(true); setTimeout(() => { const bms = battery.bmsData!; setBattery({ ...battery, bmsData: { ...bms, 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: bms.cycles + 1, health: Math.max(70, Math.min(100, bms.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); }; // Damage CRUD Handlers const handleAddDamage = () => { const newDamage: DamageRecord = { id: `DMG-${Date.now()}`, ...damageForm, estimatedCost: Number(damageForm.estimatedCost), actualCost: damageForm.actualCost ? Number(damageForm.actualCost) : undefined, }; setBattery(prev => ({ ...prev, damageHistory: [...(prev.damageHistory || []), newDamage] })); setShowDamageModal(false); resetDamageForm(); }; const handleUpdateDamage = () => { if (!editingDamage) return; const updatedDamage: DamageRecord = { ...editingDamage, ...damageForm, estimatedCost: Number(damageForm.estimatedCost), actualCost: damageForm.actualCost ? Number(damageForm.actualCost) : undefined, }; setBattery(prev => ({ ...prev, damageHistory: prev.damageHistory?.map(d => d.id === editingDamage.id ? updatedDamage : d) || [] })); setShowDamageModal(false); setEditingDamage(null); resetDamageForm(); }; const handleDeleteDamage = (damageId: string) => { setBattery(prev => ({ ...prev, damageHistory: prev.damageHistory?.filter(d => d.id !== damageId) || [] })); }; const resetDamageForm = () => { setDamageForm({ date: '', type: '', description: '', reportedBy: '', estimatedCost: 0, actualCost: 0, status: 'reported', hubId: '', hubName: '', }); }; const openAddDamageModal = () => { resetDamageForm(); setDamageForm(prev => ({ ...prev, date: new Date().toISOString().split('T')[0] })); setEditingDamage(null); setShowDamageModal(true); }; const openEditDamageModal = (damage: DamageRecord) => { setDamageForm({ date: damage.date, type: damage.type, description: damage.description, reportedBy: damage.reportedBy, estimatedCost: damage.estimatedCost, actualCost: damage.actualCost || 0, status: damage.status, hubId: '', hubName: '', }); setEditingDamage(damage); setShowDamageModal(true); }; // Maintenance CRUD Handlers const handleAddMaintenance = () => { const newMaintenance: MaintenanceRecord = { id: `MNT-${Date.now()}`, ...maintenanceForm, cost: Number(maintenanceForm.cost), nextDueDate: maintenanceForm.nextDueDate || undefined, }; setBattery(prev => ({ ...prev, maintenanceHistory: [...(prev.maintenanceHistory || []), newMaintenance] })); setShowMaintenanceModal(false); resetMaintenanceForm(); }; const handleUpdateMaintenance = () => { if (!editingMaintenance) return; const updatedMaintenance: MaintenanceRecord = { ...editingMaintenance, ...maintenanceForm, cost: Number(maintenanceForm.cost), nextDueDate: maintenanceForm.nextDueDate || undefined, }; setBattery(prev => ({ ...prev, maintenanceHistory: prev.maintenanceHistory?.map(m => m.id === editingMaintenance.id ? updatedMaintenance : m) || [] })); setShowMaintenanceModal(false); setEditingMaintenance(null); resetMaintenanceForm(); }; const handleDeleteMaintenance = (maintenanceId: string) => { setBattery(prev => ({ ...prev, maintenanceHistory: prev.maintenanceHistory?.filter(m => m.id !== maintenanceId) || [] })); }; const resetMaintenanceForm = () => { setMaintenanceForm({ date: '', type: 'routine', description: '', cost: 0, performedBy: '', nextDueDate: '', status: 'pending', hubId: '', hubName: '', }); }; const openAddMaintenanceModal = () => { resetMaintenanceForm(); setMaintenanceForm(prev => ({ ...prev, date: new Date().toISOString().split('T')[0] })); setEditingMaintenance(null); setShowMaintenanceModal(true); }; const openEditMaintenanceModal = (maintenance: MaintenanceRecord) => { setMaintenanceForm({ date: maintenance.date, type: maintenance.type, description: maintenance.description, cost: maintenance.cost, performedBy: maintenance.performedBy, nextDueDate: maintenance.nextDueDate || '', status: maintenance.status, hubId: '', hubName: '', }); setEditingMaintenance(maintenance); setShowMaintenanceModal(true); }; return (

Battery Details

ID: {battery.id}

{battery.brand} {battery.model}

{battery.serialNumber}

{battery.status}

SOC

50 ? 'text-green-600' : battery.currentSoc > 20 ? 'text-amber-600' : 'text-red-600'}`}>{battery.currentSoc}%

Health

80 ? 'text-green-600' : battery.health > 60 ? 'text-amber-600' : 'text-red-600'}`}>{battery.health}%

Cycles

{battery.cycleCount}

Price

৳{battery.purchasePrice.toLocaleString()}

{battery.bmsData && (
Live BMS Data Real-time
Updated: {battery.bmsData.timestamp}

Voltage

{battery.bmsData.voltage}V

Current

{battery.bmsData.current}A

SOC

{battery.bmsData.soc}%

Temp

{battery.bmsData.temperature}°C

Cycles

{battery.bmsData.cycles}

Health

80 ? 'text-green-600' : 'text-amber-600'}`}>{battery.bmsData.health}%

)}
{activeTab === 'info' && (

Brand

{battery.brand}

Model

{battery.model}

Serial Number

{battery.serialNumber}

Type

{typeLabels[battery.type]}

Capacity

{battery.capacity} Ah

Voltage

{battery.voltage} V

Purchase Date

{battery.purchaseDate}

Warranty Expiry

{battery.warrantyExpiry}

Last Maintenance

{battery.lastMaintenance || 'N/A'}

Next Maintenance

{battery.nextMaintenance || 'N/A'}

Purchase Price

৳{battery.purchasePrice.toLocaleString()}

{battery.monthlyRent && (

Monthly Rent

৳{battery.monthlyRent}/month

)}
)} {activeTab === 'bms' && battery.bmsData && (

BMS Real-time Data

Updated: {battery.bmsData.timestamp}

Voltage

{battery.bmsData.voltage}V

Current

{battery.bmsData.current}A

SOC

{battery.bmsData.soc}%

Temperature

{battery.bmsData.temperature}°C

Cycles

{battery.bmsData.cycles}

Health

80 ? 'text-green-600' : 'text-amber-600'}`}>{battery.bmsData.health}%

)} {activeTab === 'history' && (

Ownership History

{battery.ownershipLogs.length === 0 ? (
No history records
) : (
{battery.ownershipLogs.map((log, index) => (
{log.action} {log.timestamp}

From

{log.fromOwner}

To

{log.toOwner}

{log.rentAmount && (

Rent: ৳{log.rentAmount}/month

)} {log.notes && (

{log.notes}

)}
))}
)}
)} {activeTab === 'rent' && (

Rent Information

{battery.monthlyRent ? (

Monthly Rent Amount

৳{battery.monthlyRent}

per month

Status

{battery.assignedBikerName ? 'Rented' : 'Not Rented'}

{battery.assignedBikerName ? `to ${battery.assignedBikerName}` : 'Available for rental'}

) : (
This battery is not set up for rental.
)}
)} {activeTab === 'damage' && (

Damage History

{(battery.damageHistory || []).length > 0 ? (
{battery.damageHistory?.map(damage => ( ))}
Date Type Description Hub Est. Cost Actual Cost Status Actions
{damage.date} {damage.type} {damage.description} {damageForm.hubName || '-'} ৳{damage.estimatedCost.toLocaleString()} {damage.actualCost ? `৳${damage.actualCost.toLocaleString()}` : '-'} {damage.status === 'resolved' ? 'Resolved' : damage.status === 'in-progress' ? 'In Progress' : 'Reported'}
) : (
No damage history found.
)}
)} {activeTab === 'maintenance' && (

Maintenance History

{(battery.maintenanceHistory || []).length > 0 ? (
{battery.maintenanceHistory?.map(maint => ( ))}
Date Type Description Hub Cost Performed By Next Due Status Actions
{maint.date} {maint.type} {maint.description} {maintenanceForm.hubName || '-'} ৳{maint.cost.toLocaleString()} {maint.performedBy} {maint.nextDueDate || '-'} {maint.status === 'completed' ? 'Completed' : maint.status === 'pending' ? 'Pending' : 'Overdue'}
) : (
No maintenance history found.
)}
)}
{/* Damage Modal */} {showDamageModal && (

{editingDamage ? 'Edit Damage' : 'Add Damage'}

setDamageForm({ ...damageForm, date: e.target.value })} className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm" />