2026-04-22 01:02:45 +06:00
'use client' ;
import { useState } from 'react' ;
import Link from 'next/link' ;
import { useParams } from 'next/navigation' ;
import { investors as initialInvestors , bikes as initialBikes , transactions as initialTransactions } from '@/data/mockData' ;
import type { Investor } from '@/data/mockData' ;
import {
ArrowLeft , Wallet , TrendingUp , Banknote , Calendar , Phone , Mail , MapPin , Edit , Trash2 , Plus , X , Bike ,
User , FileText , CreditCard , DollarSign , Clock , ChevronDown , ExternalLink , Download , Upload ,
AlertTriangle , Shield , Star , CheckCircle , XCircle , Search , Filter
} from 'lucide-react' ;
const statusColors : Record < string , string > = {
active : 'bg-green-100 text-green-700' ,
pending : 'bg-amber-100 text-amber-700' ,
inactive : 'bg-slate-100 text-slate-500' ,
suspended : 'bg-red-100 text-red-700' ,
} ;
const planColors : Record < string , string > = {
silver : 'bg-slate-200 text-slate-700' ,
gold : 'bg-yellow-100 text-yellow-700' ,
platinum : 'bg-purple-100 text-purple-700' ,
diamond : 'bg-blue-100 text-blue-700' ,
} ;
const kycColors : Record < string , string > = {
verified : 'bg-green-100 text-green-700' ,
pending : 'bg-amber-100 text-amber-700' ,
rejected : 'bg-red-100 text-red-700' ,
not_submitted : 'bg-slate-100 text-slate-500' ,
} ;
const bikeStatusColors : Record < string , string > = {
available : 'bg-blue-100 text-blue-700' ,
rented : 'bg-green-100 text-green-700' ,
maintenance : 'bg-amber-100 text-amber-700' ,
retired : 'bg-slate-100 text-slate-500' ,
} ;
export default function InvestorDetailPage() {
const params = useParams ( ) ;
const investorId = params . id as string ;
const [ investors ] = useState < Investor [ ] > ( initialInvestors ) ;
const investor = investors . find ( i = > i . id === investorId ) ;
const assignedBikes = initialBikes . filter ( b = > b . investorId === investorId ) ;
2026-04-22 01:18:03 +06:00
// Investor transactions are filtered below
2026-04-22 01:02:45 +06:00
const [ activeTab , setActiveTab ] = useState ( 'overview' ) ;
const [ showEditModal , setShowEditModal ] = useState ( false ) ;
const [ showAssignBikeModal , setShowAssignBikeModal ] = useState ( false ) ;
const [ selectedBikeId , setSelectedBikeId ] = useState ( '' ) ;
2026-04-22 01:09:51 +06:00
const [ showCreateInvestmentModal , setShowCreateInvestmentModal ] = useState ( false ) ;
2026-04-22 01:18:03 +06:00
const [ showBankModal , setShowBankModal ] = useState ( false ) ;
const [ showMobileBankingModal , setShowMobileBankingModal ] = useState ( false ) ;
const [ showTaxModal , setShowTaxModal ] = useState ( false ) ;
const [ showDocModal , setShowDocModal ] = useState ( false ) ;
const [ editingBank , setEditingBank ] = useState ( { bankName : '' , bankAccountName : '' , bankAccountNumber : '' , bankBranch : '' , bankRouting : '' } ) ;
const [ editingMobileBanking , setEditingMobileBanking ] = useState ( { provider : '' , number : '' , isPrimary : false } ) ;
const [ editingTax , setEditingTax ] = useState ( { tinNumber : '' , passportNumber : '' } ) ;
const [ newDoc , setNewDoc ] = useState ( { type : 'nid' , number : '' , url : '' } ) ;
const [ editingMobileIndex , setEditingMobileIndex ] = useState < number | null > ( null ) ;
const investorTransactions = initialTransactions . filter ( t = > t . investorId === investorId ) ;
2026-04-22 01:09:51 +06:00
const [ newInvestment , setNewInvestment ] = useState ( {
planName : '' ,
planType : 'gold' as 'silver' | 'gold' | 'platinum' | 'diamond' ,
selectedBikeIds : [ ] as string [ ] ,
totalInvestment : 0 ,
monthlyReturn : 0 ,
expectedRoi : 15 ,
startDate : new Date ( ) . toISOString ( ) . split ( 'T' ) [ 0 ] ,
endDate : '' ,
paymentMethod : 'bank' as 'bank' | 'mobile' | 'cash' | 'cheque' ,
transactionReference : '' ,
notes : ''
} ) ;
2026-04-22 01:02:45 +06:00
if ( ! investor ) {
return (
< div className = "p-4 lg:p-6" >
< div className = "text-center py-12" >
< h2 className = "text-xl font-bold text-slate-800" > Investor Not Found < / h2 >
< p className = "text-slate-500 mt-2" > The investor you 're looking for doesn' t exist . < / p >
< Link href = "/admin/investors" className = "mt-4 inline-flex items-center gap-2 text-investor hover:underline" >
< ArrowLeft className = "w-4 h-4" / > Back to Investors
< / Link >
< / div >
< / div >
) ;
}
const availableBikesForAssignment = initialBikes . filter ( b = > ! b . investorId && b . status === 'available' ) ;
const handleAssignBike = ( ) = > {
alert ( 'Bike assignment functionality - would update bike investorId here' ) ;
setShowAssignBikeModal ( false ) ;
setSelectedBikeId ( '' ) ;
} ;
2026-04-22 01:09:51 +06:00
const handleCreateInvestment = ( ) = > {
const invId = ` ip ${ Date . now ( ) } ` ;
const transactionId = ` INV/ ${ new Date ( ) . getFullYear ( ) } / ${ String ( Math . floor ( Math . random ( ) * 1000 ) ) . padStart ( 3 , '0' ) } ` ;
console . log ( 'Creating Investment:' , {
id : invId ,
investorId : investor.id ,
. . . newInvestment ,
actualEarnings : 0 ,
status : 'active' as const ,
transactionId : transactionId ,
createdAt : new Date ( ) . toISOString ( )
} ) ;
console . log ( 'Accounting Entry:' , {
entryId : ` AC- ${ Date . now ( ) } ` ,
type : 'investment_created' ,
investorId : investor.id ,
investmentId : invId ,
amount : newInvestment.totalInvestment ,
debitAccount : 'Investment Asset - Investor' ,
creditAccount : newInvestment.paymentMethod === 'bank' ? 'Bank Account' : 'Cash Account' ,
transactionRef : transactionId ,
createdAt : new Date ( ) . toISOString ( )
} ) ;
alert ( ` Investment created successfully! \ n \ nInvestment ID: ${ invId } \ nTransaction Ref: ${ transactionId } \ nAmount: ৳ ${ newInvestment . totalInvestment . toLocaleString ( ) } \ n \ nAccounting entries have been logged. ` ) ;
setShowCreateInvestmentModal ( false ) ;
setNewInvestment ( {
planName : '' ,
planType : 'gold' ,
selectedBikeIds : [ ] ,
totalInvestment : 0 ,
monthlyReturn : 0 ,
expectedRoi : 15 ,
startDate : new Date ( ) . toISOString ( ) . split ( 'T' ) [ 0 ] ,
endDate : '' ,
paymentMethod : 'bank' ,
transactionReference : '' ,
notes : ''
} ) ;
} ;
2026-04-22 01:02:45 +06:00
return (
< div className = "p-4 lg:p-6" >
< div className = "flex items-center justify-between mb-6" >
< div className = "flex items-center gap-4" >
< Link href = "/admin/investors" className = "p-2 hover:bg-slate-100 rounded-lg" >
< ArrowLeft className = "w-5 h-5 text-slate-600" / >
< / Link >
< div >
< h1 className = "text-2xl lg:text-3xl font-extrabold text-slate-800" > { investor . name } < / h1 >
< p className = "text-sm text-slate-500" > { investor . id } • { investor . email } < / p >
< / div >
< / div >
< div className = "flex items-center gap-2" >
< button onClick = { ( ) = > setShowEditModal ( true ) } className = "py-2.5 px-4 border border-slate-200 text-slate-600 rounded-lg font-semibold text-sm hover:bg-slate-50 flex items-center gap-2" >
< Edit className = "w-4 h-4" / > Edit
< / button >
< button className = "py-2.5 px-4 bg-red-500 text-white rounded-lg font-semibold text-sm hover:bg-red-600 flex items-center gap-2" >
< Trash2 className = "w-4 h-4" / > Delete
< / button >
< / div >
< / div >
< div className = "flex flex-wrap gap-2 mb-6" >
< span className = { ` inline-flex items-center gap-1 text-sm font-medium px-3 py-1.5 rounded-full ${ statusColors [ investor . status ] } ` } >
{ investor . status }
< / span >
{ investor . investments && investor . investments . length > 0 && (
< span className = { ` inline-flex items-center gap-1 text-sm font-medium px-3 py-1.5 rounded-full ${ planColors [ investor . investments [ 0 ] . planType ] } ` } >
{ investor . investments . length } Investment { investor . investments . length > 1 ? 's' : '' }
< / span >
) }
< span className = { ` inline-flex items-center gap-1 text-sm font-medium px-3 py-1.5 rounded-full ${ kycColors [ investor . kycStatus ] } ` } >
< Shield className = "w-4 h-4" / > KYC { investor . kycStatus }
< / span >
< span className = { ` inline-flex items-center gap-1 text-sm font-medium px-3 py-1.5 rounded-full ${ investor . riskLevel === 'low' ? 'bg-green-100 text-green-700' : investor . riskLevel === 'medium' ? 'bg-amber-100 text-amber-700' : 'bg-red-100 text-red-700' } ` } >
Risk : { investor . riskLevel }
< / span >
< / div >
< div className = "grid grid-cols-2 lg:grid-cols-4 gap-4 mb-6" >
< div className = "bg-white rounded-xl p-5 shadow-sm border border-slate-100" >
< div className = "flex items-center gap-3" >
< div className = "w-12 h-12 rounded-xl bg-purple-50 flex items-center justify-center" >
< Wallet className = "w-6 h-6 text-purple-600" / >
< / div >
< div >
< p className = "text-2xl font-extrabold text-slate-800" > ৳ { investor . totalInvested . toLocaleString ( ) } < / p >
< p className = "text-sm text-slate-500" > Total Invested < / p >
< / div >
< / div >
< / div >
< div className = "bg-white rounded-xl p-5 shadow-sm border border-slate-100" >
< div className = "flex items-center gap-3" >
< div className = "w-12 h-12 rounded-xl bg-green-50 flex items-center justify-center" >
< TrendingUp className = "w-6 h-6 text-green-600" / >
< / div >
< div >
< p className = "text-2xl font-extrabold text-slate-800" > ৳ { investor . totalEarnings . toLocaleString ( ) } < / p >
< p className = "text-sm text-slate-500" > Total Earnings < / p >
< / div >
< / div >
< / div >
< div className = "bg-white rounded-xl p-5 shadow-sm border border-slate-100" >
< div className = "flex items-center gap-3" >
< div className = "w-12 h-12 rounded-xl bg-blue-50 flex items-center justify-center" >
< Bike className = "w-6 h-6 text-blue-600" / >
< / div >
< div >
< p className = "text-2xl font-extrabold text-slate-800" > { investor . activeBikes } < / p >
< p className = "text-sm text-slate-500" > Active Bikes < / p >
< / div >
< / div >
< / div >
< div className = "bg-white rounded-xl p-5 shadow-sm border border-slate-100" >
< div className = "flex items-center gap-3" >
< div className = "w-12 h-12 rounded-xl bg-amber-50 flex items-center justify-center" >
< Calendar className = "w-6 h-6 text-amber-600" / >
< / div >
< div >
< p className = "text-2xl font-extrabold text-slate-800" > { investor . roi } % < / p >
< p className = "text-sm text-slate-500" > ROI < / p >
< / div >
< / div >
< / div >
< / div >
< div className = "bg-white rounded-xl shadow-sm border border-slate-100 mb-6" >
< div className = "border-b border-slate-100 flex overflow-x-auto" >
< button
onClick = { ( ) = > setActiveTab ( 'overview' ) }
className = { ` px-4 py-3 text-sm font-medium whitespace-nowrap ${ activeTab === 'overview' ? 'border-b-2 border-investor text-investor' : 'text-slate-500' } ` }
>
< User className = "w-4 h-4 inline mr-1" / > Overview
< / button >
< button
onClick = { ( ) = > setActiveTab ( 'investments' ) }
className = { ` px-4 py-3 text-sm font-medium whitespace-nowrap ${ activeTab === 'investments' ? 'border-b-2 border-investor text-investor' : 'text-slate-500' } ` }
>
< TrendingUp className = "w-4 h-4 inline mr-1" / > Investments ( { investor . investments ? . length || 0 } )
< / button >
< button
onClick = { ( ) = > setActiveTab ( 'bikes' ) }
className = { ` px-4 py-3 text-sm font-medium whitespace-nowrap ${ activeTab === 'bikes' ? 'border-b-2 border-investor text-investor' : 'text-slate-500' } ` }
>
< Bike className = "w-4 h-4 inline mr-1" / > Bikes ( { assignedBikes . length } )
< / button >
< button
onClick = { ( ) = > setActiveTab ( 'financial' ) }
className = { ` px-4 py-3 text-sm font-medium whitespace-nowrap ${ activeTab === 'financial' ? 'border-b-2 border-investor text-investor' : 'text-slate-500' } ` }
>
< Banknote className = "w-4 h-4 inline mr-1" / > Financial
< / button >
< button
onClick = { ( ) = > setActiveTab ( 'transactions' ) }
className = { ` px-4 py-3 text-sm font-medium whitespace-nowrap ${ activeTab === 'transactions' ? 'border-b-2 border-investor text-investor' : 'text-slate-500' } ` }
>
< DollarSign className = "w-4 h-4 inline mr-1" / > Transactions
< / button >
< button
onClick = { ( ) = > setActiveTab ( 'documents' ) }
className = { ` px-4 py-3 text-sm font-medium whitespace-nowrap ${ activeTab === 'documents' ? 'border-b-2 border-investor text-investor' : 'text-slate-500' } ` }
>
< FileText className = "w-4 h-4 inline mr-1" / > Documents
< / button >
< / div >
< div className = "p-5" >
{ activeTab === 'overview' && (
< div className = "space-y-6" >
< div className = "grid lg:grid-cols-2 gap-6" >
< div >
< h3 className = "font-semibold text-slate-800 mb-4" > Personal Information < / h3 >
< div className = "space-y-3" >
< div className = "flex items-center gap-3 p-3 bg-slate-50 rounded-lg" >
< User className = "w-5 h-5 text-slate-400" / >
< div >
< p className = "text-xs text-slate-500" > Full Name < / p >
< p className = "font-medium text-slate-700" > { investor . name } < / p >
< / div >
< / div >
< div className = "flex items-center gap-3 p-3 bg-slate-50 rounded-lg" >
< Phone className = "w-5 h-5 text-slate-400" / >
< div >
< p className = "text-xs text-slate-500" > Phone < / p >
< p className = "font-medium text-slate-700" > { investor . phone } < / p >
< / div >
< / div >
< div className = "flex items-center gap-3 p-3 bg-slate-50 rounded-lg" >
< Mail className = "w-5 h-5 text-slate-400" / >
< div >
< p className = "text-xs text-slate-500" > Email < / p >
< p className = "font-medium text-slate-700" > { investor . email } < / p >
< / div >
< / div >
< div className = "flex items-center gap-3 p-3 bg-slate-50 rounded-lg" >
< MapPin className = "w-5 h-5 text-slate-400" / >
< div >
< p className = "text-xs text-slate-500" > Address < / p >
< p className = "font-medium text-slate-700" > { investor . address } < / p >
< / div >
< / div >
{ investor . dateOfBirth && (
< div className = "flex items-center gap-3 p-3 bg-slate-50 rounded-lg" >
< Calendar className = "w-5 h-5 text-slate-400" / >
< div >
< p className = "text-xs text-slate-500" > Date of Birth < / p >
< p className = "font-medium text-slate-700" > { investor . dateOfBirth } < / p >
< / div >
< / div >
) }
{ investor . nidNumber && (
< div className = "flex items-center gap-3 p-3 bg-slate-50 rounded-lg" >
< Shield className = "w-5 h-5 text-slate-400" / >
< div >
< p className = "text-xs text-slate-500" > NID Number < / p >
< p className = "font-medium text-slate-700" > { investor . nidNumber } < / p >
< / div >
< / div >
) }
< / div >
< / div >
< div >
< h3 className = "font-semibold text-slate-800 mb-4" > Emergency Contact < / h3 >
< div className = "space-y-3" >
{ investor . emergencyContactName && (
< div className = "flex items-center gap-3 p-3 bg-slate-50 rounded-lg" >
< Phone className = "w-5 h-5 text-slate-400" / >
< div >
< p className = "text-xs text-slate-500" > Contact < / p >
< p className = "font-medium text-slate-700" > { investor . emergencyContactName } < / p >
< p className = "text-xs text-slate-400" > { investor . emergencyContactRelation } • { investor . emergencyContactPhone } < / p >
< / div >
< / div >
) }
< / div >
< h3 className = "font-semibold text-slate-800 mb-4 mt-6" > Investment Details < / h3 >
< div className = "space-y-3" >
< div className = "flex items-center gap-3 p-3 bg-slate-50 rounded-lg" >
< Calendar className = "w-5 h-5 text-slate-400" / >
< div >
< p className = "text-xs text-slate-500" > Total Investments < / p >
< p className = "font-medium text-slate-700" >
{ investor . investments ? . length || 0 } active investments
< / p >
< / div >
< / div >
< div className = "flex items-center gap-3 p-3 bg-slate-50 rounded-lg" >
< FileText className = "w-5 h-5 text-slate-400" / >
< div >
< p className = "text-xs text-slate-500" > Overall Status < / p >
< p className = "font-medium text-slate-700 capitalize" > { investor . status } < / p >
< / div >
< / div >
{ investor . referralCode && (
< div className = "flex items-center gap-3 p-3 bg-slate-50 rounded-lg" >
< Star className = "w-5 h-5 text-slate-400" / >
< div >
< p className = "text-xs text-slate-500" > Referral Code < / p >
< p className = "font-medium text-slate-700" > { investor . referralCode } < / p >
< p className = "text-xs text-slate-400" > Referrals : { investor . totalReferrals } • Earnings : ৳ { investor . referralEarnings } < / p >
< / div >
< / div >
) }
< / div >
< / div >
< / div >
{ investor . notes && (
< div className = "mt-6" >
< h3 className = "font-semibold text-slate-800 mb-2" > Notes < / h3 >
< p className = "text-sm text-slate-600 bg-slate-50 p-3 rounded-lg" > { investor . notes } < / p >
< / div >
) }
< / div >
) }
{ activeTab === 'bikes' && (
< div >
< div className = "flex items-center justify-between mb-4" >
< h3 className = "font-semibold text-slate-800" > Assigned Bikes < / h3 >
< button
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"
>
< Plus className = "w-4 h-4" / > Assign Bike
< / button >
< / div >
< div className = "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4" >
{ assignedBikes . map ( bike = > (
< div key = { bike . id } className = "bg-slate-50 rounded-xl p-4" >
< div className = "flex items-start justify-between mb-3" >
< div className = "flex items-center gap-3" >
< div className = "w-12 h-12 rounded-xl bg-white flex items-center justify-center shadow-sm" >
< Bike className = "w-6 h-6 text-blue-600" / >
< / div >
< div >
< p className = "font-semibold text-slate-700" > { bike . model } < / p >
< p className = "text-xs text-slate-400" > { bike . brand } < / p >
< / div >
< / div >
< span className = { ` text-xs font-medium px-2.5 py-1 rounded-full ${ bikeStatusColors [ bike . status ] } ` } >
{ bike . status }
< / span >
< / div >
< div className = "space-y-2 text-xs" >
< div className = "flex justify-between" >
< span className = "text-slate-500" > Plate < / span >
< span className = "font-medium" > { bike . plateNumber } < / span >
< / div >
< div className = "flex justify-between" >
< span className = "text-slate-500" > Location < / span >
< span className = "font-medium" > { bike . location } < / span >
< / div >
< div className = "flex justify-between" >
< span className = "text-slate-500" > Battery < / span >
< span className = { ` font-medium ${ bike . batteryLevel > 50 ? 'text-green-600' : bike . batteryLevel > 20 ? 'text-amber-600' : 'text-red-600' } ` } > { bike . batteryLevel } % < / span >
< / div >
< div className = "flex justify-between" >
< span className = "text-slate-500" > Purchase Price < / span >
< span className = "font-medium text-purple-600" > ৳ { bike . purchasePrice ? . toLocaleString ( ) || 0 } < / span >
< / div >
< div className = "flex justify-between" >
< span className = "text-slate-500" > Total Earnings < / span >
< span className = "font-medium text-green-600" > ৳ { bike . totalEarnings ? . toLocaleString ( ) || 0 } < / span >
< / div >
< / div >
< / div >
) ) }
{ assignedBikes . length === 0 && (
< div className = "col-span-full text-center py-8 text-slate-400" >
< Bike className = "w-12 h-12 mx-auto mb-2 opacity-50" / >
< p > No bikes assigned yet < / p >
< / div >
) }
< / div >
< / div >
) }
{ activeTab === 'investments' && (
< div className = "space-y-6" >
< div className = "flex items-center justify-between" >
< h3 className = "font-semibold text-slate-800" > Investment Plans < / h3 >
2026-04-22 01:09:51 +06:00
< 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" >
2026-04-22 01:02:45 +06:00
< Plus className = "w-4 h-4" / > Add Investment
< / button >
< / div >
< div className = "grid grid-cols-1 md:grid-cols-2 gap-4" >
{ investor . investments ? . map ( ( inv ) = > (
< div key = { inv . id } className = "bg-slate-50 rounded-xl p-4" >
< div className = "flex items-start justify-between mb-3" >
< div >
< p className = "font-semibold text-slate-700" > { inv . planName } < / p >
< p className = "text-xs text-slate-400" > { inv . planType } Plan < / p >
< / div >
< span className = { ` text-xs font-medium px-2.5 py-1 rounded-full ${ planColors [ inv . planType ] } ` } >
{ inv . status }
< / span >
< / div >
< div className = "grid grid-cols-2 gap-2 text-xs mb-3" >
< div className = "bg-white rounded-lg p-2" >
< p className = "text-slate-400" > Investment < / p >
< p className = "font-medium text-purple-600" > ৳ { inv . totalInvestment . toLocaleString ( ) } < / p >
< / div >
< div className = "bg-white rounded-lg p-2" >
< p className = "text-slate-400" > Monthly Return < / p >
< p className = "font-medium text-green-600" > ৳ { inv . monthlyReturn . toLocaleString ( ) } < / p >
< / div >
< div className = "bg-white rounded-lg p-2" >
< p className = "text-slate-400" > Expected ROI < / p >
< p className = "font-medium text-slate-700" > { inv . expectedRoi } % < / p >
< / div >
< div className = "bg-white rounded-lg p-2" >
< p className = "text-slate-400" > Actual Earned < / p >
< p className = "font-medium text-green-600" > ৳ { inv . actualEarnings . toLocaleString ( ) } < / p >
< / div >
< / div >
< div className = "flex items-center justify-between text-xs" >
< span className = "text-slate-400" > { inv . startDate } to { inv . endDate || 'Ongoing' } < / span >
< span className = "capitalize" > { inv . paymentMethod } < / span >
< / div >
< / div >
) ) }
{ ( ! investor . investments || investor . investments . length === 0 ) && (
< div className = "col-span-full text-center py-8 text-slate-400" >
< TrendingUp className = "w-12 h-12 mx-auto mb-2 opacity-50" / >
< p > No investments yet < / p >
< button className = "mt-2 px-4 py-2 bg-investor text-white rounded-lg text-sm hover:bg-investor-dark" >
Create First Investment
< / button >
< / div >
) }
< / div >
< / div >
) }
{ activeTab === 'financial' && (
< div className = "space-y-6" >
< div className = "grid lg:grid-cols-2 gap-6" >
< div >
2026-04-22 01:18:03 +06:00
< div className = "flex items-center justify-between mb-4" >
< h3 className = "font-semibold text-slate-800" > Bank Details < / h3 >
< button onClick = { ( ) = > {
setEditingBank ( {
bankName : investor.bankName || '' ,
bankAccountName : investor.bankAccountName || '' ,
bankAccountNumber : investor.bankAccountNumber || '' ,
bankBranch : investor.bankBranch || '' ,
bankRouting : investor.bankRouting || ''
} ) ;
setShowBankModal ( true ) ;
} } className = "text-sm text-investor hover:underline flex items-center gap-1" >
< Edit className = "w-4 h-4" / > { investor . bankName ? 'Edit' : 'Add' }
< / button >
< / div >
2026-04-22 01:02:45 +06:00
< div className = "space-y-3" >
2026-04-22 01:18:03 +06:00
{ investor . bankName ? (
< >
< div className = "flex items-center gap-3 p-3 bg-slate-50 rounded-lg" >
< Banknote className = "w-5 h-5 text-slate-400" / >
< div className = "flex-1" >
< p className = "text-xs text-slate-500" > Bank < / p >
< p className = "font-medium text-slate-700" > { investor . bankName } < / p >
< p className = "text-xs text-slate-400" > { investor . bankBranch } < / p >
< / div >
2026-04-22 01:02:45 +06:00
< / div >
2026-04-22 01:18:03 +06:00
< div className = "flex items-center gap-3 p-3 bg-slate-50 rounded-lg" >
< CreditCard className = "w-5 h-5 text-slate-400" / >
< div className = "flex-1" >
< p className = "text-xs text-slate-500" > Account < / p >
< p className = "font-medium text-slate-700" > { investor . bankAccountName } < / p >
< p className = "text-xs text-slate-400" > { investor . bankAccountNumber } < / p >
{ investor . bankRouting && < p className = "text-xs text-slate-400" > Routing : { investor . bankRouting } < / p > }
< / div >
2026-04-22 01:02:45 +06:00
< / div >
2026-04-22 01:18:03 +06:00
< / >
) : (
< div className = "text-center py-8 text-slate-400 border-2 border-dashed border-slate-200 rounded-lg" >
< Banknote className = "w-8 h-8 mx-auto mb-2 opacity-50" / >
< p className = "text-sm" > No bank details added < / p >
2026-04-22 01:02:45 +06:00
< / div >
) }
< / div >
< / div >
< div >
2026-04-22 01:18:03 +06:00
< div className = "flex items-center justify-between mb-4" >
< h3 className = "font-semibold text-slate-800" > Mobile Banking < / h3 >
< button onClick = { ( ) = > {
setEditingMobileBanking ( { provider : '' , number : '' , isPrimary : ! investor . mobileBanking } ) ;
setEditingMobileIndex ( null ) ;
setShowMobileBankingModal ( true ) ;
} } className = "text-sm text-investor hover:underline flex items-center gap-1" >
< Plus className = "w-4 h-4" / > Add
< / button >
< / div >
2026-04-22 01:02:45 +06:00
< div className = "space-y-3" >
2026-04-22 01:18:03 +06:00
{ investor . mobileBanking ? (
< div className = "flex items-center gap-3 p-3 bg-purple-50 rounded-lg" >
< Phone className = "w-5 h-5 text-purple-500" / >
< div className = "flex-1" >
< p className = "text-xs text-purple-600" > Primary < / p >
< p className = "font-medium text-slate-700" > { investor . mobileBanking } < / p >
< p className = "text-xs text-slate-400" > { investor . mobileBankingNumber } < / p >
2026-04-22 01:02:45 +06:00
< / div >
2026-04-22 01:18:03 +06:00
< button onClick = { ( ) = > {
setEditingMobileBanking ( { provider : investor.mobileBanking || '' , number : investor . mobileBankingNumber || '' , isPrimary : true } ) ;
setEditingMobileIndex ( - 1 ) ;
setShowMobileBankingModal ( true ) ;
} } className = "p-1 hover:bg-purple-100 rounded" >
< Edit className = "w-4 h-4 text-purple-500" / >
< / button >
2026-04-22 01:02:45 +06:00
< / div >
2026-04-22 01:18:03 +06:00
) : null }
2026-04-22 01:02:45 +06:00
{ investor . additionalMobileBanking ? . map ( ( mb , idx ) = > (
< div key = { idx } className = "flex items-center gap-3 p-3 bg-slate-50 rounded-lg" >
< Phone className = "w-5 h-5 text-slate-400" / >
< div className = "flex-1" >
< p className = "text-xs text-slate-500" > { mb . provider } < / p >
< p className = "font-medium text-slate-700" > { mb . number } < / p >
< / div >
2026-04-22 01:18:03 +06:00
{ mb . verified ? (
2026-04-22 01:02:45 +06:00
< span className = "text-xs bg-green-100 text-green-700 px-2 py-1 rounded-full" > Verified < / span >
2026-04-22 01:18:03 +06:00
) : (
< span className = "text-xs bg-amber-100 text-amber-700 px-2 py-1 rounded-full" > Pending < / span >
2026-04-22 01:02:45 +06:00
) }
2026-04-22 01:18:03 +06:00
< button onClick = { ( ) = > {
setEditingMobileBanking ( { provider : mb.provider , number : mb . number , isPrimary : false } ) ;
setEditingMobileIndex ( idx ) ;
setShowMobileBankingModal ( true ) ;
} } className = "p-1 hover:bg-slate-200 rounded" >
< Edit className = "w-4 h-4 text-slate-400" / >
< / button >
< button onClick = { ( ) = > alert ( ` Delete mobile banking ${ mb . provider } ` ) } className = "p-1 hover:bg-red-50 rounded" >
< Trash2 className = "w-4 h-4 text-red-400" / >
< / button >
2026-04-22 01:02:45 +06:00
< / div >
) ) }
2026-04-22 01:18:03 +06:00
{ ( ! investor . mobileBanking && ( ! investor . additionalMobileBanking || investor . additionalMobileBanking . length === 0 ) ) && (
< div className = "text-center py-8 text-slate-400 border-2 border-dashed border-slate-200 rounded-lg" >
< Phone className = "w-8 h-8 mx-auto mb-2 opacity-50" / >
< p className = "text-sm" > No mobile banking added < / p >
< / div >
) }
2026-04-22 01:02:45 +06:00
< / div >
2026-04-22 01:18:03 +06:00
< div className = "flex items-center justify-between mb-4 mt-6" >
< h3 className = "font-semibold text-slate-800" > Tax Information < / h3 >
< button onClick = { ( ) = > {
setEditingTax ( {
tinNumber : investor.tinNumber || '' ,
passportNumber : investor.passportNumber || ''
} ) ;
setShowTaxModal ( true ) ;
} } className = "text-sm text-investor hover:underline flex items-center gap-1" >
< Edit className = "w-4 h-4" / > { investor . tinNumber || investor . passportNumber ? 'Edit' : 'Add' }
< / button >
< / div >
2026-04-22 01:02:45 +06:00
< div className = "space-y-3" >
2026-04-22 01:18:03 +06:00
{ investor . tinNumber || investor . passportNumber ? (
< >
{ investor . tinNumber && (
< div className = "flex items-center gap-3 p-3 bg-slate-50 rounded-lg" >
< FileText className = "w-5 h-5 text-slate-400" / >
< div >
< p className = "text-xs text-slate-500" > TIN < / p >
< p className = "font-medium text-slate-700" > { investor . tinNumber } < / p >
< / div >
< / div >
) }
{ investor . passportNumber && (
< div className = "flex items-center gap-3 p-3 bg-slate-50 rounded-lg" >
< FileText className = "w-5 h-5 text-slate-400" / >
< div >
< p className = "text-xs text-slate-500" > Passport < / p >
< p className = "font-medium text-slate-700" > { investor . passportNumber } < / p >
< / div >
< / div >
) }
< / >
) : (
< div className = "text-center py-8 text-slate-400 border-2 border-dashed border-slate-200 rounded-lg" >
< FileText className = "w-8 h-8 mx-auto mb-2 opacity-50" / >
< p className = "text-sm" > No tax info added < / p >
2026-04-22 01:02:45 +06:00
< / div >
) }
< / div >
< / div >
< / div >
< div >
< h3 className = "font-semibold text-slate-800 mb-4" > Investment Summary < / h3 >
< div className = "grid grid-cols-2 lg:grid-cols-4 gap-4" >
< div className = "bg-purple-50 rounded-lg p-4" >
< p className = "text-sm text-purple-600" > Total Invested < / p >
< p className = "text-xl font-bold text-purple-700" > ৳ { investor . totalInvested . toLocaleString ( ) } < / p >
< / div >
< div className = "bg-green-50 rounded-lg p-4" >
< p className = "text-sm text-green-600" > Total Earnings < / p >
< p className = "text-xl font-bold text-green-700" > ৳ { investor . totalEarnings . toLocaleString ( ) } < / p >
< / div >
< div className = "bg-amber-50 rounded-lg p-4" >
< p className = "text-sm text-amber-600" > Pending Earnings < / p >
< p className = "text-xl font-bold text-amber-700" > ৳ { investor . pendingEarnings . toLocaleString ( ) } < / p >
< / div >
< div className = "bg-slate-50 rounded-lg p-4" >
< p className = "text-sm text-slate-600" > Total Withdrawn < / p >
< p className = "text-xl font-bold text-slate-700" > ৳ { investor . totalWithdrawn . toLocaleString ( ) } < / p >
< / div >
< / div >
< / div >
< / div >
) }
{ activeTab === 'transactions' && (
< div >
< div className = "flex items-center justify-between mb-4" >
2026-04-22 01:18:03 +06:00
< h3 className = "font-semibold text-slate-800" > All Transactions < / h3 >
< div className = "flex gap-2" >
< button onClick = { ( ) = > alert ( 'Withdrawal request modal would open here' ) } className = "py-2 px-3 bg-red-500 text-white rounded-lg text-sm font-medium hover:bg-red-600 flex items-center gap-1" >
< Banknote className = "w-4 h-4" / > Request Withdrawal
< / button >
< button className = "py-2 px-3 border border-slate-200 text-slate-600 rounded-lg text-sm font-medium hover:bg-slate-50 flex items-center gap-1" >
< Download className = "w-4 h-4" / > Export
< / button >
< / div >
2026-04-22 01:02:45 +06:00
< / div >
2026-04-22 01:18:03 +06:00
< div className = "mb-6" >
< h4 className = "font-semibold text-slate-700 mb-3" > Pending Withdrawals < / h4 >
< div className = "space-y-2" >
{ investorTransactions . filter ( t = > t . type === 'withdrawal' && t . status === 'pending' ) . map ( tx = > (
< div key = { tx . id } className = "flex items-center justify-between p-4 bg-amber-50 border border-amber-200 rounded-lg" >
< div className = "flex items-center gap-3" >
< div className = "w-12 h-12 rounded-full bg-red-100 flex items-center justify-center" >
< Banknote className = "w-6 h-6 text-red-600" / >
< / div >
< div >
< p className = "text-sm font-medium text-slate-700" > { tx . description } < / p >
< p className = "text-xs text-amber-600" > Ref : { tx . referenceNumber || tx . id } • { tx . createdAt } < / p >
< / div >
2026-04-22 01:02:45 +06:00
< / div >
2026-04-22 01:18:03 +06:00
< div className = "text-right" >
< p className = "text-lg font-bold text-red-600" > - ৳ { tx . amount . toLocaleString ( ) } < / p >
< span className = "text-xs font-medium px-2 py-1 rounded-full bg-amber-100 text-amber-700" >
Pending
< / span >
2026-04-22 01:02:45 +06:00
< / div >
< / div >
2026-04-22 01:18:03 +06:00
) ) }
{ investorTransactions . filter ( t = > t . type === 'withdrawal' && t . status === 'pending' ) . length === 0 && (
< div className = "text-center py-4 text-slate-400 border border-dashed border-slate-200 rounded-lg" >
< p className = "text-sm" > No pending withdrawals < / p >
2026-04-22 01:02:45 +06:00
< / div >
2026-04-22 01:18:03 +06:00
) }
< / div >
< / div >
< div >
< h4 className = "font-semibold text-slate-700 mb-3" > Transaction History < / h4 >
< div className = "space-y-2" >
{ investorTransactions . map ( tx = > (
< 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 = { ` 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 === 'withdrawal' ? 'bg-red-100' :
tx . type === 'investment' ? 'bg-purple-100' :
tx . type === 'referral_bonus' ? 'bg-yellow-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' :
tx . type === 'withdrawal' ? 'text-red-600' :
tx . type === 'investment' ? 'text-purple-600' :
tx . type === 'referral_bonus' ? 'text-yellow-600' :
tx . type === 'adjustment' || tx . type === 'penalty' ? 'text-orange-600' : 'text-blue-600'
} ` } />
< / div >
< div >
< p className = "text-sm font-medium text-slate-700" > { tx . description } < / p >
< p className = "text-xs text-slate-400" > { tx . createdAt } { tx . referenceNumber && ` • Ref: ${ tx . referenceNumber } ` } < / p >
< / div >
< / div >
< div className = "text-right" >
< 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 === '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 ( ) }
< / p >
< span className = { ` text-xs font-medium px-2 py-0.5 rounded-full ${
tx . status === 'completed' ? 'bg-green-100 text-green-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 }
< / span >
< / div >
< / div >
) ) }
{ investorTransactions . length === 0 && (
< div className = "text-center py-8 text-slate-400" >
< DollarSign className = "w-12 h-12 mx-auto mb-2 opacity-50" / >
< p > No transactions yet < / p >
< / div >
) }
< / div >
2026-04-22 01:02:45 +06:00
< / div >
< / div >
) }
{ activeTab === 'documents' && (
< div >
2026-04-22 01:18:03 +06:00
< div className = "flex items-center justify-between mb-4" >
< h3 className = "font-semibold text-slate-800" > KYC Documents < / h3 >
< button onClick = { ( ) = > setShowDocModal ( 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" / > Upload Document
< / button >
< / div >
< div className = "space-y-2 mb-6" >
2026-04-22 01:02:45 +06:00
{ investor . kycDocuments ? . map ( ( doc , idx ) = > (
2026-04-22 01:18:03 +06:00
< div key = { idx } className = "flex items-center justify-between p-4 bg-slate-50 rounded-lg" >
2026-04-22 01:02:45 +06:00
< div className = "flex items-center gap-3" >
2026-04-22 01:18:03 +06:00
< div className = { ` w-12 h-12 rounded-lg flex items-center justify-center ${
doc . type === 'nid' ? 'bg-blue-100' :
doc . type === 'passport' ? 'bg-purple-100' :
doc . type === 'bank_statement' ? 'bg-green-100' :
doc . type === 'tin_certificate' ? 'bg-amber-100' : 'bg-slate-100'
} ` }>
< FileText className = { ` w-6 h-6 ${
doc . type === 'nid' ? 'text-blue-600' :
doc . type === 'passport' ? 'text-purple-600' :
doc . type === 'bank_statement' ? 'text-green-600' :
doc . type === 'tin_certificate' ? 'text-amber-600' : 'text-slate-600'
} ` } />
< / div >
2026-04-22 01:02:45 +06:00
< div >
< p className = "text-sm font-medium text-slate-700 capitalize" > { doc . type . replace ( '_' , ' ' ) } < / p >
2026-04-22 01:18:03 +06:00
< p className = "text-xs text-slate-400" > { doc . number || 'No document number' } • Uploaded : { doc . uploadedAt || 'N/A' } < / p >
2026-04-22 01:02:45 +06:00
< / div >
< / div >
< div className = "flex items-center gap-2" >
{ doc . verified ? (
2026-04-22 01:18:03 +06:00
< span className = "flex items-center gap-1 text-xs font-medium px-3 py-1.5 rounded-full bg-green-100 text-green-700" >
2026-04-22 01:02:45 +06:00
< CheckCircle className = "w-3 h-3" / > Verified
< / span >
) : (
2026-04-22 01:18:03 +06:00
< span className = "flex items-center gap-1 text-xs font-medium px-3 py-1.5 rounded-full bg-amber-100 text-amber-700" >
< Clock className = "w-3 h-3" / > Pending Review
2026-04-22 01:02:45 +06:00
< / span >
) }
2026-04-22 01:18:03 +06:00
< button onClick = { ( ) = > alert ( 'Edit document' ) } className = "p-2 hover:bg-slate-200 rounded-lg" >
< Edit className = "w-4 h-4 text-slate-400" / >
< / button >
< 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" / >
< / button >
2026-04-22 01:02:45 +06:00
< / div >
< / div >
) ) }
{ ( ! investor . kycDocuments || investor . kycDocuments . length === 0 ) && (
2026-04-22 01:18:03 +06:00
< div className = "text-center py-12 text-slate-400 border-2 border-dashed border-slate-200 rounded-lg" >
2026-04-22 01:02:45 +06:00
< FileText className = "w-12 h-12 mx-auto mb-2 opacity-50" / >
2026-04-22 01:18:03 +06:00
< p > No documents uploaded yet < / p >
2026-04-22 01:02:45 +06:00
< / div >
) }
< / div >
2026-04-22 01:18:03 +06:00
< 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 >
< p className = "text-sm text-blue-700" >
{ investor . kycStatus === 'verified'
? 'All documents have been verified. Investor is fully verified.'
: investor . kycStatus === 'pending'
? 'Documents are under review. Verification typically takes 24-48 hours.'
: 'Please upload required documents for verification.' }
< / p >
2026-04-22 01:02:45 +06:00
< / div >
< / div >
) }
< / div >
< / div >
{ showAssignBikeModal && (
< 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-md" >
< div className = "p-5 border-b border-slate-100 flex items-center justify-between" >
< h2 className = "text-lg font-bold text-slate-800" > Assign Bike to Investor < / h2 >
< button onClick = { ( ) = > setShowAssignBikeModal ( false ) } className = "p-2 hover:bg-slate-100 rounded-lg" >
< X className = "w-5 h-5 text-slate-400" / >
< / button >
< / div >
< div className = "p-5" >
< label className = "text-sm font-medium text-slate-600 mb-1 block" > Select Bike < / label >
< select
value = { selectedBikeId }
onChange = { ( e ) = > setSelectedBikeId ( e . target . value ) }
className = "w-full px-3 py-2 border border-slate-200 rounded-lg text-sm"
>
< option value = "" > Select a bike < / option >
{ availableBikesForAssignment . map ( bike = > (
< option key = { bike . id } value = { bike . id } >
{ bike . model } - { bike . plateNumber } ( ৳ { bike . purchasePrice ? . toLocaleString ( ) || 0 } )
< / option >
) ) }
< / select >
< / div >
< div className = "p-5 border-t border-slate-100 flex justify-end gap-3" >
< button onClick = { ( ) = > setShowAssignBikeModal ( 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 = { handleAssignBike } disabled = { ! selectedBikeId } className = "px-4 py-2 bg-investor text-white rounded-lg text-sm hover:bg-investor-dark disabled:opacity-50" > Assign Bike < / button >
< / div >
< / div >
< / div >
) }
2026-04-22 01:09:51 +06:00
{ showCreateInvestmentModal && (
< 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" > Create New Investment < / h2 >
< button onClick = { ( ) = > setShowCreateInvestmentModal ( false ) } className = "p-2 hover:bg-slate-100 rounded-lg" >
< X className = "w-5 h-5 text-slate-400" / >
< / button >
< / div >
< div className = "p-5 overflow-y-auto flex-1 space-y-4" >
< div className = "grid grid-cols-2 gap-4" >
< div >
< label className = "text-sm font-medium text-slate-600 mb-1 block" > Plan Name * < / label >
< input
type = "text"
value = { newInvestment . planName }
onChange = { ( e ) = > setNewInvestment ( { . . . newInvestment , planName : e.target.value } ) }
className = "w-full px-3 py-2 border border-slate-200 rounded-lg text-sm"
placeholder = "e.g., Gold EV Fleet 2024"
/ >
< / div >
< div >
< label className = "text-sm font-medium text-slate-600 mb-1 block" > Plan Type * < / label >
< select
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 } ) }
className = "w-full px-3 py-2 border border-slate-200 rounded-lg text-sm"
>
< option value = "silver" > Silver ( 12 % ROI ) < / option >
< option value = "gold" > Gold ( 15 % ROI ) < / option >
< option value = "platinum" > Platinum ( 18 % ROI ) < / option >
< option value = "diamond" > Diamond ( 20 % ROI ) < / option >
< / select >
< / div >
< / div >
< div >
< label className = "text-sm font-medium text-slate-600 mb-1 block" > Select Bikes < / label >
< 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 = > (
< label key = { bike . id } className = "flex items-center gap-2 p-2 hover:bg-slate-50 rounded cursor-pointer" >
< input
type = "checkbox"
checked = { newInvestment . selectedBikeIds . includes ( bike . id ) }
onChange = { ( e ) = > {
if ( e . target . checked ) {
setNewInvestment ( { . . . newInvestment , selectedBikeIds : [ . . . newInvestment . selectedBikeIds , bike . id ] } ) ;
} else {
setNewInvestment ( { . . . newInvestment , selectedBikeIds : newInvestment.selectedBikeIds.filter ( id = > id !== bike . id ) } ) ;
}
} }
className = "rounded text-investor"
/ >
< span className = "text-sm" > { bike . model } ( { bike . plateNumber } ) < / span >
< / label >
) ) }
< / div >
< / div >
< div className = "grid grid-cols-3 gap-4" >
< div >
< label className = "text-sm font-medium text-slate-600 mb-1 block" > Investment Amount ( ৳ ) * < / label >
< input
type = "number"
value = { newInvestment . totalInvestment }
onChange = { ( e ) = > setNewInvestment ( { . . . newInvestment , totalInvestment : Number ( e . target . value ) , monthlyReturn : Math.round ( Number ( e . target . value ) * newInvestment . expectedRoi / 100 / 12 ) } ) }
className = "w-full px-3 py-2 border border-slate-200 rounded-lg text-sm"
placeholder = "0"
/ >
< / div >
< div >
< label className = "text-sm font-medium text-slate-600 mb-1 block" > Monthly Return ( ৳ ) < / label >
< input
type = "number"
value = { newInvestment . monthlyReturn }
onChange = { ( e ) = > setNewInvestment ( { . . . newInvestment , monthlyReturn : Number ( e . target . value ) } ) }
className = "w-full px-3 py-2 border border-slate-200 rounded-lg text-sm"
placeholder = "0"
/ >
< / div >
< div >
< label className = "text-sm font-medium text-slate-600 mb-1 block" > Expected ROI ( % ) < / label >
< input
type = "number"
value = { newInvestment . expectedRoi }
onChange = { ( e ) = > setNewInvestment ( { . . . newInvestment , expectedRoi : Number ( e . target . value ) } ) }
className = "w-full px-3 py-2 border border-slate-200 rounded-lg text-sm"
placeholder = "15"
/ >
< / div >
< / div >
< div className = "grid grid-cols-2 gap-4" >
< div >
< label className = "text-sm font-medium text-slate-600 mb-1 block" > Start Date * < / label >
< input
type = "date"
value = { newInvestment . startDate }
onChange = { ( e ) = > setNewInvestment ( { . . . newInvestment , startDate : e.target.value } ) }
className = "w-full px-3 py-2 border border-slate-200 rounded-lg text-sm"
/ >
< / div >
< div >
< label className = "text-sm font-medium text-slate-600 mb-1 block" > End Date < / label >
< input
type = "date"
value = { newInvestment . endDate }
onChange = { ( e ) = > setNewInvestment ( { . . . newInvestment , endDate : e.target.value } ) }
className = "w-full px-3 py-2 border border-slate-200 rounded-lg text-sm"
/ >
< / div >
< / div >
< div className = "grid grid-cols-2 gap-4" >
< div >
< label className = "text-sm font-medium text-slate-600 mb-1 block" > Payment Method * < / label >
< select
value = { newInvestment . paymentMethod }
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"
>
< option value = "bank" > Bank Transfer < / option >
< option value = "mobile" > Mobile Banking < / option >
< option value = "cash" > Cash < / option >
< option value = "cheque" > Cheque < / option >
< / select >
< / div >
< div >
< label className = "text-sm font-medium text-slate-600 mb-1 block" > Transaction Reference < / label >
< input
type = "text"
value = { newInvestment . transactionReference }
onChange = { ( e ) = > setNewInvestment ( { . . . newInvestment , transactionReference : e.target.value } ) }
className = "w-full px-3 py-2 border border-slate-200 rounded-lg text-sm"
placeholder = "Auto-generated if empty"
/ >
< / div >
< / div >
< div >
< label className = "text-sm font-medium text-slate-600 mb-1 block" > Notes < / label >
< textarea
value = { newInvestment . notes }
onChange = { ( e ) = > setNewInvestment ( { . . . newInvestment , notes : e.target.value } ) }
className = "w-full px-3 py-2 border border-slate-200 rounded-lg text-sm"
rows = { 2 }
placeholder = "Additional notes..."
/ >
< / div >
< div className = "bg-blue-50 border border-blue-200 rounded-lg p-4" >
< h4 className = "font-semibold text-blue-800 mb-2" > Accounting Entries to be Created : < / h4 >
< div className = "text-sm text-blue-700 space-y-1" >
< p > • Debit : Investment Asset - Investor ( { newInvestment . totalInvestment ? ` ৳ ${ newInvestment . totalInvestment . toLocaleString ( ) } ` : '৳0' } ) < / p >
< p > • Credit : { newInvestment . paymentMethod === 'bank' ? 'Bank Account' : newInvestment . paymentMethod === 'mobile' ? 'Mobile Wallet' : newInvestment . paymentMethod === 'cash' ? 'Cash Account' : 'Cheque Receivable' } ( { newInvestment . totalInvestment ? ` ৳ ${ newInvestment . totalInvestment . toLocaleString ( ) } ` : '৳0' } ) < / p >
< p > • Transaction ID will be auto - generated < / p >
< / div >
< / div >
< / div >
< 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 = { handleCreateInvestment }
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"
>
< TrendingUp className = "w-4 h-4" / > Create Investment
< / button >
< / div >
< / div >
< / div >
) }
2026-04-22 01:18:03 +06:00
{ showBankModal && (
< 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-md" >
< div className = "p-5 border-b border-slate-100 flex items-center justify-between" >
< h2 className = "text-lg font-bold text-slate-800" > Bank Details < / h2 >
< button onClick = { ( ) = > setShowBankModal ( false ) } className = "p-2 hover:bg-slate-100 rounded-lg" >
< X className = "w-5 h-5 text-slate-400" / >
< / button >
< / div >
< div className = "p-5 space-y-4" >
< div >
< label className = "text-sm font-medium text-slate-600 mb-1 block" > Bank Name < / label >
< input type = "text" value = { editingBank . bankName } onChange = { ( e ) = > setEditingBank ( { . . . editingBank , bankName : e.target.value } ) } className = "w-full px-3 py-2 border border-slate-200 rounded-lg text-sm" placeholder = "e.g., Standard Chartered Bank" / >
< / div >
< div >
< label className = "text-sm font-medium text-slate-600 mb-1 block" > Branch < / label >
< input type = "text" value = { editingBank . bankBranch } onChange = { ( e ) = > setEditingBank ( { . . . editingBank , bankBranch : e.target.value } ) } className = "w-full px-3 py-2 border border-slate-200 rounded-lg text-sm" placeholder = "e.g., Gulshan Branch" / >
< / div >
< div >
< label className = "text-sm font-medium text-slate-600 mb-1 block" > Account Name < / label >
< input type = "text" value = { editingBank . bankAccountName } onChange = { ( e ) = > setEditingBank ( { . . . editingBank , bankAccountName : e.target.value } ) } className = "w-full px-3 py-2 border border-slate-200 rounded-lg text-sm" placeholder = "Account holder name" / >
< / div >
< div >
< label className = "text-sm font-medium text-slate-600 mb-1 block" > Account Number < / label >
< input type = "text" value = { editingBank . bankAccountNumber } onChange = { ( e ) = > setEditingBank ( { . . . editingBank , bankAccountNumber : e.target.value } ) } className = "w-full px-3 py-2 border border-slate-200 rounded-lg text-sm" placeholder = "Account number" / >
< / div >
< div >
< label className = "text-sm font-medium text-slate-600 mb-1 block" > Routing Number < / label >
< input type = "text" value = { editingBank . bankRouting } onChange = { ( e ) = > setEditingBank ( { . . . editingBank , bankRouting : e.target.value } ) } className = "w-full px-3 py-2 border border-slate-200 rounded-lg text-sm" placeholder = "Routing number" / >
< / div >
< / div >
< div className = "p-5 border-t border-slate-100 flex justify-between" >
{ investor . bankName && (
< button onClick = { ( ) = > { alert ( 'Bank details deleted' ) ; setShowBankModal ( false ) ; } } className = "px-4 py-2 border border-red-200 text-red-600 rounded-lg text-sm hover:bg-red-50" > Delete < / button >
) }
< div className = "flex gap-2 ml-auto" >
< button onClick = { ( ) = > setShowBankModal ( 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 = { ( ) = > { alert ( 'Bank details saved!' ) ; setShowBankModal ( false ) ; } } className = "px-4 py-2 bg-investor text-white rounded-lg text-sm hover:bg-investor-dark" > Save < / button >
< / div >
< / div >
< / div >
< / div >
) }
{ showMobileBankingModal && (
< 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-md" >
< div className = "p-5 border-b border-slate-100 flex items-center justify-between" >
< h2 className = "text-lg font-bold text-slate-800" > { editingMobileIndex !== null ? 'Edit' : 'Add' } Mobile Banking < / h2 >
< button onClick = { ( ) = > setShowMobileBankingModal ( false ) } className = "p-2 hover:bg-slate-100 rounded-lg" >
< X className = "w-5 h-5 text-slate-400" / >
< / button >
< / div >
< div className = "p-5 space-y-4" >
< div >
< label className = "text-sm font-medium text-slate-600 mb-1 block" > Provider < / label >
< select value = { editingMobileBanking . provider } onChange = { ( e ) = > setEditingMobileBanking ( { . . . editingMobileBanking , provider : e.target.value } ) } className = "w-full px-3 py-2 border border-slate-200 rounded-lg text-sm" >
< option value = "" > Select Provider < / option >
< option value = "Bkash" > Bkash < / option >
< option value = "Nagad" > Nagad < / option >
< option value = "Rocket" > Rocket < / option >
< option value = "Upay" > Upay < / option >
< / select >
< / div >
< div >
< label className = "text-sm font-medium text-slate-600 mb-1 block" > Mobile Number < / label >
< input type = "text" value = { editingMobileBanking . number } onChange = { ( e ) = > setEditingMobileBanking ( { . . . editingMobileBanking , number : e . target . value } ) } className = "w-full px-3 py-2 border border-slate-200 rounded-lg text-sm" placeholder = "01XXXXXXXXX" / >
< / div >
< div className = "flex items-center gap-2" >
< input type = "checkbox" checked = { editingMobileBanking . isPrimary } onChange = { ( e ) = > setEditingMobileBanking ( { . . . editingMobileBanking , isPrimary : e.target.checked } ) } className = "rounded text-investor" / >
< span className = "text-sm text-slate-600" > Set as primary account < / span >
< / div >
< / div >
< div className = "p-5 border-t border-slate-100 flex justify-end gap-3" >
< button onClick = { ( ) = > setShowMobileBankingModal ( 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 = { ( ) = > { alert ( 'Mobile banking saved!' ) ; setShowMobileBankingModal ( false ) ; } } className = "px-4 py-2 bg-investor text-white rounded-lg text-sm hover:bg-investor-dark" > Save < / button >
< / div >
< / div >
< / div >
) }
{ showTaxModal && (
< 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-md" >
< div className = "p-5 border-b border-slate-100 flex items-center justify-between" >
< h2 className = "text-lg font-bold text-slate-800" > Tax Information < / h2 >
< button onClick = { ( ) = > setShowTaxModal ( false ) } className = "p-2 hover:bg-slate-100 rounded-lg" >
< X className = "w-5 h-5 text-slate-400" / >
< / button >
< / div >
< div className = "p-5 space-y-4" >
< div >
< label className = "text-sm font-medium text-slate-600 mb-1 block" > TIN Number < / label >
< input type = "text" value = { editingTax . tinNumber } onChange = { ( e ) = > setEditingTax ( { . . . editingTax , tinNumber : e.target.value } ) } className = "w-full px-3 py-2 border border-slate-200 rounded-lg text-sm" placeholder = "TIN Number" / >
< / div >
< div >
< label className = "text-sm font-medium text-slate-600 mb-1 block" > Passport Number < / label >
< input type = "text" value = { editingTax . passportNumber } onChange = { ( e ) = > setEditingTax ( { . . . editingTax , passportNumber : e.target.value } ) } className = "w-full px-3 py-2 border border-slate-200 rounded-lg text-sm" placeholder = "Passport Number" / >
< / div >
< / div >
< div className = "p-5 border-t border-slate-100 flex justify-between" >
{ ( investor . tinNumber || investor . passportNumber ) && (
< button onClick = { ( ) = > { alert ( 'Tax info deleted' ) ; setShowTaxModal ( false ) ; } } className = "px-4 py-2 border border-red-200 text-red-600 rounded-lg text-sm hover:bg-red-50" > Delete All < / button >
) }
< div className = "flex gap-2 ml-auto" >
< button onClick = { ( ) = > setShowTaxModal ( 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 = { ( ) = > { alert ( 'Tax info saved!' ) ; setShowTaxModal ( false ) ; } } className = "px-4 py-2 bg-investor text-white rounded-lg text-sm hover:bg-investor-dark" > Save < / button >
< / div >
< / div >
< / div >
< / div >
) }
{ showDocModal && (
< 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-md" >
< div className = "p-5 border-b border-slate-100 flex items-center justify-between" >
< h2 className = "text-lg font-bold text-slate-800" > Upload Document < / h2 >
< button onClick = { ( ) = > setShowDocModal ( false ) } className = "p-2 hover:bg-slate-100 rounded-lg" >
< X className = "w-5 h-5 text-slate-400" / >
< / button >
< / div >
< div className = "p-5 space-y-4" >
< div >
< label className = "text-sm font-medium text-slate-600 mb-1 block" > Document Type < / label >
< select value = { newDoc . type } onChange = { ( e ) = > setNewDoc ( { . . . newDoc , type : e . target . value } ) } className = "w-full px-3 py-2 border border-slate-200 rounded-lg text-sm" >
< option value = "nid" > NID Card < / option >
< option value = "passport" > Passport < / option >
< option value = "bank_statement" > Bank Statement < / option >
< option value = "tin_certificate" > TIN Certificate < / option >
< option value = "trade_license" > Trade License < / option >
< option value = "other" > Other < / option >
< / select >
< / div >
< div >
< label className = "text-sm font-medium text-slate-600 mb-1 block" > Document Number < / label >
< input type = "text" value = { newDoc . number } onChange = { ( e ) = > setNewDoc ( { . . . newDoc , number : e . target . value } ) } className = "w-full px-3 py-2 border border-slate-200 rounded-lg text-sm" placeholder = "Document number (optional)" / >
< / div >
< div >
< label className = "text-sm font-medium text-slate-600 mb-1 block" > Upload File < / label >
< div className = "border-2 border-dashed border-slate-200 rounded-lg p-6 text-center" >
< FileText className = "w-10 h-10 text-slate-300 mx-auto mb-2" / >
< p className = "text-sm text-slate-500 mb-2" > Click to upload or drag and drop < / p >
< p className = "text-xs text-slate-400" > PNG , JPG , PDF up to 10 MB < / p >
< / div >
< / div >
< / div >
< div className = "p-5 border-t border-slate-100 flex justify-end gap-3" >
< button onClick = { ( ) = > setShowDocModal ( 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 = { ( ) = > { alert ( 'Document uploaded successfully!' ) ; setShowDocModal ( false ) ; } } className = "px-4 py-2 bg-investor text-white rounded-lg text-sm hover:bg-investor-dark" > Upload < / button >
< / div >
< / div >
< / div >
) }
2026-04-22 01:02:45 +06:00
< / div >
) ;
}