feat: integrate battery selection and sync battery level from mock data in fleet management form
This commit is contained in:
@@ -17,6 +17,7 @@ interface Bike {
|
||||
plateNumber: string;
|
||||
status: 'available' | 'rented' | 'maintenance' | 'retired';
|
||||
batteryLevel: number;
|
||||
batteryId?: string;
|
||||
location?: string; // deprecated - use hubId/hubName
|
||||
hubId?: string;
|
||||
hubName?: string;
|
||||
@@ -56,6 +57,15 @@ const hubs = [
|
||||
{ id: 'HUB-004', name: 'Mirpur Hub' },
|
||||
];
|
||||
|
||||
const mockBatteries = [
|
||||
{ id: 'BAT-001', brand: 'Lithium', model: '60V/30Ah', serialNumber: 'LTH-2024-001', chargeLevel: 95 },
|
||||
{ id: 'BAT-002', brand: 'Lithium', model: '60V/30Ah', serialNumber: 'LTH-2024-002', chargeLevel: 75 },
|
||||
{ id: 'BAT-003', brand: 'Lithium', model: '60V/40Ah', serialNumber: 'LTH-2024-003', chargeLevel: 45 },
|
||||
{ id: 'BAT-004', brand: 'Lithium', model: '60V/30Ah', serialNumber: 'LTH-2024-004', chargeLevel: 88 },
|
||||
{ id: 'BAT-005', brand: 'Lithium', model: '48V/25Ah', serialNumber: 'LTH-2024-005', chargeLevel: 62 },
|
||||
{ id: 'BAT-006', brand: 'Lithium', model: '60V/30Ah', serialNumber: 'LTH-2024-006', chargeLevel: 100 },
|
||||
];
|
||||
|
||||
const statusColors: Record<string, string> = {
|
||||
available: 'bg-green-100 text-green-700',
|
||||
rented: 'bg-blue-100 text-blue-700',
|
||||
@@ -159,9 +169,9 @@ export default function FleetPage() {
|
||||
<p className="font-semibold text-slate-700">{selectedMapBike.model}</p>
|
||||
<p className="text-xs text-slate-500">{selectedMapBike.brand} • {selectedMapBike.id}</p>
|
||||
<span className={`inline-flex items-center gap-1 text-xs font-medium px-2 py-0.5 rounded-full mt-1 ${selectedMapBike.status === 'available' ? 'bg-green-100 text-green-700' :
|
||||
selectedMapBike.status === 'rented' ? 'bg-blue-100 text-blue-700' :
|
||||
selectedMapBike.status === 'maintenance' ? 'bg-amber-100 text-amber-700' :
|
||||
'bg-slate-100 text-slate-500'
|
||||
selectedMapBike.status === 'rented' ? 'bg-blue-100 text-blue-700' :
|
||||
selectedMapBike.status === 'maintenance' ? 'bg-amber-100 text-amber-700' :
|
||||
'bg-slate-100 text-slate-500'
|
||||
}`}>
|
||||
{selectedMapBike.status}
|
||||
</span>
|
||||
@@ -182,7 +192,7 @@ export default function FleetPage() {
|
||||
<div className="flex justify-between">
|
||||
<span className="text-slate-500">Battery</span>
|
||||
<span className={`font-medium ${selectedMapBike.batteryLevel > 50 ? 'text-green-600' :
|
||||
selectedMapBike.batteryLevel > 20 ? 'text-amber-600' : 'text-red-600'
|
||||
selectedMapBike.batteryLevel > 20 ? 'text-amber-600' : 'text-red-600'
|
||||
}`}>{selectedMapBike.batteryLevel}%</span>
|
||||
</div>
|
||||
<div className="flex justify-between">
|
||||
@@ -488,6 +498,7 @@ function BikeForm({ bike, onSave, onCancel }: { bike: Bike | null; onSave: (bike
|
||||
plateNumber: '',
|
||||
status: 'available',
|
||||
batteryLevel: 100,
|
||||
batteryId: '',
|
||||
location: '', // deprecated
|
||||
hubId: '',
|
||||
hubName: '',
|
||||
@@ -563,14 +574,27 @@ function BikeForm({ bike, onSave, onCancel }: { bike: Bike | null; onSave: (bike
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-slate-700 mb-1">Battery Level (%)</label>
|
||||
<input
|
||||
type="number"
|
||||
value={formData.batteryLevel}
|
||||
onChange={(e) => handleChange('batteryLevel', parseInt(e.target.value))}
|
||||
<label className="block text-sm font-medium text-slate-700 mb-1">Battery</label>
|
||||
<select
|
||||
value={formData.batteryId || ''}
|
||||
onChange={(e) => {
|
||||
const battery = mockBatteries.find(b => b.id === e.target.value);
|
||||
handleChange('batteryId', e.target.value);
|
||||
if (battery) {
|
||||
handleChange('batteryLevel', battery.chargeLevel);
|
||||
}
|
||||
}}
|
||||
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-accent"
|
||||
/>
|
||||
>
|
||||
<option value="">Select Battery...</option>
|
||||
{mockBatteries.map(battery => (
|
||||
<option key={battery.id} value={battery.id}>
|
||||
{battery.brand} {battery.model} - {battery.serialNumber} ({battery.chargeLevel}%)
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-slate-700 mb-1">Hub *</label>
|
||||
<select
|
||||
@@ -588,6 +612,16 @@ function BikeForm({ bike, onSave, onCancel }: { bike: Bike | null; onSave: (bike
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-slate-700 mb-1">Battery Level (%)</label>
|
||||
<input
|
||||
type="number"
|
||||
value={formData.batteryLevel}
|
||||
onChange={(e) => handleChange('batteryLevel', parseInt(e.target.value))}
|
||||
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-accent"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-slate-700 mb-1">Assigned To</label>
|
||||
<input
|
||||
@@ -812,9 +846,9 @@ function FleetMap({ bikes, onSelectBike, selectedBike, large }: { bikes: Bike[];
|
||||
<path
|
||||
d={large ? "M0,0 L-3,-6 A3.5,3.5 0 1,1 3,-6 L0,0 Z" : "M0,0 L-2,-4 A2.5,2.5 0 1,1 2,-4 L0,0 Z"}
|
||||
className={`${data.bikes[0].status === 'available' ? 'fill-green-500' :
|
||||
data.bikes[0].status === 'rented' ? 'fill-blue-500' :
|
||||
data.bikes[0].status === 'maintenance' ? 'fill-amber-500' :
|
||||
'fill-slate-400'
|
||||
data.bikes[0].status === 'rented' ? 'fill-blue-500' :
|
||||
data.bikes[0].status === 'maintenance' ? 'fill-amber-500' :
|
||||
'fill-slate-400'
|
||||
}`}
|
||||
filter="url(#shadow)"
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user