feat: add investor co-ownership tracking and management fields to battery details view
This commit is contained in:
@@ -994,6 +994,47 @@ export default function BatteryDetailPage({ params }: { params: Promise<{ id: st
|
||||
</div>
|
||||
)}
|
||||
|
||||
{battery.investorId && (
|
||||
<div className="bg-emerald-50 rounded-xl border border-emerald-200 p-5 mb-6">
|
||||
<div className="flex items-center justify-between mb-4">
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="w-10 h-10 rounded-lg bg-emerald-100 flex items-center justify-center">
|
||||
<Handshake className="w-5 h-5 text-emerald-600" />
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-emerald-800">Investor Co-Ownership Details</h3>
|
||||
<span className="text-xs text-emerald-600 bg-emerald-100 px-2 py-0.5 rounded-full font-medium">Active Investment</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-2 md:grid-cols-4 gap-4">
|
||||
<div className="bg-white rounded-lg p-3 border border-emerald-100/50">
|
||||
<p className="text-xs text-emerald-600 mb-1">Investor Name</p>
|
||||
<Link href={`/admin/investors/${battery.investorId}`} className="font-bold text-slate-800 hover:text-accent hover:underline flex items-center gap-1">
|
||||
{battery.investorName} <TrendingUp className="w-3.5 h-3.5 text-emerald-500" />
|
||||
</Link>
|
||||
<p className="text-xs text-slate-400">ID: {battery.investorId}</p>
|
||||
</div>
|
||||
<div className="bg-white rounded-lg p-3 border border-emerald-100/50">
|
||||
<p className="text-xs text-emerald-600 mb-1">Ownership Share (%)</p>
|
||||
<p className="font-bold text-emerald-700 text-lg">{battery.investorSharePercentage}%</p>
|
||||
<p className="text-xs text-slate-400">Share of Daily Rent Revenue</p>
|
||||
</div>
|
||||
<div className="bg-white rounded-lg p-3 border border-emerald-100/50">
|
||||
<p className="text-xs text-emerald-600 mb-1">Invested Amount</p>
|
||||
<p className="font-bold text-slate-800">৳{(battery.investedAmount || 0).toLocaleString()}</p>
|
||||
<p className="text-xs text-slate-400">Total Capital Contributed</p>
|
||||
</div>
|
||||
<div className="bg-white rounded-lg p-3 border border-emerald-100/50">
|
||||
<p className="text-xs text-emerald-600 mb-1">Investor Daily Payout</p>
|
||||
<p className="font-bold text-emerald-600">৳{(((battery.rentPrice || 150) * (battery.investorSharePercentage || 0)) / 100).toLocaleString()}/day</p>
|
||||
<p className="text-xs text-slate-400">Calculated from Daily Rent</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{showEditModal && (
|
||||
<EditBatteryModal
|
||||
battery={battery}
|
||||
@@ -1157,6 +1198,52 @@ function EditBatteryModal({
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="border-t border-slate-100 pt-4 mt-4">
|
||||
<h3 className="text-sm font-bold text-slate-800 mb-3">Investor Assignment (Co-Ownership)</h3>
|
||||
<div className="grid grid-cols-2 gap-4">
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-slate-700 mb-1">Investor ID</label>
|
||||
<input
|
||||
type="text"
|
||||
value={formData.investorId || ''}
|
||||
onChange={(e) => handleChange('investorId', e.target.value)}
|
||||
placeholder="INV-001"
|
||||
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-slate-700 mb-1">Investor Name</label>
|
||||
<input
|
||||
type="text"
|
||||
value={formData.investorName || ''}
|
||||
onChange={(e) => handleChange('investorName', e.target.value)}
|
||||
placeholder="Tahmid Rahman"
|
||||
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-slate-700 mb-1">Ownership Share (%)</label>
|
||||
<input
|
||||
type="number"
|
||||
value={formData.investorSharePercentage || 0}
|
||||
onChange={(e) => handleChange('investorSharePercentage', parseInt(e.target.value))}
|
||||
placeholder="60"
|
||||
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-slate-700 mb-1">Invested Amount (৳)</label>
|
||||
<input
|
||||
type="number"
|
||||
value={formData.investedAmount || 0}
|
||||
onChange={(e) => handleChange('investedAmount', parseInt(e.target.value))}
|
||||
placeholder="45000"
|
||||
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="p-5 border-t border-slate-100 flex gap-3 sticky bottom-0 bg-white">
|
||||
<button onClick={onClose} className="flex-1 py-2.5 px-4 border border-slate-200 rounded-lg font-semibold text-sm hover:bg-slate-50">
|
||||
|
||||
@@ -5,7 +5,7 @@ import Link from 'next/link';
|
||||
import {
|
||||
Battery, Plus, Search, Filter, X, Download, Upload, MoreHorizontal,
|
||||
BatteryCharging, BatteryWarning, BatteryFull, Zap, Thermometer,
|
||||
Activity, Clock, MapPin, Bike, User, History, TrendingUp, DollarSign,
|
||||
Activity, Clock, MapPin, Bike, User, History, TrendingUp, DollarSign, Handshake,
|
||||
Eye, Edit, Trash2, RefreshCw, CheckCircle, AlertTriangle, ChevronRight,
|
||||
ArrowUpDown, Calendar, Gauge, Timer
|
||||
} from 'lucide-react';
|
||||
@@ -65,6 +65,10 @@ interface Battery {
|
||||
bmsData?: BMSData;
|
||||
deposit?: number;
|
||||
rentPrice?: number;
|
||||
investorId?: string;
|
||||
investorName?: string;
|
||||
investorSharePercentage?: number;
|
||||
investedAmount?: number;
|
||||
history: BatteryHistory[];
|
||||
}
|
||||
|
||||
@@ -103,6 +107,10 @@ const mockBatteries: Battery[] = [
|
||||
purchasePrice: 45000,
|
||||
deposit: 5000,
|
||||
rentPrice: 150,
|
||||
investorId: 'INV-001',
|
||||
investorName: 'Tahmid Rahman',
|
||||
investorSharePercentage: 60,
|
||||
investedAmount: 45000,
|
||||
warrantyExpiry: '2027-01-15',
|
||||
status: 'in-use',
|
||||
currentSoc: 78,
|
||||
@@ -737,27 +745,7 @@ export default function BatteriesPage() {
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Details Modal */}
|
||||
{showDetailsModal && selectedBattery && (
|
||||
<div className="fixed inset-0 bg-black/50 flex items-center justify-center z-50 p-4">
|
||||
<div className="bg-white rounded-xl shadow-xl w-full max-w-2xl max-h-[90vh] overflow-hidden flex flex-col">
|
||||
<div className="p-5 border-b border-slate-100 flex items-center justify-between">
|
||||
<h2 className="text-lg font-bold text-slate-800">Battery Details</h2>
|
||||
<button onClick={() => setShowDetailsModal(false)} className="p-2 hover:bg-slate-100 rounded-lg">
|
||||
<X className="w-5 h-5 text-slate-400" />
|
||||
</button>
|
||||
</div>
|
||||
<BatteryDetails
|
||||
battery={selectedBattery}
|
||||
bikes={mockBikes}
|
||||
bikers={mockBikers}
|
||||
stations={mockStations}
|
||||
onAssign={handleAssignToBike}
|
||||
onClose={() => setShowDetailsModal(false)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
|
||||
{/* History Modal */}
|
||||
{showHistoryModal && selectedBattery && (
|
||||
|
||||
Reference in New Issue
Block a user