@@ -2083,60 +2082,14 @@ export default function BikerDetailPage() {
>
) : (
<>
-
-
-
- setEditForm({ ...editForm, batSwappedAt: e.target.value })} className="w-full px-3 py-2 border border-slate-200 rounded-lg text-xs" placeholder="YYYY-MM-DD HH:MM" />
-
-
-
- setEditForm({ ...editForm, batOdometer: e.target.value })} className="w-full px-3 py-2 border border-slate-200 rounded-lg text-xs" />
-
+
+
Click edit button on existing batteries to update them.
>
)}
>
) : (
<>
-
-
-
{biker.bikes.batteries.map((bat, idx) => (
diff --git a/src/app/admin/rentals/[id]/page.tsx b/src/app/admin/rentals/[id]/page.tsx
index 6e78b22..1ca36cf 100644
--- a/src/app/admin/rentals/[id]/page.tsx
+++ b/src/app/admin/rentals/[id]/page.tsx
@@ -6,7 +6,7 @@ import Link from 'next/link';
import {
ArrowLeft, Bike, User, Calendar, DollarSign, Wallet, Shield, CheckCircle, XCircle,
Clock, Edit, Save, Plus, Trash2, Image, Upload, Lock, Unlock, AlertTriangle, MessageSquare, MapPin,
- Phone, MessageCircle, Play, Check, X, FileText, Download
+ Phone, MessageCircle, Play, Check, X, FileText, Download, Battery
} from 'lucide-react';
import {
canRentalAccept, canRentalReject, canRentalCancel, canRentalEdit,
@@ -41,6 +41,9 @@ interface Rental {
bikeModel: string;
bikePlate: string;
bikeBattery: number;
+ batteryId?: string;
+ batteryName?: string;
+ batteryRent?: number;
type: RentalType;
status: RentalStatus;
startDate: string;
@@ -73,6 +76,17 @@ interface Rental {
activatedAt?: string;
lockHistory?: LockEvent[];
paymentHistory?: PaymentHistory[];
+ batteryHistory?: BatteryRentalHistory[];
+}
+
+interface BatteryRentalHistory {
+ id: string;
+ batteryId: string;
+ batteryName: string;
+ assignedAt: string;
+ returnedAt?: string;
+ monthlyRent: number;
+ status: 'active' | 'returned';
}
interface LockEvent {
@@ -146,6 +160,10 @@ const mockRentals: Rental[] = [
{ id: 'lh3', action: 'locked', reason: 'Second payment overdue - Day 2 penalty', performedBy: 'System', performedAt: '2024-03-01' },
{ id: 'lh4', action: 'unlocked', reason: 'Payment cleared', performedBy: 'Admin Manager', performedAt: '2024-03-02' },
],
+ batteryHistory: [
+ { id: 'BAT-RENT-001', batteryId: 'BAT-DH-001', batteryName: 'Galaxy 72V 45Ah', assignedAt: '2024-01-16', monthlyRent: 1500, status: 'active' },
+ { id: 'BAT-RENT-002', batteryId: 'BAT-DH-002', batteryName: 'Titan 72V 50Ah', assignedAt: '2024-02-20', returnedAt: '2024-03-15', monthlyRent: 1800, status: 'returned' },
+ ],
},
{
id: 'RNT-002',
@@ -710,6 +728,53 @@ export default function RentalDetailPage() {
+ {/* Battery Rental History */}
+ {rental.batteryHistory && rental.batteryHistory.length > 0 && (
+
+
+ Battery Rental History
+
+
+
+
+
+ | Battery ID |
+ Battery Name |
+ Assigned |
+ Returned |
+ Monthly Rent |
+ Status |
+
+
+
+ {rental.batteryHistory.map(bat => (
+
+ | {bat.batteryId} |
+ {bat.batteryName} |
+ {bat.assignedAt} |
+ {bat.returnedAt || '-'} |
+ ৳{bat.monthlyRent} |
+
+
+ {bat.status === 'active' ? 'Active' : 'Returned'}
+
+ |
+
+ ))}
+
+
+
+ {rental.batteryHistory.some(b => b.status === 'active') && (
+
+
+ Active Battery Rent:
+ ৳{rental.batteryHistory.filter(b => b.status === 'active').reduce((sum, b) => sum + b.monthlyRent, 0)}/month
+
+
+ )}
+
+ )}
+
{/* Initial Condition Images */}
{/* {(rental.status === 'pending' || rental.status === 'accepted') && rental.initialImages && ( */}
{rental.initialImages && (
diff --git a/src/app/admin/rentals/page.tsx b/src/app/admin/rentals/page.tsx
index d73893f..2b53247 100644
--- a/src/app/admin/rentals/page.tsx
+++ b/src/app/admin/rentals/page.tsx
@@ -33,6 +33,9 @@ interface Rental {
bikeModel: string;
bikePlate: string;
bikeBattery: number;
+ batteryId?: string;
+ batteryName?: string;
+ batteryRent?: number;
type: RentalType;
status: RentalStatus;
startDate: string;
@@ -63,6 +66,15 @@ interface Rental {
createdAt: string;
acceptedAt?: string;
activatedAt?: string;
+ batteryHistory?: {
+ id: string;
+ batteryId: string;
+ batteryName: string;
+ assignedAt: string;
+ returnedAt?: string;
+ monthlyRent: number;
+ status: 'active' | 'returned';
+ }[];
}
interface Bike {
@@ -103,6 +115,23 @@ const mockHubs = [
{ id: 'HUB-004', name: 'Mirpur Hub' },
];
+interface Battery {
+ id: string;
+ brand: string;
+ model: string;
+ soc: number;
+ monthlyRent: number;
+ status: 'available' | 'in-use' | 'maintenance';
+}
+
+const mockBatteries: Battery[] = [
+ { id: 'BAT-DH-001', brand: 'Galaxy', model: '72V 45Ah', soc: 85, monthlyRent: 1500, status: 'available' },
+ { id: 'BAT-DH-002', brand: 'Titan', model: '72V 50Ah', soc: 92, monthlyRent: 1800, status: 'available' },
+ { id: 'BAT-DH-003', brand: 'PowerMax', model: '60V 40Ah', soc: 78, monthlyRent: 1200, status: 'available' },
+ { id: 'BAT-DH-004', brand: 'UltraCell', model: '72V 55Ah', soc: 88, monthlyRent: 2000, status: 'available' },
+ { id: 'BAT-DH-005', brand: 'EcoVolt', model: '48V 30Ah', soc: 65, monthlyRent: 800, status: 'available' },
+];
+
const rentalSettings = {
single: {
Premium: { deposit: 5000, contractMonths: [1, 3, 6, 12], dailyRate: 200, weeklyRate: 1200, monthlyRate: 5000 },
@@ -304,6 +333,8 @@ export default function RentalsPage() {
subscriptionType: 'daily' | 'weekly' | 'monthly';
contractMonths: number;
bikeId: string;
+ batteryId: string;
+ batteryRent: number;
startDate: string;
hubId: string;
depositAmount: number;
@@ -316,12 +347,16 @@ export default function RentalsPage() {
subscriptionType: 'daily',
contractMonths: 0,
bikeId: '',
+ batteryId: '',
+ batteryRent: 0,
startDate: new Date().toISOString().split('T')[0],
hubId: '',
depositAmount: 0,
depositPaymentMethod: 'cash',
});
+ const availableBatteries = mockBatteries.filter(b => b.status === 'available');
+
const [showJournalPreview, setShowJournalPreview] = useState(false);
useEffect(() => {
@@ -439,6 +474,7 @@ export default function RentalsPage() {
const bike = mockBikes.find(b => b.id === newRental.bikeId);
const user = mockUsers.find(u => u.id === newRental.userId);
const hub = mockHubs.find(h => h.id === newRental.hubId);
+ const battery = mockBatteries.find(b => b.id === newRental.batteryId);
const settings = planConditions[newRental.type]?.find(p => p.name === newRental.planConditionName) || planConditions[newRental.type]?.[0];
const rental: Rental = {
@@ -450,6 +486,9 @@ export default function RentalsPage() {
bikeModel: bike?.model || '',
bikePlate: bike?.plate || '',
bikeBattery: bike?.battery || 0,
+ batteryId: newRental.batteryId || undefined,
+ batteryName: battery ? `${battery.brand} ${battery.model}` : undefined,
+ batteryRent: newRental.batteryRent || undefined,
type: newRental.type,
status: 'pending',
startDate: newRental.startDate,
@@ -473,6 +512,14 @@ export default function RentalsPage() {
hubName: hub?.name || '',
imagesApproved: false,
createdAt: new Date().toISOString().split('T')[0],
+ batteryHistory: newRental.batteryId ? [{
+ id: `BAT-RENT-${Date.now()}`,
+ batteryId: newRental.batteryId,
+ batteryName: battery ? `${battery.brand} ${battery.model}` : '',
+ assignedAt: new Date().toISOString().split('T')[0],
+ monthlyRent: newRental.batteryRent,
+ status: 'active' as const,
+ }] : undefined,
};
setRentals([...rentals, rental]);
@@ -486,6 +533,8 @@ export default function RentalsPage() {
subscriptionType: 'daily',
contractMonths: 0,
bikeId: '',
+ batteryId: '',
+ batteryRent: 0,
evModel: '',
startDate: new Date().toISOString().split('T')[0],
hubId: '',
@@ -927,26 +976,52 @@ export default function RentalsPage() {
)}
{createStep === 3 && (
-
-
Step 3: Select Bike
-
- {selectedBike && (
-
- Battery:
- 70 ? 'bg-green-100 text-green-700' : selectedBike.battery > 40 ? 'bg-amber-100 text-amber-700' : 'bg-red-100 text-red-700'}`}>
- {selectedBike.battery}%
-
-
- )}
+
+
Step 3: Select Bike & Battery
+
+
+
+
+ {selectedBike && (
+
+ Battery:
+ 70 ? 'bg-green-100 text-green-700' : selectedBike.battery > 40 ? 'bg-amber-100 text-amber-700' : 'bg-red-100 text-red-700'}`}>
+ {selectedBike.battery}%
+
+
+ )}
+
+
+
+
+
+ {newRental.batteryId && (
+
+
Battery Monthly Rent: ৳{newRental.batteryRent}/month
+
+ )}
+
)}
@@ -958,7 +1033,18 @@ export default function RentalsPage() {
Deposit Amount: ৳{selectedPlan?.deposit.toLocaleString()}
User: {selectedUser?.name}
Bike: {selectedBike?.model} ({selectedBike?.plate})
+ {newRental.batteryId && (
+
Battery: {availableBatteries.find(b => b.id === newRental.batteryId)?.brand} {availableBatteries.find(b => b.id === newRental.batteryId)?.model} (Rent: ৳{newRental.batteryRent}/month)
+ )}
Hub: {mockHubs.find(h => h.id === newRental.hubId)?.name}
+ {newRental.batteryId && (
+
+
+ Combined Monthly Rent: ৳{(newRental.subscriptionType === 'daily' ? selectedPlan?.dailyRate : newRental.subscriptionType === 'weekly' ? selectedPlan?.weeklyRate : selectedPlan?.monthlyRate) + newRental.batteryRent}/month
+ (Bike: ৳{newRental.subscriptionType === 'daily' ? selectedPlan?.dailyRate : newRental.subscriptionType === 'weekly' ? selectedPlan?.weeklyRate : selectedPlan?.monthlyRate} + Battery: ৳{newRental.batteryRent})
+
+
+ )}