refactor: rename investment plans to EV investment plans across UI components

This commit is contained in:
sazzadulalambd
2026-05-19 16:20:31 +06:00
parent 5d1a5454c0
commit c6a9fd960e
7 changed files with 93 additions and 100 deletions

View File

@@ -5,9 +5,9 @@ import Link from 'next/link';
import { useParams } from 'next/navigation'; import { useParams } from 'next/navigation';
import { investors as initialInvestors, bikes as initialBikes, transactions as initialTransactions } from '@/data/mockData'; import { investors as initialInvestors, bikes as initialBikes, transactions as initialTransactions } from '@/data/mockData';
import type { Investor } from '@/data/mockData'; import type { Investor } from '@/data/mockData';
import { import {
ArrowLeft, Wallet, TrendingUp, Banknote, Calendar, Phone, Mail, MapPin, Edit, Trash2, Plus, X, Bike, ArrowLeft, Wallet, TrendingUp, Banknote, Calendar, Phone, Mail, MapPin, Edit, Trash2, Plus, X, Bike,
User, FileText, CreditCard, DollarSign, Clock, ChevronDown, ExternalLink, Download, Upload, User, FileText, CreditCard, DollarSign, Clock, ChevronDown, ExternalLink, Download, Upload,
AlertTriangle, Shield, Star, CheckCircle, XCircle, Search, Filter, BookOpen, ArrowRight, Printer AlertTriangle, Shield, Star, CheckCircle, XCircle, Search, Filter, BookOpen, ArrowRight, Printer
} from 'lucide-react'; } from 'lucide-react';
@@ -42,13 +42,13 @@ const bikeStatusColors: Record<string, string> = {
export default function InvestorDetailPage() { export default function InvestorDetailPage() {
const params = useParams(); const params = useParams();
const investorId = params.id as string; const investorId = params.id as string;
const [investors] = useState<Investor[]>(initialInvestors); const [investors] = useState<Investor[]>(initialInvestors);
const investor = investors.find(i => i.id === investorId); const investor = investors.find(i => i.id === investorId);
const assignedBikes = initialBikes.filter(b => b.investorId === investorId); const assignedBikes = initialBikes.filter(b => b.investorId === investorId);
// Investor transactions are filtered below // Investor transactions are filtered below
const [activeTab, setActiveTab] = useState('overview'); const [activeTab, setActiveTab] = useState('overview');
const [showEditModal, setShowEditModal] = useState(false); const [showEditModal, setShowEditModal] = useState(false);
const [showAssignBikeModal, setShowAssignBikeModal] = useState(false); const [showAssignBikeModal, setShowAssignBikeModal] = useState(false);
@@ -108,7 +108,7 @@ export default function InvestorDetailPage() {
const invId = `INV-${Date.now()}`; const invId = `INV-${Date.now()}`;
const year = new Date().getFullYear(); const year = new Date().getFullYear();
const transactionRef = newInvestment.transactionReference || `INV/${year}/${String(investor.investments.length + 1).padStart(4, '0')}`; const transactionRef = newInvestment.transactionReference || `INV/${year}/${String(investor.investments.length + 1).padStart(4, '0')}`;
const getDebitAccount = (method: string) => { const getDebitAccount = (method: string) => {
switch (method) { switch (method) {
case 'bank': return { code: '1200', name: 'Bank - City Bank' }; case 'bank': return { code: '1200', name: 'Bank - City Bank' };
@@ -118,9 +118,9 @@ export default function InvestorDetailPage() {
default: return { code: '1200', name: 'Bank - City Bank' }; default: return { code: '1200', name: 'Bank - City Bank' };
} }
}; };
const debitAccount = getDebitAccount(newInvestment.paymentMethod); const debitAccount = getDebitAccount(newInvestment.paymentMethod);
const journalEntry = { const journalEntry = {
entryId: `JE-${Date.now()}`, entryId: `JE-${Date.now()}`,
date: newInvestment.startDate, date: newInvestment.startDate,
@@ -137,9 +137,9 @@ export default function InvestorDetailPage() {
amount: newInvestment.totalInvestment, amount: newInvestment.totalInvestment,
paymentMethod: newInvestment.paymentMethod paymentMethod: newInvestment.paymentMethod
}; };
setInvestorJournals([journalEntry, ...investorJournals]); setInvestorJournals([journalEntry, ...investorJournals]);
console.log('Creating Investment:', { console.log('Creating Investment:', {
id: invId, id: invId,
investorId: investor.id, investorId: investor.id,
@@ -149,7 +149,7 @@ export default function InvestorDetailPage() {
transactionId: transactionRef, transactionId: transactionRef,
createdAt: new Date().toISOString() createdAt: new Date().toISOString()
}); });
alert(`Investment created successfully! alert(`Investment created successfully!
Investor: ${investor.name} Investor: ${investor.name}
@@ -424,7 +424,7 @@ Credit (Cr): Investor Liability ৳${newInvestment.totalInvestment.toLocaleStri
<div> <div>
<div className="flex items-center justify-between mb-4"> <div className="flex items-center justify-between mb-4">
<h3 className="font-semibold text-slate-800">Assigned Bikes</h3> <h3 className="font-semibold text-slate-800">Assigned Bikes</h3>
<button <button
onClick={() => setShowAssignBikeModal(true)} onClick={() => setShowAssignBikeModal(true)}
className="py-2 px-3 bg-investor text-white rounded-lg text-sm font-medium hover:bg-investor-dark flex items-center gap-1" className="py-2 px-3 bg-investor text-white rounded-lg text-sm font-medium hover:bg-investor-dark flex items-center gap-1"
> >
@@ -485,7 +485,7 @@ Credit (Cr): Investor Liability ৳${newInvestment.totalInvestment.toLocaleStri
{activeTab === 'investments' && ( {activeTab === 'investments' && (
<div className="space-y-6"> <div className="space-y-6">
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<h3 className="font-semibold text-slate-800">Investment Plans</h3> <h3 className="font-semibold text-slate-800">EV Investment Plans</h3>
<button onClick={() => setShowCreateInvestmentModal(true)} className="py-2 px-3 bg-investor text-white rounded-lg text-sm font-medium hover:bg-investor-dark flex items-center gap-1"> <button onClick={() => setShowCreateInvestmentModal(true)} className="py-2 px-3 bg-investor text-white rounded-lg text-sm font-medium hover:bg-investor-dark flex items-center gap-1">
<Plus className="w-4 h-4" /> Add Investment <Plus className="w-4 h-4" /> Add Investment
</button> </button>
@@ -767,27 +767,25 @@ Credit (Cr): Investor Liability ৳${newInvestment.totalInvestment.toLocaleStri
{investorTransactions.map(tx => ( {investorTransactions.map(tx => (
<div key={tx.id} className="flex items-center justify-between p-3 bg-slate-50 rounded-lg"> <div key={tx.id} className="flex items-center justify-between p-3 bg-slate-50 rounded-lg">
<div className="flex items-center gap-3"> <div className="flex items-center gap-3">
<div className={`w-10 h-10 rounded-full flex items-center justify-center ${ <div className={`w-10 h-10 rounded-full flex items-center justify-center ${tx.type === 'earning' || tx.type === 'bike_earning' || tx.type === 'investment_return' ? 'bg-green-100' :
tx.type === 'earning' || tx.type === 'bike_earning' || tx.type === 'investment_return' ? 'bg-green-100' : tx.type === 'withdrawal' ? 'bg-red-100' :
tx.type === 'withdrawal' ? 'bg-red-100' : tx.type === 'investment' ? 'bg-purple-100' :
tx.type === 'investment' ? 'bg-purple-100' : tx.type === 'referral_bonus' ? 'bg-yellow-100' :
tx.type === 'referral_bonus' ? 'bg-yellow-100' : tx.type === 'adjustment' || tx.type === 'penalty' ? 'bg-orange-100' : 'bg-blue-100'
tx.type === 'adjustment' || tx.type === 'penalty' ? 'bg-orange-100' : 'bg-blue-100' }`}>
}`}> <DollarSign className={`w-5 h-5 ${tx.type === 'earning' || tx.type === 'bike_earning' ? 'text-green-600' :
<DollarSign className={`w-5 h-5 ${ tx.type === 'withdrawal' ? 'text-red-600' :
tx.type === 'earning' || tx.type === 'bike_earning' ? 'text-green-600' : tx.type === 'investment' ? 'text-purple-600' :
tx.type === 'withdrawal' ? 'text-red-600' : tx.type === 'referral_bonus' ? 'text-yellow-600' :
tx.type === 'investment' ? 'text-purple-600' : tx.type === 'adjustment' || tx.type === 'penalty' ? 'text-orange-600' : 'text-blue-600'
tx.type === 'referral_bonus' ? 'text-yellow-600' : }`} />
tx.type === 'adjustment' || tx.type === 'penalty' ? 'text-orange-600' : 'text-blue-600'
}`} />
</div> </div>
<div> <div>
<p className="text-sm font-medium text-slate-700">{tx.description}</p> <p className="text-sm font-medium text-slate-700">{tx.description}</p>
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<p className="text-xs text-slate-400">{tx.createdAt}</p> <p className="text-xs text-slate-400">{tx.createdAt}</p>
{tx.referenceNumber && ( {tx.referenceNumber && (
<button <button
onClick={() => { onClick={() => {
const getAccountingInfo = (type: string, amount: number) => { const getAccountingInfo = (type: string, amount: number) => {
if (type === 'investment') { if (type === 'investment') {
@@ -840,17 +838,15 @@ Credit (Cr): Investor Liability ৳${newInvestment.totalInvestment.toLocaleStri
</div> </div>
</div> </div>
<div className="text-right"> <div className="text-right">
<p className={`text-sm font-medium ${ <p className={`text-sm font-medium ${tx.type === 'earning' || tx.type === 'bike_earning' || tx.type === 'investment_return' || tx.type === 'referral_bonus' ? 'text-green-600' :
tx.type === 'earning' || tx.type === 'bike_earning' || tx.type === 'investment_return' || tx.type === 'referral_bonus' ? 'text-green-600' :
tx.type === 'withdrawal' || tx.type === 'penalty' || tx.type === 'adjustment' ? 'text-red-600' : 'text-blue-600' tx.type === 'withdrawal' || tx.type === 'penalty' || tx.type === 'adjustment' ? 'text-red-600' : 'text-blue-600'
}`}> }`}>
{tx.type === 'earning' || tx.type === 'bike_earning' || tx.type === 'investment_return' || tx.type === 'referral_bonus' ? '+' : tx.type === 'withdrawal' || tx.type === 'penalty' || tx.type === 'adjustment' ? '-' : '+'}{tx.amount.toLocaleString()} {tx.type === 'earning' || tx.type === 'bike_earning' || tx.type === 'investment_return' || tx.type === 'referral_bonus' ? '+' : tx.type === 'withdrawal' || tx.type === 'penalty' || tx.type === 'adjustment' ? '-' : '+'}{tx.amount.toLocaleString()}
</p> </p>
<span className={`text-xs font-medium px-2 py-0.5 rounded-full ${ <span className={`text-xs font-medium px-2 py-0.5 rounded-full ${tx.status === 'completed' ? 'bg-green-100 text-green-700' :
tx.status === 'completed' ? 'bg-green-100 text-green-700' : tx.status === 'pending' ? 'bg-amber-100 text-amber-700' :
tx.status === 'pending' ? 'bg-amber-100 text-amber-700' : tx.status === 'cancelled' ? 'bg-red-100 text-red-700' : 'bg-slate-100 text-slate-700'
tx.status === 'cancelled' ? 'bg-red-100 text-red-700' : 'bg-slate-100 text-slate-700' }`}>
}`}>
{tx.status} {tx.status}
</span> </span>
</div> </div>
@@ -875,23 +871,21 @@ Credit (Cr): Investor Liability ৳${newInvestment.totalInvestment.toLocaleStri
<Plus className="w-4 h-4" /> Upload Document <Plus className="w-4 h-4" /> Upload Document
</button> </button>
</div> </div>
<div className="space-y-2 mb-6"> <div className="space-y-2 mb-6">
{investor.kycDocuments?.map((doc, idx) => ( {investor.kycDocuments?.map((doc, idx) => (
<div key={idx} className="flex items-center justify-between p-4 bg-slate-50 rounded-lg"> <div key={idx} className="flex items-center justify-between p-4 bg-slate-50 rounded-lg">
<div className="flex items-center gap-3"> <div className="flex items-center gap-3">
<div className={`w-12 h-12 rounded-lg flex items-center justify-center ${ <div className={`w-12 h-12 rounded-lg flex items-center justify-center ${doc.type === 'nid' ? 'bg-blue-100' :
doc.type === 'nid' ? 'bg-blue-100' :
doc.type === 'passport' ? 'bg-purple-100' : doc.type === 'passport' ? 'bg-purple-100' :
doc.type === 'bank_statement' ? 'bg-green-100' : doc.type === 'bank_statement' ? 'bg-green-100' :
doc.type === 'tin_certificate' ? 'bg-amber-100' : 'bg-slate-100' doc.type === 'tin_certificate' ? 'bg-amber-100' : 'bg-slate-100'
}`}> }`}>
<FileText className={`w-6 h-6 ${ <FileText className={`w-6 h-6 ${doc.type === 'nid' ? 'text-blue-600' :
doc.type === 'nid' ? 'text-blue-600' :
doc.type === 'passport' ? 'text-purple-600' : doc.type === 'passport' ? 'text-purple-600' :
doc.type === 'bank_statement' ? 'text-green-600' : doc.type === 'bank_statement' ? 'text-green-600' :
doc.type === 'tin_certificate' ? 'text-amber-600' : 'text-slate-600' doc.type === 'tin_certificate' ? 'text-amber-600' : 'text-slate-600'
}`} /> }`} />
</div> </div>
<div> <div>
<p className="text-sm font-medium text-slate-700 capitalize">{doc.type.replace('_', ' ')}</p> <p className="text-sm font-medium text-slate-700 capitalize">{doc.type.replace('_', ' ')}</p>
@@ -911,7 +905,7 @@ Credit (Cr): Investor Liability ৳${newInvestment.totalInvestment.toLocaleStri
<button onClick={() => alert('Edit document')} className="p-2 hover:bg-slate-200 rounded-lg"> <button onClick={() => alert('Edit document')} className="p-2 hover:bg-slate-200 rounded-lg">
<Edit className="w-4 h-4 text-slate-400" /> <Edit className="w-4 h-4 text-slate-400" />
</button> </button>
<button onClick={() => { if(confirm('Delete this document?')) alert('Document deleted'); }} className="p-2 hover:bg-red-50 rounded-lg"> <button onClick={() => { if (confirm('Delete this document?')) alert('Document deleted'); }} className="p-2 hover:bg-red-50 rounded-lg">
<Trash2 className="w-4 h-4 text-red-400" /> <Trash2 className="w-4 h-4 text-red-400" />
</button> </button>
</div> </div>
@@ -928,11 +922,11 @@ Credit (Cr): Investor Liability ৳${newInvestment.totalInvestment.toLocaleStri
<div className="bg-blue-50 border border-blue-200 rounded-lg p-4"> <div className="bg-blue-50 border border-blue-200 rounded-lg p-4">
<h4 className="font-semibold text-blue-800 mb-2">KYC Status: {investor.kycStatus.toUpperCase()}</h4> <h4 className="font-semibold text-blue-800 mb-2">KYC Status: {investor.kycStatus.toUpperCase()}</h4>
<p className="text-sm text-blue-700"> <p className="text-sm text-blue-700">
{investor.kycStatus === 'verified' {investor.kycStatus === 'verified'
? 'All documents have been verified. Investor is fully verified.' ? 'All documents have been verified. Investor is fully verified.'
: investor.kycStatus === 'pending' : investor.kycStatus === 'pending'
? 'Documents are under review. Verification typically takes 24-48 hours.' ? 'Documents are under review. Verification typically takes 24-48 hours.'
: 'Please upload required documents for verification.'} : 'Please upload required documents for verification.'}
</p> </p>
</div> </div>
</div> </div>
@@ -952,7 +946,7 @@ Credit (Cr): Investor Liability ৳${newInvestment.totalInvestment.toLocaleStri
<div className="p-5"> <div className="p-5">
<label className="text-sm font-medium text-slate-600 mb-1 block">Select Bike</label> <label className="text-sm font-medium text-slate-600 mb-1 block">Select Bike</label>
<select <select
value={selectedBikeId} value={selectedBikeId}
onChange={(e) => setSelectedBikeId(e.target.value)} onChange={(e) => setSelectedBikeId(e.target.value)}
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm" className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm"
@@ -988,8 +982,8 @@ Credit (Cr): Investor Liability ৳${newInvestment.totalInvestment.toLocaleStri
<div className="grid grid-cols-2 gap-4"> <div className="grid grid-cols-2 gap-4">
<div> <div>
<label className="text-sm font-medium text-slate-600 mb-1 block">Plan Name *</label> <label className="text-sm font-medium text-slate-600 mb-1 block">Plan Name *</label>
<input <input
type="text" type="text"
value={newInvestment.planName} value={newInvestment.planName}
onChange={(e) => setNewInvestment({ ...newInvestment, planName: e.target.value })} onChange={(e) => setNewInvestment({ ...newInvestment, planName: e.target.value })}
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm" className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm"
@@ -998,7 +992,7 @@ Credit (Cr): Investor Liability ৳${newInvestment.totalInvestment.toLocaleStri
</div> </div>
<div> <div>
<label className="text-sm font-medium text-slate-600 mb-1 block">Plan Type *</label> <label className="text-sm font-medium text-slate-600 mb-1 block">Plan Type *</label>
<select <select
value={newInvestment.planType} value={newInvestment.planType}
onChange={(e) => setNewInvestment({ ...newInvestment, planType: e.target.value as any, expectedRoi: e.target.value === 'silver' ? 12 : e.target.value === 'gold' ? 15 : e.target.value === 'platinum' ? 18 : 20 })} onChange={(e) => setNewInvestment({ ...newInvestment, planType: e.target.value as any, expectedRoi: e.target.value === 'silver' ? 12 : e.target.value === 'gold' ? 15 : e.target.value === 'platinum' ? 18 : 20 })}
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm" className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm"
@@ -1016,7 +1010,7 @@ Credit (Cr): Investor Liability ৳${newInvestment.totalInvestment.toLocaleStri
<div className="grid grid-cols-2 gap-2 max-h-32 overflow-y-auto border border-slate-200 rounded-lg p-2"> <div className="grid grid-cols-2 gap-2 max-h-32 overflow-y-auto border border-slate-200 rounded-lg p-2">
{availableBikesForAssignment.map(bike => ( {availableBikesForAssignment.map(bike => (
<label key={bike.id} className="flex items-center gap-2 p-2 hover:bg-slate-50 rounded cursor-pointer"> <label key={bike.id} className="flex items-center gap-2 p-2 hover:bg-slate-50 rounded cursor-pointer">
<input <input
type="checkbox" type="checkbox"
checked={newInvestment.selectedBikeIds.includes(bike.id)} checked={newInvestment.selectedBikeIds.includes(bike.id)}
onChange={(e) => { onChange={(e) => {
@@ -1037,7 +1031,7 @@ Credit (Cr): Investor Liability ৳${newInvestment.totalInvestment.toLocaleStri
<div className="grid grid-cols-3 gap-4"> <div className="grid grid-cols-3 gap-4">
<div> <div>
<label className="text-sm font-medium text-slate-600 mb-1 block">Investment Amount () *</label> <label className="text-sm font-medium text-slate-600 mb-1 block">Investment Amount () *</label>
<input <input
type="number" type="number"
value={newInvestment.totalInvestment} value={newInvestment.totalInvestment}
onChange={(e) => setNewInvestment({ ...newInvestment, totalInvestment: Number(e.target.value), monthlyReturn: Math.round(Number(e.target.value) * newInvestment.expectedRoi / 100 / 12) })} onChange={(e) => setNewInvestment({ ...newInvestment, totalInvestment: Number(e.target.value), monthlyReturn: Math.round(Number(e.target.value) * newInvestment.expectedRoi / 100 / 12) })}
@@ -1047,7 +1041,7 @@ Credit (Cr): Investor Liability ৳${newInvestment.totalInvestment.toLocaleStri
</div> </div>
<div> <div>
<label className="text-sm font-medium text-slate-600 mb-1 block">Monthly Return ()</label> <label className="text-sm font-medium text-slate-600 mb-1 block">Monthly Return ()</label>
<input <input
type="number" type="number"
value={newInvestment.monthlyReturn} value={newInvestment.monthlyReturn}
onChange={(e) => setNewInvestment({ ...newInvestment, monthlyReturn: Number(e.target.value) })} onChange={(e) => setNewInvestment({ ...newInvestment, monthlyReturn: Number(e.target.value) })}
@@ -1057,7 +1051,7 @@ Credit (Cr): Investor Liability ৳${newInvestment.totalInvestment.toLocaleStri
</div> </div>
<div> <div>
<label className="text-sm font-medium text-slate-600 mb-1 block">Expected ROI (%)</label> <label className="text-sm font-medium text-slate-600 mb-1 block">Expected ROI (%)</label>
<input <input
type="number" type="number"
value={newInvestment.expectedRoi} value={newInvestment.expectedRoi}
onChange={(e) => setNewInvestment({ ...newInvestment, expectedRoi: Number(e.target.value) })} onChange={(e) => setNewInvestment({ ...newInvestment, expectedRoi: Number(e.target.value) })}
@@ -1070,7 +1064,7 @@ Credit (Cr): Investor Liability ৳${newInvestment.totalInvestment.toLocaleStri
<div className="grid grid-cols-2 gap-4"> <div className="grid grid-cols-2 gap-4">
<div> <div>
<label className="text-sm font-medium text-slate-600 mb-1 block">Start Date *</label> <label className="text-sm font-medium text-slate-600 mb-1 block">Start Date *</label>
<input <input
type="date" type="date"
value={newInvestment.startDate} value={newInvestment.startDate}
onChange={(e) => setNewInvestment({ ...newInvestment, startDate: e.target.value })} onChange={(e) => setNewInvestment({ ...newInvestment, startDate: e.target.value })}
@@ -1079,7 +1073,7 @@ Credit (Cr): Investor Liability ৳${newInvestment.totalInvestment.toLocaleStri
</div> </div>
<div> <div>
<label className="text-sm font-medium text-slate-600 mb-1 block">End Date</label> <label className="text-sm font-medium text-slate-600 mb-1 block">End Date</label>
<input <input
type="date" type="date"
value={newInvestment.endDate} value={newInvestment.endDate}
onChange={(e) => setNewInvestment({ ...newInvestment, endDate: e.target.value })} onChange={(e) => setNewInvestment({ ...newInvestment, endDate: e.target.value })}
@@ -1091,7 +1085,7 @@ Credit (Cr): Investor Liability ৳${newInvestment.totalInvestment.toLocaleStri
<div className="grid grid-cols-2 gap-4"> <div className="grid grid-cols-2 gap-4">
<div> <div>
<label className="text-sm font-medium text-slate-600 mb-1 block">Payment Method *</label> <label className="text-sm font-medium text-slate-600 mb-1 block">Payment Method *</label>
<select <select
value={newInvestment.paymentMethod} value={newInvestment.paymentMethod}
onChange={(e) => setNewInvestment({ ...newInvestment, paymentMethod: e.target.value as any })} onChange={(e) => setNewInvestment({ ...newInvestment, paymentMethod: e.target.value as any })}
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm" className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm"
@@ -1104,7 +1098,7 @@ Credit (Cr): Investor Liability ৳${newInvestment.totalInvestment.toLocaleStri
</div> </div>
<div> <div>
<label className="text-sm font-medium text-slate-600 mb-1 block">Transaction Reference</label> <label className="text-sm font-medium text-slate-600 mb-1 block">Transaction Reference</label>
<input <input
type="text" type="text"
value={newInvestment.transactionReference} value={newInvestment.transactionReference}
onChange={(e) => setNewInvestment({ ...newInvestment, transactionReference: e.target.value })} onChange={(e) => setNewInvestment({ ...newInvestment, transactionReference: e.target.value })}
@@ -1116,7 +1110,7 @@ Credit (Cr): Investor Liability ৳${newInvestment.totalInvestment.toLocaleStri
<div> <div>
<label className="text-sm font-medium text-slate-600 mb-1 block">Notes</label> <label className="text-sm font-medium text-slate-600 mb-1 block">Notes</label>
<textarea <textarea
value={newInvestment.notes} value={newInvestment.notes}
onChange={(e) => setNewInvestment({ ...newInvestment, notes: e.target.value })} onChange={(e) => setNewInvestment({ ...newInvestment, notes: e.target.value })}
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm" className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm"
@@ -1136,7 +1130,7 @@ Credit (Cr): Investor Liability ৳${newInvestment.totalInvestment.toLocaleStri
} }
}; };
const debitDisplay = getDebitAccountDisplay(newInvestment.paymentMethod); const debitDisplay = getDebitAccountDisplay(newInvestment.paymentMethod);
return ( return (
<div className="bg-green-50 border border-green-200 rounded-lg p-4"> <div className="bg-green-50 border border-green-200 rounded-lg p-4">
<div className="flex items-center gap-2 mb-3"> <div className="flex items-center gap-2 mb-3">
@@ -1175,8 +1169,8 @@ Credit (Cr): Investor Liability ৳${newInvestment.totalInvestment.toLocaleStri
<div className="p-5 border-t border-slate-100 flex justify-end gap-3"> <div className="p-5 border-t border-slate-100 flex justify-end gap-3">
<button onClick={() => setShowCreateInvestmentModal(false)} className="px-4 py-2 border border-slate-200 text-slate-600 rounded-lg text-sm hover:bg-slate-50">Cancel</button> <button onClick={() => setShowCreateInvestmentModal(false)} className="px-4 py-2 border border-slate-200 text-slate-600 rounded-lg text-sm hover:bg-slate-50">Cancel</button>
<button <button
onClick={handleCreateInvestment} onClick={handleCreateInvestment}
disabled={!newInvestment.planName || !newInvestment.totalInvestment} disabled={!newInvestment.planName || !newInvestment.totalInvestment}
className="px-4 py-2 bg-investor text-white rounded-lg text-sm hover:bg-investor-dark disabled:opacity-50 flex items-center gap-2" className="px-4 py-2 bg-investor text-white rounded-lg text-sm hover:bg-investor-dark disabled:opacity-50 flex items-center gap-2"
> >
@@ -1409,13 +1403,13 @@ Credit (Cr): Investor Liability ৳${newInvestment.totalInvestment.toLocaleStri
<X className="w-5 h-5 text-slate-400" /> <X className="w-5 h-5 text-slate-400" />
</button> </button>
</div> </div>
<div className="p-6" id="invoice-content"> <div className="p-6" id="invoice-content">
<div className="text-center border-b border-slate-200 pb-4 mb-4"> <div className="text-center border-b border-slate-200 pb-4 mb-4">
<h1 className="text-xl font-extrabold text-investor">JAIBEN Mobility Ltd</h1> <h1 className="text-xl font-extrabold text-investor">JAIBEN Mobility Ltd</h1>
<p className="text-xs text-slate-500">EV Rental & Investment Company</p> <p className="text-xs text-slate-500">EV Rental & Investment Company</p>
</div> </div>
<div className="flex justify-between mb-4"> <div className="flex justify-between mb-4">
<div> <div>
<p className="text-xs text-slate-500">Invoice No</p> <p className="text-xs text-slate-500">Invoice No</p>
@@ -1426,13 +1420,13 @@ Credit (Cr): Investor Liability ৳${newInvestment.totalInvestment.toLocaleStri
<p className="text-sm font-medium">{selectedInvoice.date}</p> <p className="text-sm font-medium">{selectedInvoice.date}</p>
</div> </div>
</div> </div>
<div className="mb-4"> <div className="mb-4">
<p className="text-xs text-slate-500">Investor</p> <p className="text-xs text-slate-500">Investor</p>
<p className="text-sm font-medium">{selectedInvoice.investorName}</p> <p className="text-sm font-medium">{selectedInvoice.investorName}</p>
<p className="text-xs text-slate-400">{selectedInvoice.investorId}</p> <p className="text-xs text-slate-400">{selectedInvoice.investorId}</p>
</div> </div>
<table className="w-full mb-4"> <table className="w-full mb-4">
<thead> <thead>
<tr className="border-b border-slate-200"> <tr className="border-b border-slate-200">
@@ -1453,17 +1447,16 @@ Credit (Cr): Investor Liability ৳${newInvestment.totalInvestment.toLocaleStri
</tr> </tr>
</tfoot> </tfoot>
</table> </table>
<div className="flex justify-between mb-2"> <div className="flex justify-between mb-2">
<span className="text-xs text-slate-500">Status</span> <span className="text-xs text-slate-500">Status</span>
<span className={`text-xs px-2 py-1 rounded-full ${ <span className={`text-xs px-2 py-1 rounded-full ${selectedInvoice.status === 'completed' ? 'bg-green-100 text-green-700' :
selectedInvoice.status === 'completed' ? 'bg-green-100 text-green-700' :
selectedInvoice.status === 'pending' ? 'bg-amber-100 text-amber-700' : 'bg-slate-100 text-slate-700' selectedInvoice.status === 'pending' ? 'bg-amber-100 text-amber-700' : 'bg-slate-100 text-slate-700'
}`}> }`}>
{selectedInvoice.status} {selectedInvoice.status}
</span> </span>
</div> </div>
<div className="mt-4 pt-4 border-t border-slate-200"> <div className="mt-4 pt-4 border-t border-slate-200">
<p className="text-xs text-slate-500 mb-2">Double Entry Accounting (Journal)</p> <p className="text-xs text-slate-500 mb-2">Double Entry Accounting (Journal)</p>
<div className="bg-slate-50 rounded-lg p-3 border border-slate-200"> <div className="bg-slate-50 rounded-lg p-3 border border-slate-200">
@@ -1486,21 +1479,21 @@ Credit (Cr): Investor Liability ৳${newInvestment.totalInvestment.toLocaleStri
</div> </div>
</div> </div>
</div> </div>
<div className="mt-6 pt-4 border-t border-slate-200 text-center"> <div className="mt-6 pt-4 border-t border-slate-200 text-center">
<p className="text-xs text-slate-400">Thank you for your investment!</p> <p className="text-xs text-slate-400">Thank you for your investment!</p>
<p className="text-xs text-slate-400">Generated on {new Date().toLocaleDateString()}</p> <p className="text-xs text-slate-400">Generated on {new Date().toLocaleDateString()}</p>
</div> </div>
</div> </div>
<div className="p-5 border-t border-slate-100 flex justify-between"> <div className="p-5 border-t border-slate-100 flex justify-between">
<button <button
onClick={() => window.print()} onClick={() => window.print()}
className="px-4 py-2 bg-investor text-white rounded-lg text-sm hover:bg-investor-dark flex items-center gap-2" className="px-4 py-2 bg-investor text-white rounded-lg text-sm hover:bg-investor-dark flex items-center gap-2"
> >
<Printer className="w-4 h-4" /> Print <Printer className="w-4 h-4" /> Print
</button> </button>
<button <button
onClick={() => { onClick={() => {
import('jspdf').then(jsPDF => { import('jspdf').then(jsPDF => {
const doc = new jsPDF.default(); const doc = new jsPDF.default();
@@ -1527,7 +1520,7 @@ Credit (Cr): Investor Liability ৳${newInvestment.totalInvestment.toLocaleStri
doc.text('Thank you for your investment!', 20, 115); doc.text('Thank you for your investment!', 20, 115);
doc.save(`invoice-${selectedInvoice.reference}.pdf`); doc.save(`invoice-${selectedInvoice.reference}.pdf`);
}); });
}} }}
className="px-4 py-2 border border-slate-200 text-slate-600 rounded-lg text-sm hover:bg-slate-50 flex items-center gap-2" className="px-4 py-2 border border-slate-200 text-slate-600 rounded-lg text-sm hover:bg-slate-50 flex items-center gap-2"
> >
<Download className="w-4 h-4" /> PDF <Download className="w-4 h-4" /> PDF

View File

@@ -946,7 +946,7 @@ export default function InvestorDetailPage() {
<div className="flex items-center justify-between mb-4"> <div className="flex items-center justify-between mb-4">
<div> <div>
<h3 className="font-semibold text-slate-800">Assigned Bikes</h3> <h3 className="font-semibold text-slate-800">Assigned Bikes</h3>
<p className="text-sm text-slate-500">{assignedBikes.length} bikes across {investor.investments?.length || 0} investment plans</p> <p className="text-sm text-slate-500">{assignedBikes.length} bikes across {investor.investments?.length || 0} EV Investment Plans</p>
</div> </div>
</div> </div>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4"> <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
@@ -1060,7 +1060,7 @@ export default function InvestorDetailPage() {
<div className="space-y-6"> <div className="space-y-6">
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<div> <div>
<h3 className="font-semibold text-slate-800">Investment Plans</h3> <h3 className="font-semibold text-slate-800">EV Investment Plans</h3>
<p className="text-sm text-slate-500">Manage investment portfolios for this investor</p> <p className="text-sm text-slate-500">Manage investment portfolios for this investor</p>
</div> </div>
<button onClick={() => setShowCreateInvestmentModal(true)} className="py-2 px-4 bg-investor text-white rounded-lg text-sm font-medium hover:bg-investor-dark flex items-center gap-2"> <button onClick={() => setShowCreateInvestmentModal(true)} className="py-2 px-4 bg-investor text-white rounded-lg text-sm font-medium hover:bg-investor-dark flex items-center gap-2">
@@ -1871,7 +1871,7 @@ export default function InvestorDetailPage() {
</div> </div>
<div> <div>
<h4 className="font-semibold text-slate-800 mb-3">Select Investment Plans & Bikes</h4> <h4 className="font-semibold text-slate-800 mb-3">Select EV Investment Plans & Bikes</h4>
<div className="space-y-4"> <div className="space-y-4">
<div className="flex items-center gap-3 p-4 bg-slate-50 rounded-lg border border-slate-200"> <div className="flex items-center gap-3 p-4 bg-slate-50 rounded-lg border border-slate-200">
<input <input
@@ -1896,7 +1896,7 @@ export default function InvestorDetailPage() {
<div className="border border-slate-200 rounded-lg overflow-hidden"> <div className="border border-slate-200 rounded-lg overflow-hidden">
<div className="bg-slate-50 px-4 py-2 border-b border-slate-200"> <div className="bg-slate-50 px-4 py-2 border-b border-slate-200">
<p className="text-sm font-medium text-slate-700">Investment Plans</p> <p className="text-sm font-medium text-slate-700">EV Investment Plans</p>
</div> </div>
<div className="divide-y divide-slate-100"> <div className="divide-y divide-slate-100">
{investor.investments?.map((inv: any) => { {investor.investments?.map((inv: any) => {

View File

@@ -68,14 +68,14 @@ export default function BatteryInvestmentSettings({
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<h3 className="text-lg font-semibold text-slate-800 flex items-center gap-2"> <h3 className="text-lg font-semibold text-slate-800 flex items-center gap-2">
<Battery className="w-5 h-5 text-emerald-600 animate-pulse" /> <Battery className="w-5 h-5 text-emerald-600 animate-pulse" />
Battery Investment Plans Battery EV Investment Plans
</h3> </h3>
</div> </div>
<div className="flex items-center justify-between bg-emerald-50 border border-emerald-200 rounded-xl p-4"> <div className="flex items-center justify-between bg-emerald-50 border border-emerald-200 rounded-xl p-4">
<div> <div>
<h4 className="font-semibold text-emerald-800">Battery Investment Plans ({(settings.plans as any).batteryInvestment?.length || 0})</h4> <h4 className="font-semibold text-emerald-800">Battery EV Investment Plans ({(settings.plans as any).batteryInvestment?.length || 0})</h4>
<p className="text-sm text-emerald-600">Manage high-yield battery pack investment plans for partners</p> <p className="text-sm text-emerald-600">Manage high-yield battery pack EV Investment Plans for partners</p>
</div> </div>
<button onClick={() => { setAddBatteryPlan(true); setNewBatteryName(''); }} className="px-4 py-2 bg-emerald-600 text-white rounded-lg text-sm font-medium flex items-center gap-2 hover:bg-emerald-700 transition-colors"> <button onClick={() => { setAddBatteryPlan(true); setNewBatteryName(''); }} className="px-4 py-2 bg-emerald-600 text-white rounded-lg text-sm font-medium flex items-center gap-2 hover:bg-emerald-700 transition-colors">
<Plus className="w-4 h-4" /> New Plan <Plus className="w-4 h-4" /> New Plan

View File

@@ -72,13 +72,13 @@ export default function InvestmentSettings({
return ( return (
<div className="p-6 space-y-6"> <div className="p-6 space-y-6">
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<h3 className="text-lg font-semibold text-slate-800">Investment Plans</h3> <h3 className="text-lg font-semibold text-slate-800">EV Investment Plans</h3>
</div> </div>
<div className="flex items-center justify-between bg-amber-50 border border-amber-200 rounded-xl p-4"> <div className="flex items-center justify-between bg-amber-50 border border-amber-200 rounded-xl p-4">
<div> <div>
<h4 className="font-semibold text-amber-800">Investment Plans ({settings.plans.investment.length})</h4> <h4 className="font-semibold text-amber-800">EV Investment Plans ({settings.plans.investment.length})</h4>
<p className="text-sm text-amber-600">Manage investment plans for investors</p> <p className="text-sm text-amber-600">Manage EV Investment Plans for investors</p>
</div> </div>
<button onClick={() => { setAddInvestPlan(true); setNewInvestName(''); }} className="px-4 py-2 bg-amber-600 text-white rounded-lg text-sm font-medium flex items-center gap-2"> <button onClick={() => { setAddInvestPlan(true); setNewInvestName(''); }} className="px-4 py-2 bg-amber-600 text-white rounded-lg text-sm font-medium flex items-center gap-2">
<Plus className="w-4 h-4" /> New Plan <Plus className="w-4 h-4" /> New Plan

View File

@@ -894,7 +894,7 @@ export default function CompanySettingsPage() {
const [newPolicyDesc, setNewPolicyDesc] = useState(''); const [newPolicyDesc, setNewPolicyDesc] = useState('');
const [newPolicyShowApp, setNewPolicyShowApp] = useState(true); const [newPolicyShowApp, setNewPolicyShowApp] = useState(true);
const [newPolicyShowWeb, setNewPolicyShowWeb] = useState(true); const [newPolicyShowWeb, setNewPolicyShowWeb] = useState(true);
// Bike Investment // Bike Investment
const [addInvestPlan, setAddInvestPlan] = useState(false); const [addInvestPlan, setAddInvestPlan] = useState(false);
const [newInvestName, setNewInvestName] = useState(''); const [newInvestName, setNewInvestName] = useState('');
@@ -1229,7 +1229,7 @@ export default function CompanySettingsPage() {
{ id: 'kyc', label: 'KYC Documents', icon: Package }, { id: 'kyc', label: 'KYC Documents', icon: Package },
{ id: 'plans', label: 'Plan Selection', icon: Package }, { id: 'plans', label: 'Plan Selection', icon: Package },
{ id: 'investment', label: 'Bike Investment Plan', icon: DollarSign }, { id: 'investment', label: 'EV Investment Plan', icon: DollarSign },
{ id: 'batteryinvestment', label: 'Battery Investment Plan', icon: Battery }, { id: 'batteryinvestment', label: 'Battery Investment Plan', icon: Battery },
{ id: 'swapstation', label: 'Swap Station Plan (P3)', icon: Zap }, { id: 'swapstation', label: 'Swap Station Plan (P3)', icon: Zap },
{ id: 'riderrequest', label: 'Rider Request Plan (P2)', icon: Users }, { id: 'riderrequest', label: 'Rider Request Plan (P2)', icon: Users },

View File

@@ -69,11 +69,11 @@ export default function MyInvestmentsPage() {
</div> </div>
</div> </div>
{/* Investment Plans Cards */} {/* EV Investment Plans Cards */}
<div className="space-y-6"> <div className="space-y-6">
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<div> <div>
<h3 className="font-semibold text-slate-800">Investment Plans</h3> <h3 className="font-semibold text-slate-800">EV Investment Plans</h3>
<p className="text-sm text-slate-500">Manage investment portfolios for this investor</p> <p className="text-sm text-slate-500">Manage investment portfolios for this investor</p>
</div> </div>
</div> </div>

View File

@@ -341,9 +341,9 @@ export default function InvestorWithdrawPage() {
</div> </div>
</div> </div>
{/* Select Investment Plans & Bikes */} {/* Select EV Investment Plans & Bikes */}
<div> <div>
<h4 className="font-semibold text-slate-800 mb-2">Select Investment Plans & Bikes</h4> <h4 className="font-semibold text-slate-800 mb-2">Select EV Investment Plans & Bikes</h4>
<div className="space-y-3"> <div className="space-y-3">
<div className="flex items-center gap-3 p-3 bg-slate-50 rounded-lg border border-slate-200"> <div className="flex items-center gap-3 p-3 bg-slate-50 rounded-lg border border-slate-200">
<input <input
@@ -361,7 +361,7 @@ export default function InvestorWithdrawPage() {
<div className="border border-slate-200 rounded-lg overflow-hidden"> <div className="border border-slate-200 rounded-lg overflow-hidden">
<div className="bg-slate-100 px-3 py-2 border-b border-slate-200"> <div className="bg-slate-100 px-3 py-2 border-b border-slate-200">
<p className="text-sm font-semibold text-slate-700">Investment Plans</p> <p className="text-sm font-semibold text-slate-700">EV Investment Plans</p>
</div> </div>
<div className="divide-y divide-slate-100"> <div className="divide-y divide-slate-100">
{investor.investments?.map((inv: any) => { {investor.investments?.map((inv: any) => {