feat: add battery management functionality with assignment, registration, and investment tracking to investor dashboard
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
|
||||
import { useState } from 'react';
|
||||
import Link from 'next/link';
|
||||
import { Target, Plus, Zap, ChevronRight, ArrowRight, Edit, Trash2, Eye, TrendingUp, X, CreditCard } from 'lucide-react';
|
||||
import { Target, Plus, Zap, ChevronRight, ArrowRight, Edit, Trash2, Eye, TrendingUp, X, CreditCard, Battery } from 'lucide-react';
|
||||
import { investors } from '@/data/mockData';
|
||||
import toast from 'react-hot-toast';
|
||||
import InvestorNotification from '@/components/InvestorNotification';
|
||||
@@ -12,14 +12,20 @@ export default function MyInvestmentsPage() {
|
||||
const [showCreateModal, setShowCreateModal] = useState(false);
|
||||
const [selectedTemplate, setSelectedTemplate] = useState<any>(null);
|
||||
const [newInvestment, setNewInvestment] = useState({
|
||||
planName: '', planType: 'gold', totalInvestment: 0, initialPayment: 0, paymentType: 'full',
|
||||
planName: '', planType: 'gold', assetType: 'bike', totalInvestment: 0, initialPayment: 0, paymentType: 'full',
|
||||
startDate: '', endDate: '', paymentMethod: 'bank', transactionReference: '', notes: ''
|
||||
});
|
||||
|
||||
const PLAN_TEMPLATES = [
|
||||
{ id: '1bike', name: '1 Bike Plan', tier: 'Standard', evBasePrice: 200000, minQuantity: 1, duration: 12, maxInvestment: 1000000 },
|
||||
{ id: '5bike', name: '5 Bike Plan', tier: 'Premium', evBasePrice: 180000, minQuantity: 5, duration: 24, maxInvestment: 5000000 },
|
||||
{ id: '10bike', name: '10 Bike Plan', tier: 'Enterprise', evBasePrice: 170000, minQuantity: 10, duration: 36, maxInvestment: 10000000 },
|
||||
{ id: '1bike', name: '1 Bike Plan', tier: 'Standard', evBasePrice: 200000, minQuantity: 1, duration: 12, maxInvestment: 1000000, type: 'bike' },
|
||||
{ id: '5bike', name: '5 Bike Plan', tier: 'Premium', evBasePrice: 180000, minQuantity: 5, duration: 24, maxInvestment: 5000000, type: 'bike' },
|
||||
{ id: '10bike', name: '10 Bike Plan', tier: 'Enterprise', evBasePrice: 170000, minQuantity: 10, duration: 36, maxInvestment: 10000000, type: 'bike' },
|
||||
];
|
||||
|
||||
const BATTERY_TEMPLATES = [
|
||||
{ id: '1battery', name: '1 Battery Pack Plan', tier: 'Standard', evBasePrice: 45000, minQuantity: 1, duration: 12, maxInvestment: 500000, type: 'battery' },
|
||||
{ id: '5battery', name: '5 Battery Pack Plan', tier: 'Premium', evBasePrice: 42000, minQuantity: 5, duration: 18, maxInvestment: 2000000, type: 'battery' },
|
||||
{ id: '10battery', name: '10 Battery Pack Fleet', tier: 'Enterprise', evBasePrice: 40000, minQuantity: 10, duration: 24, maxInvestment: 5000000, type: 'battery' },
|
||||
];
|
||||
|
||||
const planConfig: Record<string, { bg: string; border: string; icon: string }> = {
|
||||
@@ -44,7 +50,7 @@ export default function MyInvestmentsPage() {
|
||||
);
|
||||
setShowCreateModal(false);
|
||||
setSelectedTemplate(null);
|
||||
setNewInvestment({ planName: '', planType: 'gold', totalInvestment: 0, initialPayment: 0, paymentType: 'full', startDate: '', endDate: '', paymentMethod: 'bank', transactionReference: '', notes: '' });
|
||||
setNewInvestment({ planName: '', planType: 'gold', assetType: 'bike', totalInvestment: 0, initialPayment: 0, paymentType: 'full', startDate: '', endDate: '', paymentMethod: 'bank', transactionReference: '', notes: '' });
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -85,7 +91,14 @@ export default function MyInvestmentsPage() {
|
||||
<div key={inv.id} className={`bg-white rounded-xl border ${style.border} overflow-hidden`}>
|
||||
<div className={`${style.bg} p-4 flex items-center justify-between`}>
|
||||
<div>
|
||||
<h4 className="font-semibold text-slate-800">{inv.planName}</h4>
|
||||
<h4 className="font-bold text-slate-800 flex items-center gap-1.5">
|
||||
{inv.planName.toLowerCase().includes('battery') ? (
|
||||
<Battery className="w-4 h-4 text-emerald-600 animate-pulse flex-shrink-0" />
|
||||
) : (
|
||||
<Zap className="w-4 h-4 text-investor flex-shrink-0" />
|
||||
)}
|
||||
{inv.planName}
|
||||
</h4>
|
||||
<p className="text-sm text-slate-500 capitalize">{inv.planType} Plan</p>
|
||||
</div>
|
||||
<span className={`text-xs font-medium px-2.5 py-1 rounded-full ${inv.status === 'active' ? 'bg-green-100 text-green-700' : 'bg-slate-200 text-slate-600'}`}>
|
||||
@@ -166,10 +179,41 @@ export default function MyInvestmentsPage() {
|
||||
<div className="p-5 overflow-y-auto flex-1 space-y-5">
|
||||
{!selectedTemplate ? (
|
||||
<>
|
||||
{/* Category Selector */}
|
||||
<div>
|
||||
<label className="text-sm font-semibold text-slate-700 mb-2 block">Choose Investment Asset Type *</label>
|
||||
<div className="grid grid-cols-2 gap-4">
|
||||
<button
|
||||
onClick={() => {
|
||||
setNewInvestment({ ...newInvestment, assetType: 'bike' });
|
||||
}}
|
||||
className={`py-3 px-4 rounded-xl border-2 flex items-center justify-center gap-2 font-bold text-sm transition-all ${
|
||||
newInvestment.assetType === 'bike'
|
||||
? 'bg-investor/10 border-investor text-investor shadow-sm'
|
||||
: 'bg-white border-slate-200 text-slate-600 hover:bg-slate-50'
|
||||
}`}
|
||||
>
|
||||
<Zap className="w-4 h-4 text-investor animate-pulse" /> Bike Investment Plans
|
||||
</button>
|
||||
<button
|
||||
onClick={() => {
|
||||
setNewInvestment({ ...newInvestment, assetType: 'battery' });
|
||||
}}
|
||||
className={`py-3 px-4 rounded-xl border-2 flex items-center justify-center gap-2 font-bold text-sm transition-all ${
|
||||
newInvestment.assetType === 'battery'
|
||||
? 'bg-emerald-100 border-emerald-500 text-emerald-800 shadow-sm'
|
||||
: 'bg-white border-slate-200 text-slate-600 hover:bg-slate-50'
|
||||
}`}
|
||||
>
|
||||
<Battery className="w-4 h-4 text-emerald-600 animate-pulse" /> Battery Investment Plans
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label className="text-sm font-medium text-slate-600 mb-2 block">Select Plan Template</label>
|
||||
<div className="grid grid-cols-1 sm:grid-cols-3 gap-3">
|
||||
{PLAN_TEMPLATES.map(plan => (
|
||||
{(newInvestment.assetType === 'battery' ? BATTERY_TEMPLATES : PLAN_TEMPLATES).map(plan => (
|
||||
<button
|
||||
key={plan.id}
|
||||
onClick={() => {
|
||||
@@ -182,10 +226,10 @@ export default function MyInvestmentsPage() {
|
||||
startDate: new Date().toISOString().split('T')[0],
|
||||
});
|
||||
}}
|
||||
className="p-4 rounded-lg border-2 border-slate-200 hover:border-investor/50 text-left transition-all hover:bg-slate-50"
|
||||
className={`p-4 rounded-lg border-2 text-left transition-all hover:bg-slate-50 ${newInvestment.assetType === 'battery' ? 'border-slate-200 hover:border-emerald-500' : 'border-slate-200 hover:border-investor/50'}`}
|
||||
>
|
||||
<p className="font-semibold text-slate-800">{plan.name}</p>
|
||||
<p className="text-xs text-slate-500 mt-1">৳{plan.evBasePrice.toLocaleString()} × {plan.minQuantity} bikes</p>
|
||||
<p className="text-xs text-slate-500 mt-1">৳{plan.evBasePrice.toLocaleString()} × {plan.minQuantity} {newInvestment.assetType}(s)</p>
|
||||
<p className="text-sm text-slate-600 mt-1">Duration: {plan.duration} months</p>
|
||||
</button>
|
||||
))}
|
||||
@@ -228,11 +272,11 @@ export default function MyInvestmentsPage() {
|
||||
|
||||
<div className="grid grid-cols-3 gap-4">
|
||||
<div>
|
||||
<label className="text-sm font-medium text-slate-600 mb-1 block">EV Base Price (৳)</label>
|
||||
<label className="text-sm font-medium text-slate-600 mb-1 block">{selectedTemplate.type === 'battery' ? 'Battery Pack Cost (৳)' : 'EV Base Price (৳)'}</label>
|
||||
<input type="number" value={selectedTemplate.evBasePrice} disabled className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm bg-slate-50 cursor-not-allowed" />
|
||||
</div>
|
||||
<div>
|
||||
<label className="text-sm font-medium text-slate-600 mb-1 block">Minimum Quantity</label>
|
||||
<label className="text-sm font-medium text-slate-600 mb-1 block">Minimum Quantity ({selectedTemplate.type === 'battery' ? 'Packs' : 'Bikes'})</label>
|
||||
<input type="number" value={selectedTemplate.minQuantity} disabled className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm bg-slate-50 cursor-not-allowed" />
|
||||
</div>
|
||||
<div>
|
||||
|
||||
Reference in New Issue
Block a user