2026-04-22 01:02:45 +06:00
'use client' ;
import { useState } from 'react' ;
import Link from 'next/link' ;
2026-05-14 13:54:02 +06:00
import { useParams , useRouter } from 'next/navigation' ;
2026-04-22 01:02:45 +06:00
import { investors as initialInvestors , bikes as initialBikes , transactions as initialTransactions } from '@/data/mockData' ;
import type { Investor } from '@/data/mockData' ;
2026-05-14 13:54:02 +06:00
import toast from 'react-hot-toast' ;
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 , BookOpen , ArrowRight , Printer ,
UserCircle , Home , Briefcase , CreditCardIcon , Heart , PhoneCall , PhoneOutgoing , MessageSquare , Save ,
ShieldCheck , Building2 , Users , Check , AlertOctagon , Activity , Award , Camera
2026-04-22 01:02:45 +06:00
} 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' ,
} ;
2026-05-14 13:54:02 +06:00
function SectionCard ( { title , icon : Icon , children , headerBg = 'bg-slate-50' , headerBorder = 'border-slate-100' , editKey , editingSection , setEditingSection , onEdit , editForm , setEditForm } : { title : string ; icon : any ; children : React.ReactNode ; headerBg? : string ; headerBorder? : string ; editKey? : string ; editingSection? : string | null ; setEditingSection ? : ( s : string | null ) = > void ; onEdit ? : ( ) = > void ; editForm? : any ; setEditForm? : any } ) {
return (
< div className = "bg-white rounded-xl border border-slate-200 overflow-hidden" >
< div className = { ` ${ headerBg } px-5 py-4 border-b ${ headerBorder } flex items-center justify-between ` } >
< div className = "flex items-center gap-2" >
< Icon className = "w-5 h-5 text-slate-600" / >
< h3 className = "font-semibold text-slate-800" > { title } < / h3 >
< / div >
{ editKey && setEditingSection ? (
editingSection !== editKey ? (
< button onClick = { ( ) = > { setEditingSection ( editKey ) ; onEdit ? . ( ) ; } } className = "p-1.5 hover:bg-white rounded-lg transition-colors" >
< Edit className = "w-4 h-4 text-slate-500" / >
< / button >
) : (
< div className = "flex gap-1" >
< button onClick = { ( ) = > { toast . success ( 'Updated' ) ; setEditingSection ( null ) ; } } className = "px-3 py-1.5 bg-green-600 text-white rounded-lg text-xs font-medium hover:bg-green-700" > Save < / button >
< button onClick = { ( ) = > setEditingSection ( null ) } className = "px-3 py-1.5 border border-slate-200 text-slate-600 rounded-lg text-xs font-medium hover:bg-slate-50" > Cancel < / button >
< / div >
)
) : null }
< / div >
< div className = "p-4" >
{ children }
< / div >
< / div >
) ;
}
2026-04-22 01:02:45 +06:00
export default function InvestorDetailPage() {
const params = useParams ( ) ;
2026-05-14 13:54:02 +06:00
const router = useRouter ( ) ;
2026-04-22 01:02:45 +06:00
const investorId = params . id as string ;
2026-05-14 13:54:02 +06:00
2026-04-22 01:02:45 +06:00
const [ investors ] = useState < Investor [ ] > ( initialInvestors ) ;
const investor = investors . find ( i = > i . id === investorId ) ;
2026-05-14 13:54:02 +06:00
2026-04-22 01:02:45 +06:00
const assignedBikes = initialBikes . filter ( b = > b . investorId === investorId ) ;
2026-04-22 01:18:03 +06:00
// Investor transactions are filtered below
2026-05-14 13:54:02 +06:00
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-05-14 19:49:57 +06:00
const [ showInvestmentSuccessModal , setShowInvestmentSuccessModal ] = useState ( false ) ;
const [ lastCreatedInvestment , setLastCreatedInvestment ] = useState < any > ( null ) ;
2026-04-26 14:56:12 +06:00
const [ showInvoiceModal , setShowInvoiceModal ] = useState ( false ) ;
const [ showJournalModal , setShowJournalModal ] = useState ( false ) ;
const [ selectedInvoice , setSelectedInvoice ] = useState < any > ( null ) ;
const [ investorJournals , setInvestorJournals ] = useState < any [ ] > ( [ ] ) ;
2026-04-22 01:18:03 +06:00
const [ showBankModal , setShowBankModal ] = useState ( false ) ;
2026-05-14 13:54:02 +06:00
const [ editingSection , setEditingSection ] = useState < string | null > ( null ) ;
const [ editForm , setEditForm ] = useState < any > ( { } ) ;
2026-04-22 01:18:03 +06:00
const [ showMobileBankingModal , setShowMobileBankingModal ] = useState ( false ) ;
const [ showTaxModal , setShowTaxModal ] = useState ( false ) ;
const [ showDocModal , setShowDocModal ] = useState ( false ) ;
2026-05-14 20:15:39 +06:00
const [ editingBankAccount , setEditingBankAccount ] = useState < any > ( { id : '' , bankName : '' , accountName : '' , accountNumber : '' , branch : '' , routing : '' , isPrimary : false } ) ;
const [ bankSaveSuccess , setBankSaveSuccess ] = useState ( false ) ;
const [ showDeleteBankModal , setShowDeleteBankModal ] = useState ( false ) ;
const [ bankErrors , setBankErrors ] = useState < { bankName? : string ; accountName? : string ; accountNumber? : string } > ( { } ) ;
2026-04-22 01:18:03 +06:00
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 = ( ) = > {
2026-04-26 14:56:12 +06:00
const invId = ` INV- ${ Date . now ( ) } ` ;
const year = new Date ( ) . getFullYear ( ) ;
const transactionRef = newInvestment . transactionReference || ` INV/ ${ year } / ${ String ( investor . investments . length + 1 ) . padStart ( 4 , '0' ) } ` ;
2026-05-14 13:54:02 +06:00
2026-04-26 14:56:12 +06:00
const getDebitAccount = ( method : string ) = > {
switch ( method ) {
case 'bank' : return { code : '1200' , name : 'Bank - City Bank' } ;
case 'cash' : return { code : '1100' , name : 'Cash in Hand' } ;
case 'mobile' : return { code : '1300' , name : 'bKash Business' } ;
case 'cheque' : return { code : '1410' , name : 'Cheque Receivable' } ;
default : return { code : '1200' , name : 'Bank - City Bank' } ;
}
} ;
2026-05-14 13:54:02 +06:00
2026-04-26 14:56:12 +06:00
const debitAccount = getDebitAccount ( newInvestment . paymentMethod ) ;
2026-05-14 13:54:02 +06:00
2026-04-26 14:56:12 +06:00
const journalEntry = {
entryId : ` JE- ${ Date . now ( ) } ` ,
date : newInvestment.startDate ,
reference : transactionRef ,
description : ` ${ investor . name } - ${ newInvestment . planName } ` ,
entries : [
{ accountCode : debitAccount.code , accountName : debitAccount.name , debit : newInvestment.totalInvestment , credit : 0 } ,
{ accountCode : '2200' , accountName : 'Investor Liabilities' , debit : 0 , credit : newInvestment.totalInvestment } ,
] ,
isAuto : true ,
sourceType : 'investor_funding' ,
createdAt : new Date ( ) . toISOString ( ) ,
type : 'investment' ,
amount : newInvestment.totalInvestment ,
paymentMethod : newInvestment.paymentMethod
} ;
2026-05-14 13:54:02 +06:00
2026-05-14 19:49:57 +06:00
setInvestorJournals ( [ journalEntry , . . . investorJournals ] ) ;
2026-05-14 13:54:02 +06:00
2026-05-14 19:49:57 +06:00
setLastCreatedInvestment ( {
2026-04-22 01:09:51 +06:00
id : invId ,
investorId : investor.id ,
. . . newInvestment ,
actualEarnings : 0 ,
2026-05-14 19:49:57 +06:00
status : 'active' ,
2026-04-26 14:56:12 +06:00
transactionId : transactionRef ,
2026-05-14 19:49:57 +06:00
createdAt : new Date ( ) . toISOString ( ) ,
debitAccount ,
journalEntry
2026-04-22 01:09:51 +06:00
} ) ;
2026-05-14 13:54:02 +06:00
2026-04-22 01:09:51 +06:00
setShowCreateInvestmentModal ( false ) ;
2026-05-14 19:49:57 +06:00
setShowInvestmentSuccessModal ( true ) ;
2026-04-22 01:09:51 +06:00
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" >
2026-05-14 13:54:02 +06:00
< button onClick = { ( ) = > router . push ( '/admin/investors' ) } className = "flex items-center gap-2 text-slate-600 hover:text-slate-800 mb-4" >
< ArrowLeft className = "w-4 h-4" / > Back to Investors
< / button >
{ /* Profile Card Header */ }
< div className = "bg-white rounded-xl shadow-sm border border-slate-100 overflow-hidden mb-6" >
< div className = "p-5" >
< div className = "flex flex-col lg:flex-row lg:items-start gap-5" >
{ /* Profile Image */ }
< div className = "relative group flex-shrink-0 mx-auto lg:mx-0" >
< div className = "w-24 h-24 rounded-full bg-gradient-to-br from-purple-500 to-blue-500 flex items-center justify-center shadow-lg border-4 border-white" >
< span className = "text-3xl font-extrabold text-white" > { investor . name . charAt ( 0 ) } < / span >
< / div >
< label className = "absolute bottom-0 right-0 w-8 h-8 bg-blue-600 rounded-full flex items-center justify-center cursor-pointer opacity-0 group-hover:opacity-100 transition-opacity shadow-lg border-2 border-white" >
< Camera className = "w-4 h-4 text-white" / >
< input type = "file" accept = "image/*" className = "hidden" onChange = { ( ) = > toast . success ( 'Profile image updated' ) } / >
< / label >
< / div >
2026-04-22 01:02:45 +06:00
2026-05-14 13:54:02 +06:00
{ /* Profile Info */ }
< div className = "flex-1" >
< div className = "flex flex-col lg:flex-row lg:items-start lg:justify-between gap-4" >
< div >
< h1 className = "text-2xl font-extrabold text-slate-800" > { investor . name } < / h1 >
< p className = "text-sm text-slate-500 mt-0.5" > { investor . id } & bull ; { investor . email } < / p >
< div className = "flex items-center gap-2 mt-1" >
{ investor . referralCode && (
< span className = "inline-flex items-center gap-1 text-xs font-medium px-2 py-0.5 rounded bg-purple-50 text-purple-700 border border-purple-100" >
< Star className = "w-3 h-3" / > Ref : { investor . referralCode }
< / span >
) }
{ investor . totalReferrals > 0 && (
< span className = "text-xs text-slate-400" > Referrals : { investor . totalReferrals } < / span >
) }
< / div >
< div className = "flex flex-wrap items-center gap-2 mt-2" >
< span className = { ` inline-flex items-center gap-1 text-xs font-medium px-2.5 py-1 rounded-full ${ statusColors [ investor . status ] } ` } > { investor . status } < / span >
{ investor . investments && investor . investments . length > 0 && (
< span className = { ` inline-flex items-center gap-1 text-xs font-medium px-2.5 py-1 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-xs font-medium px-2.5 py-1 rounded-full ${ kycColors [ investor . kycStatus ] } ` } >
< ShieldCheck className = "w-3 h-3" / > KYC { investor . kycStatus }
< / span >
< span className = { ` inline-flex items-center gap-1 text-xs font-medium px-2.5 py-1 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 >
< div className = "flex items-center gap-2 flex-shrink-0" >
< button onClick = { ( ) = > setShowEditModal ( true ) } className = "py-2 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 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 >
2026-04-22 01:02:45 +06:00
2026-05-14 13:54:02 +06:00
{ /* Stats Row */ }
< div className = "grid grid-cols-3 lg:grid-cols-6 gap-3 mt-5" >
< div className = "p-3 bg-purple-50 rounded-lg border border-purple-100" >
< p className = "text-xs text-purple-600 font-medium" > Total Invested < / p >
< p className = "text-sm font-bold text-purple-700" > ৳ { investor . totalInvested . toLocaleString ( ) } < / p >
< / div >
< div className = "p-3 bg-green-50 rounded-lg border border-green-100" >
< p className = "text-xs text-green-600 font-medium" > Total Earnings < / p >
< p className = "text-sm font-bold text-green-700" > ৳ { investor . totalEarnings . toLocaleString ( ) } < / p >
< / div >
< div className = "p-3 bg-blue-50 rounded-lg border border-blue-100" >
< p className = "text-xs text-blue-600 font-medium" > ROI < / p >
< p className = "text-sm font-bold text-blue-700" > { investor . roi } % < / p >
< / div >
< div className = "p-3 bg-amber-50 rounded-lg border border-amber-100" >
< p className = "text-xs text-amber-600 font-medium" > Active Bikes < / p >
< p className = "text-sm font-bold text-amber-700" > { investor . activeBikes } < / p >
< / div >
< div className = "p-3 bg-red-50 rounded-lg border border-red-100" >
< p className = "text-xs text-red-600 font-medium" > Pending Earning < / p >
< p className = "text-sm font-bold text-red-700" > ৳ { investor . pendingEarnings . toLocaleString ( ) } < / p >
< / div >
< div className = "p-3 bg-slate-50 rounded-lg border border-slate-100" >
< p className = "text-xs text-slate-600 font-medium" > Withdrawn < / p >
< p className = "text-sm font-bold text-slate-700" > ৳ { investor . totalWithdrawn . toLocaleString ( ) } < / p >
< / div >
< / div >
2026-04-22 01:02:45 +06:00
< / 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' && (
2026-05-14 13:54:02 +06:00
< div className = "space-y-4" >
< div className = "flex gap-4" >
< div className = "flex-1 space-y-4" >
< SectionCard title = "Personal Information" icon = { User } headerBg = "bg-emerald-50" headerBorder = "border-emerald-100" editKey = "personal" editingSection = { editingSection } setEditingSection = { setEditingSection } onEdit = { ( ) = > setEditForm ( {
fullName : investor.name ,
phone : investor.phone ,
phoneAlt : investor.phoneAlt || '' ,
email : investor.email ,
nidNumber : investor.nidNumber || '' ,
tinNumber : investor.tinNumber || '' ,
dateOfBirth : investor.dateOfBirth || '' ,
gender : investor.gender || '' ,
occupation : investor.occupation || '' ,
bloodGroup : ( investor as any ) . bloodGroup || '' ,
maritalStatus : ( investor as any ) . maritalStatus || '' ,
religion : ( investor as any ) . religion || '' ,
nationality : ( investor as any ) . nationality || 'Bangladeshi'
} ) } editForm = { editForm } setEditForm = { setEditForm } >
{ editingSection === 'personal' ? (
< div className = "grid grid-cols-1 md:grid-cols-2 gap-3" >
< div className = "md:col-span-2" >
< label className = "text-xs text-slate-500 mb-1 block" > Full Name < / label >
< input type = "text" value = { editForm . fullName || '' } onChange = { ( e ) = > setEditForm ( { . . . editForm , fullName : e.target.value } ) } className = "w-full px-3 py-2 border border-slate-200 rounded-lg text-sm" / >
< / div >
< div >
< label className = "text-xs text-slate-500 mb-1 block" > Phone < / label >
< input type = "text" value = { editForm . phone || '' } onChange = { ( e ) = > setEditForm ( { . . . editForm , phone : e.target.value } ) } className = "w-full px-3 py-2 border border-slate-200 rounded-lg text-sm" / >
< / div >
< div >
< label className = "text-xs text-slate-500 mb-1 block" > Alternate Phone < / label >
< input type = "text" value = { editForm . phoneAlt || '' } onChange = { ( e ) = > setEditForm ( { . . . editForm , phoneAlt : e.target.value } ) } className = "w-full px-3 py-2 border border-slate-200 rounded-lg text-sm" / >
< / div >
< div className = "md:col-span-2" >
< label className = "text-xs text-slate-500 mb-1 block" > Email < / label >
< input type = "email" value = { editForm . email || '' } onChange = { ( e ) = > setEditForm ( { . . . editForm , email : e.target.value } ) } className = "w-full px-3 py-2 border border-slate-200 rounded-lg text-sm" / >
< / div >
< div >
< label className = "text-xs text-slate-500 mb-1 block" > NID Number < / label >
< input type = "text" value = { editForm . nidNumber || '' } onChange = { ( e ) = > setEditForm ( { . . . editForm , nidNumber : e.target.value } ) } className = "w-full px-3 py-2 border border-slate-200 rounded-lg text-sm" / >
< / div >
< div >
< label className = "text-xs text-slate-500 mb-1 block" > TIN Number < / label >
< input type = "text" value = { editForm . tinNumber || '' } onChange = { ( e ) = > setEditForm ( { . . . editForm , tinNumber : e.target.value } ) } className = "w-full px-3 py-2 border border-slate-200 rounded-lg text-sm" / >
< / div >
< div >
< label className = "text-xs text-slate-500 mb-1 block" > Date of Birth < / label >
< input type = "date" value = { editForm . dateOfBirth || '' } onChange = { ( e ) = > setEditForm ( { . . . editForm , dateOfBirth : e.target.value } ) } className = "w-full px-3 py-2 border border-slate-200 rounded-lg text-sm" / >
< / div >
< div >
< label className = "text-xs text-slate-500 mb-1 block" > Gender < / label >
< select value = { editForm . gender || '' } onChange = { ( e ) = > setEditForm ( { . . . editForm , gender : e.target.value } ) } className = "w-full px-3 py-2 border border-slate-200 rounded-lg text-sm" >
< option value = "" > Select < / option >
< option value = "Male" > Male < / option >
< option value = "Female" > Female < / option >
< option value = "Other" > Other < / option >
< / select >
< / div >
< div >
< label className = "text-xs text-slate-500 mb-1 block" > Occupation < / label >
< input type = "text" value = { editForm . occupation || '' } onChange = { ( e ) = > setEditForm ( { . . . editForm , occupation : e.target.value } ) } className = "w-full px-3 py-2 border border-slate-200 rounded-lg text-sm" / >
< / div >
< div >
< label className = "text-xs text-slate-500 mb-1 block" > Blood Group < / label >
< select value = { editForm . bloodGroup || '' } onChange = { ( e ) = > setEditForm ( { . . . editForm , bloodGroup : e.target.value } ) } className = "w-full px-3 py-2 border border-slate-200 rounded-lg text-sm" >
< option value = "" > Select < / option >
< option value = "A+" > A + < / option >
< option value = "A-" > A - < / option >
< option value = "B+" > B + < / option >
< option value = "B-" > B - < / option >
< option value = "O+" > O + < / option >
< option value = "O-" > O - < / option >
< option value = "AB+" > AB + < / option >
< option value = "AB-" > AB - < / option >
< / select >
< / div >
< div >
< label className = "text-xs text-slate-500 mb-1 block" > Marital Status < / label >
< select value = { editForm . maritalStatus || '' } onChange = { ( e ) = > setEditForm ( { . . . editForm , maritalStatus : e.target.value } ) } className = "w-full px-3 py-2 border border-slate-200 rounded-lg text-sm" >
< option value = "" > Select < / option >
< option value = "Single" > Single < / option >
< option value = "Married" > Married < / option >
< option value = "Divorced" > Divorced < / option >
< option value = "Widowed" > Widowed < / option >
< / select >
< / div >
< div >
< label className = "text-xs text-slate-500 mb-1 block" > Religion < / label >
< select value = { editForm . religion || '' } onChange = { ( e ) = > setEditForm ( { . . . editForm , religion : e.target.value } ) } className = "w-full px-3 py-2 border border-slate-200 rounded-lg text-sm" >
< option value = "" > Select < / option >
< option value = "Islam" > Islam < / option >
< option value = "Hinduism" > Hinduism < / option >
< option value = "Christianity" > Christianity < / option >
< option value = "Buddhism" > Buddhism < / option >
< option value = "Other" > Other < / option >
< / select >
< / div >
< div >
< label className = "text-xs text-slate-500 mb-1 block" > Nationality < / label >
< input type = "text" value = { editForm . nationality || '' } onChange = { ( e ) = > setEditForm ( { . . . editForm , nationality : e.target.value } ) } className = "w-full px-3 py-2 border border-slate-200 rounded-lg text-sm" / >
< / div >
2026-04-22 01:02:45 +06:00
< / div >
2026-05-14 13:54:02 +06:00
) : (
< div className = "grid grid-cols-1 md:grid-cols-2 gap-3" >
< div className = "p-3 bg-slate-50 rounded-lg" >
< p className = "text-xs text-slate-500" > Full Name < / p >
< p className = "font-medium text-slate-700" > { investor . name } < / p >
< / div >
< div className = "p-3 bg-slate-50 rounded-lg" >
< p className = "text-xs text-slate-500" > Phone < / p >
< p className = "font-medium text-slate-700" > { investor . phone } < / p >
< / div >
< div className = "p-3 bg-slate-50 rounded-lg" >
< p className = "text-xs text-slate-500" > Alternate Phone < / p >
< p className = "font-medium text-slate-700" > { investor . phoneAlt || '-' } < / p >
< / div >
< div className = "p-3 bg-slate-50 rounded-lg" >
< p className = "text-xs text-slate-500" > Email < / p >
< p className = "font-medium text-slate-700" > { investor . email } < / p >
< / div >
< div className = "p-3 bg-slate-50 rounded-lg" >
< p className = "text-xs text-slate-500" > NID Number < / p >
< p className = "font-medium text-slate-700" > { investor . nidNumber || '-' } < / p >
< / div >
< div className = "p-3 bg-slate-50 rounded-lg" >
< p className = "text-xs text-slate-500" > TIN Number < / p >
< p className = "font-medium text-slate-700" > { investor . tinNumber || '-' } < / p >
< / div >
< div className = "p-3 bg-slate-50 rounded-lg" >
< p className = "text-xs text-slate-500" > Date of Birth < / p >
< p className = "font-medium text-slate-700" > { investor . dateOfBirth || '-' } < / p >
< / div >
< div className = "p-3 bg-slate-50 rounded-lg" >
< p className = "text-xs text-slate-500" > Gender < / p >
< p className = "font-medium text-slate-700" > { investor . gender || '-' } < / p >
< / div >
< div className = "p-3 bg-slate-50 rounded-lg" >
< p className = "text-xs text-slate-500" > Occupation < / p >
< p className = "font-medium text-slate-700" > { investor . occupation || '-' } < / p >
< / div >
< div className = "p-3 bg-slate-50 rounded-lg" >
< p className = "text-xs text-slate-500" > Blood Group < / p >
< p className = "font-medium text-slate-700" > { ( investor as any ) . bloodGroup || '-' } < / p >
< / div >
< div className = "p-3 bg-slate-50 rounded-lg" >
< p className = "text-xs text-slate-500" > Marital Status < / p >
< p className = "font-medium text-slate-700" > { ( investor as any ) . maritalStatus || '-' } < / p >
< / div >
< div className = "p-3 bg-slate-50 rounded-lg" >
< p className = "text-xs text-slate-500" > Religion < / p >
< p className = "font-medium text-slate-700" > { ( investor as any ) . religion || '-' } < / p >
< / div >
< div className = "p-3 bg-slate-50 rounded-lg" >
< p className = "text-xs text-slate-500" > Nationality < / p >
< p className = "font-medium text-slate-700" > { ( investor as any ) . nationality || 'Bangladeshi' } < / p >
< / div >
2026-04-22 01:02:45 +06:00
< / div >
2026-05-14 13:54:02 +06:00
) }
< / SectionCard >
< SectionCard title = "Nominee Details" icon = { Heart } headerBg = "bg-orange-50" headerBorder = "border-orange-100" editKey = "nominee" editingSection = { editingSection } setEditingSection = { setEditingSection } onEdit = { ( ) = > setEditForm ( {
nomineeName : ( investor as any ) . nomineeName || '' ,
nomineeRelation : ( investor as any ) . nomineeRelation || '' ,
nomineeNid : ( investor as any ) . nomineeNid || '' ,
nomineePhone : ( investor as any ) . nomineePhone || '' ,
nomineeEmail : ( investor as any ) . nomineeEmail || '' ,
nomineeAddress : ( investor as any ) . nomineeAddress || '' ,
nomineeShare : ( investor as any ) . nomineeShare || ''
} ) } editForm = { editForm } setEditForm = { setEditForm } >
{ editingSection === 'nominee' ? (
< div className = "grid grid-cols-1 md:grid-cols-2 gap-3" >
< div >
< label className = "text-xs text-slate-500 mb-1 block" > Nominee Name < / label >
< input type = "text" value = { editForm . nomineeName || '' } onChange = { ( e ) = > setEditForm ( { . . . editForm , nomineeName : e.target.value } ) } className = "w-full px-3 py-2 border border-slate-200 rounded-lg text-sm" / >
< / div >
< div >
< label className = "text-xs text-slate-500 mb-1 block" > Relationship < / label >
< select value = { editForm . nomineeRelation || '' } onChange = { ( e ) = > setEditForm ( { . . . editForm , nomineeRelation : e.target.value } ) } className = "w-full px-3 py-2 border border-slate-200 rounded-lg text-sm" >
< option value = "" > Select < / option >
< option value = "Spouse" > Spouse < / option >
< option value = "Child" > Child < / option >
< option value = "Parent" > Parent < / option >
< option value = "Sibling" > Sibling < / option >
< option value = "Other" > Other < / option >
< / select >
< / div >
< div >
< label className = "text-xs text-slate-500 mb-1 block" > NID Number < / label >
< input type = "text" value = { editForm . nomineeNid || '' } onChange = { ( e ) = > setEditForm ( { . . . editForm , nomineeNid : e.target.value } ) } className = "w-full px-3 py-2 border border-slate-200 rounded-lg text-sm" / >
< / div >
< div >
< label className = "text-xs text-slate-500 mb-1 block" > Phone < / label >
< input type = "text" value = { editForm . nomineePhone || '' } onChange = { ( e ) = > setEditForm ( { . . . editForm , nomineePhone : e.target.value } ) } className = "w-full px-3 py-2 border border-slate-200 rounded-lg text-sm" / >
< / div >
< div >
< label className = "text-xs text-slate-500 mb-1 block" > Email < / label >
< input type = "email" value = { editForm . nomineeEmail || '' } onChange = { ( e ) = > setEditForm ( { . . . editForm , nomineeEmail : e.target.value } ) } className = "w-full px-3 py-2 border border-slate-200 rounded-lg text-sm" / >
< / div >
< div >
< label className = "text-xs text-slate-500 mb-1 block" > Share % < / label >
< input type = "number" value = { editForm . nomineeShare || '' } onChange = { ( e ) = > setEditForm ( { . . . editForm , nomineeShare : e.target.value } ) } className = "w-full px-3 py-2 border border-slate-200 rounded-lg text-sm" / >
< / div >
< div className = "md:col-span-2" >
< label className = "text-xs text-slate-500 mb-1 block" > Address < / label >
< input type = "text" value = { editForm . nomineeAddress || '' } onChange = { ( e ) = > setEditForm ( { . . . editForm , nomineeAddress : e.target.value } ) } className = "w-full px-3 py-2 border border-slate-200 rounded-lg text-sm" / >
< / div >
2026-04-22 01:02:45 +06:00
< / div >
2026-05-14 13:54:02 +06:00
) : (
< div className = "grid grid-cols-1 md:grid-cols-2 gap-3" >
< div className = "p-3 bg-slate-50 rounded-lg" >
< p className = "text-xs text-slate-500" > Nominee Name < / p >
< p className = "font-medium text-slate-700" > { ( investor as any ) . nomineeName || '-' } < / p >
< / div >
< div className = "p-3 bg-slate-50 rounded-lg" >
< p className = "text-xs text-slate-500" > Relationship < / p >
< p className = "font-medium text-slate-700" > { ( investor as any ) . nomineeRelation || '-' } < / p >
< / div >
< div className = "p-3 bg-slate-50 rounded-lg" >
< p className = "text-xs text-slate-500" > NID Number < / p >
< p className = "font-medium text-slate-700" > { ( investor as any ) . nomineeNid || '-' } < / p >
< / div >
< div className = "p-3 bg-slate-50 rounded-lg" >
< p className = "text-xs text-slate-500" > Phone < / p >
< p className = "font-medium text-slate-700" > { ( investor as any ) . nomineePhone || '-' } < / p >
< / div >
< div className = "p-3 bg-slate-50 rounded-lg" >
< p className = "text-xs text-slate-500" > Email < / p >
< p className = "font-medium text-slate-700" > { ( investor as any ) . nomineeEmail || '-' } < / p >
< / div >
< div className = "p-3 bg-slate-50 rounded-lg" >
< p className = "text-xs text-slate-500" > Share % < / p >
< p className = "font-medium text-slate-700" > { ( investor as any ) . nomineeShare || '-' } < / p >
< / div >
< div className = "p-3 bg-slate-50 rounded-lg md:col-span-2" >
< p className = "text-xs text-slate-500" > Address < / p >
< p className = "font-medium text-slate-700" > { ( investor as any ) . nomineeAddress || '-' } < / p >
< / div >
2026-04-22 01:02:45 +06:00
< / div >
2026-05-14 13:54:02 +06:00
) }
< / SectionCard >
< SectionCard title = "Emergency Contact" icon = { PhoneCall } headerBg = "bg-red-50" headerBorder = "border-red-100" editKey = "emergency" editingSection = { editingSection } setEditingSection = { setEditingSection } onEdit = { ( ) = > setEditForm ( {
emergencyName : investor.emergencyContactName || '' ,
emergencyRelation : investor.emergencyContactRelation || '' ,
emergencyPhone : investor.emergencyContactPhone || '' ,
emergencyEmail : ( investor as any ) . emergencyEmail || '' ,
emergencyAddress : ( investor as any ) . emergencyAddress || ''
} ) } editForm = { editForm } setEditForm = { setEditForm } >
{ editingSection === 'emergency' ? (
< div className = "grid grid-cols-1 md:grid-cols-2 gap-3" >
2026-04-22 01:02:45 +06:00
< div >
2026-05-14 13:54:02 +06:00
< label className = "text-xs text-slate-500 mb-1 block" > Contact Name < / label >
< input type = "text" value = { editForm . emergencyName || '' } onChange = { ( e ) = > setEditForm ( { . . . editForm , emergencyName : e.target.value } ) } className = "w-full px-3 py-2 border border-slate-200 rounded-lg text-sm" / >
< / div >
< div >
< label className = "text-xs text-slate-500 mb-1 block" > Relationship < / label >
< select value = { editForm . emergencyRelation || '' } onChange = { ( e ) = > setEditForm ( { . . . editForm , emergencyRelation : e.target.value } ) } className = "w-full px-3 py-2 border border-slate-200 rounded-lg text-sm" >
< option value = "" > Select < / option >
< option value = "Spouse" > Spouse < / option >
< option value = "Child" > Child < / option >
< option value = "Parent" > Parent < / option >
< option value = "Sibling" > Sibling < / option >
< option value = "Friend" > Friend < / option >
< option value = "Other" > Other < / option >
< / select >
< / div >
< div >
< label className = "text-xs text-slate-500 mb-1 block" > Phone < / label >
< input type = "text" value = { editForm . emergencyPhone || '' } onChange = { ( e ) = > setEditForm ( { . . . editForm , emergencyPhone : e.target.value } ) } className = "w-full px-3 py-2 border border-slate-200 rounded-lg text-sm" / >
< / div >
< div >
< label className = "text-xs text-slate-500 mb-1 block" > Email < / label >
< input type = "email" value = { editForm . emergencyEmail || '' } onChange = { ( e ) = > setEditForm ( { . . . editForm , emergencyEmail : e.target.value } ) } className = "w-full px-3 py-2 border border-slate-200 rounded-lg text-sm" / >
< / div >
< div className = "md:col-span-2" >
< label className = "text-xs text-slate-500 mb-1 block" > Address < / label >
< input type = "text" value = { editForm . emergencyAddress || '' } onChange = { ( e ) = > setEditForm ( { . . . editForm , emergencyAddress : 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-1 md:grid-cols-2 gap-3" >
< div className = "p-3 bg-slate-50 rounded-lg" >
< p className = "text-xs text-slate-500" > Contact Name < / p >
< p className = "font-medium text-slate-700" > { investor . emergencyContactName || '-' } < / p >
< / div >
< div className = "p-3 bg-slate-50 rounded-lg" >
< p className = "text-xs text-slate-500" > Relationship < / p >
< p className = "font-medium text-slate-700" > { investor . emergencyContactRelation || '-' } < / p >
< / div >
< div className = "p-3 bg-slate-50 rounded-lg" >
< p className = "text-xs text-slate-500" > Phone < / p >
< p className = "font-medium text-slate-700" > { investor . emergencyContactPhone || '-' } < / p >
< / div >
< div className = "p-3 bg-slate-50 rounded-lg" >
< p className = "text-xs text-slate-500" > Email < / p >
< p className = "font-medium text-slate-700" > { ( investor as any ) . emergencyEmail || '-' } < / p >
< / div >
< div className = "p-3 bg-slate-50 rounded-lg md:col-span-2" >
< p className = "text-xs text-slate-500" > Address < / p >
< p className = "font-medium text-slate-700" > { ( investor as any ) . emergencyAddress || '-' } < / p >
2026-04-22 01:02:45 +06:00
< / div >
< / div >
) }
2026-05-14 13:54:02 +06:00
< / SectionCard >
< / div >
< div className = "flex-1 space-y-4" >
< SectionCard title = "Investment Information" icon = { Briefcase } headerBg = "bg-blue-50" headerBorder = "border-blue-100" editKey = "investmentInfo" editingSection = { editingSection } setEditingSection = { setEditingSection } onEdit = { ( ) = > setEditForm ( {
companyName : ( investor as any ) . companyName || '' ,
monthlyIncome : ( investor as any ) . monthlyIncome || '' ,
investmentSource : ( investor as any ) . investmentSource || '' ,
profession : investor.occupation || ''
} ) } editForm = { editForm } setEditForm = { setEditForm } >
{ editingSection === 'investmentInfo' ? (
< div className = "grid grid-cols-1 md:grid-cols-2 gap-3" >
< div className = "md:col-span-2" >
< label className = "text-xs text-slate-500 mb-1 block" > Company / Business Name < / label >
< input type = "text" value = { editForm . companyName || '' } onChange = { ( e ) = > setEditForm ( { . . . editForm , companyName : e.target.value } ) } className = "w-full px-3 py-2 border border-slate-200 rounded-lg text-sm" / >
< / div >
2026-04-22 01:02:45 +06:00
< div >
2026-05-14 13:54:02 +06:00
< label className = "text-xs text-slate-500 mb-1 block" > Monthly Income ( ৳ ) < / label >
< input type = "number" value = { editForm . monthlyIncome || '' } onChange = { ( e ) = > setEditForm ( { . . . editForm , monthlyIncome : e.target.value } ) } className = "w-full px-3 py-2 border border-slate-200 rounded-lg text-sm" / >
< / div >
< div >
< label className = "text-xs text-slate-500 mb-1 block" > Investment Source < / label >
< input type = "text" value = { editForm . investmentSource || '' } onChange = { ( e ) = > setEditForm ( { . . . editForm , investmentSource : e.target.value } ) } className = "w-full px-3 py-2 border border-slate-200 rounded-lg text-sm" placeholder = "e.g., Savings, Business profit, Inheritance" / >
< / div >
< div className = "md:col-span-2" >
< label className = "text-xs text-slate-500 mb-1 block" > Profession / Occupation < / label >
< input type = "text" value = { editForm . profession || '' } onChange = { ( e ) = > setEditForm ( { . . . editForm , profession : e.target.value } ) } className = "w-full px-3 py-2 border border-slate-200 rounded-lg text-sm" / >
< / div >
< / div >
) : (
< div className = "space-y-2" >
< div className = "grid grid-cols-1 md:grid-cols-2 gap-2" >
< div className = "p-3 bg-slate-50 rounded-lg" >
< p className = "text-xs text-slate-500" > Company / Business Name < / p >
< p className = "font-medium text-slate-700" > { ( investor as any ) . companyName || '-' } < / p >
< / div >
< div className = "p-3 bg-slate-50 rounded-lg" >
< p className = "text-xs text-slate-500" > Monthly Income < / p >
< p className = "font-medium text-slate-700" > { ( investor as any ) . monthlyIncome || '-' } < / p >
< / div >
< div className = "p-3 bg-slate-50 rounded-lg" >
< p className = "text-xs text-slate-500" > Investment Source < / p >
< p className = "font-medium text-slate-700" > { ( investor as any ) . investmentSource || '-' } < / p >
< / div >
< div className = "p-3 bg-slate-50 rounded-lg" >
< p className = "text-xs text-slate-500" > Profession / Occupation < / p >
< p className = "font-medium text-slate-700" > { investor . occupation || '-' } < / p >
< / div >
2026-04-22 01:02:45 +06:00
< / div >
< / div >
) }
2026-05-14 13:54:02 +06:00
< / SectionCard >
< SectionCard title = "Present Address" icon = { Home } headerBg = "bg-green-50" headerBorder = "border-green-100" editKey = "presentAddress" editingSection = { editingSection } setEditingSection = { setEditingSection } onEdit = { ( ) = > {
const parts = investor . address . split ( ',' ) . map ( s = > s . trim ( ) ) ;
setEditForm ( {
addressLine1 : parts.slice ( 0 , 2 ) . join ( ', ' ) ,
addressLine2 : parts.slice ( 2 , 4 ) . join ( ', ' ) ,
division : parts [ 4 ] || 'Dhaka' ,
district : parts [ 5 ] || 'Dhaka' ,
thana : parts [ 3 ] || '' ,
zipCode : parts [ 6 ] || '' ,
landmark : parts [ 7 ] || ''
} ) ;
} } editForm = { editForm } setEditForm = { setEditForm } >
{ editingSection === 'presentAddress' ? (
< div className = "grid grid-cols-1 md:grid-cols-2 gap-3" >
< div className = "md:col-span-2" >
< label className = "text-xs text-slate-500 mb-1 block" > Address Line 1 ( House / Flat + Road ) < / label >
< input type = "text" value = { editForm . addressLine1 || '' } onChange = { ( e ) = > setEditForm ( { . . . editForm , addressLine1 : e.target.value } ) } className = "w-full px-3 py-2 border border-slate-200 rounded-lg text-sm" / >
< / div >
< div className = "md:col-span-2" >
< label className = "text-xs text-slate-500 mb-1 block" > Address Line 2 ( Block + Area ) < / label >
< input type = "text" value = { editForm . addressLine2 || '' } onChange = { ( e ) = > setEditForm ( { . . . editForm , addressLine2 : e.target.value } ) } className = "w-full px-3 py-2 border border-slate-200 rounded-lg text-sm" / >
< / div >
< div >
< label className = "text-xs text-slate-500 mb-1 block" > Division < / label >
< select value = { editForm . division || '' } onChange = { ( e ) = > setEditForm ( { . . . editForm , division : e.target.value } ) } className = "w-full px-3 py-2 border border-slate-200 rounded-lg text-sm" >
< option value = "Dhaka" > Dhaka < / option >
< option value = "Chittagong" > Chittagong < / option >
< option value = "Sylhet" > Sylhet < / option >
< option value = "Khulna" > Khulna < / option >
< option value = "Barisal" > Barisal < / option >
< option value = "Rangpur" > Rangpur < / option >
< option value = "Mymensingh" > Mymensingh < / option >
< / select >
< / div >
< div >
< label className = "text-xs text-slate-500 mb-1 block" > District < / label >
< select value = { editForm . district || '' } onChange = { ( e ) = > setEditForm ( { . . . editForm , district : e.target.value } ) } className = "w-full px-3 py-2 border border-slate-200 rounded-lg text-sm" >
< option value = "Dhaka" > Dhaka < / option >
< option value = "Gazipur" > Gazipur < / option >
< option value = "Narayanganj" > Narayanganj < / option >
< option value = "Tangail" > Tangail < / option >
< option value = "Kishoreganj" > Kishoreganj < / option >
< / select >
< / div >
< div >
< label className = "text-xs text-slate-500 mb-1 block" > Thana < / label >
< input type = "text" value = { editForm . thana || '' } onChange = { ( e ) = > setEditForm ( { . . . editForm , thana : e.target.value } ) } className = "w-full px-3 py-2 border border-slate-200 rounded-lg text-sm" / >
< / div >
2026-04-22 01:02:45 +06:00
< div >
2026-05-14 13:54:02 +06:00
< label className = "text-xs text-slate-500 mb-1 block" > Zip Code < / label >
< input type = "text" value = { editForm . zipCode || '' } onChange = { ( e ) = > setEditForm ( { . . . editForm , zipCode : e.target.value } ) } className = "w-full px-3 py-2 border border-slate-200 rounded-lg text-sm" / >
< / div >
< div className = "md:col-span-2" >
< label className = "text-xs text-slate-500 mb-1 block" > Landmark < / label >
< input type = "text" value = { editForm . landmark || '' } onChange = { ( e ) = > setEditForm ( { . . . editForm , landmark : e.target.value } ) } className = "w-full px-3 py-2 border border-slate-200 rounded-lg text-sm" / >
< / div >
< / div >
) : (
< div className = "space-y-2" >
< div className = "p-3 bg-slate-50 rounded-lg" >
< p className = "text-xs text-slate-500" > Address Line 1 < / p >
< p className = "font-medium text-slate-700" > { investor . address } < / p >
< / div >
< div className = "p-3 bg-slate-50 rounded-lg" >
< p className = "text-xs text-slate-500" > Landmark < / p >
< p className = "font-medium text-slate-700" > - < / p >
< / div >
< div className = "grid grid-cols-2 gap-2" >
< div className = "p-3 bg-slate-50 rounded-lg" >
< p className = "text-xs text-slate-500" > Division < / p >
< p className = "font-medium text-slate-700" > Dhaka < / p >
< / div >
< div className = "p-3 bg-slate-50 rounded-lg" >
< p className = "text-xs text-slate-500" > District < / p >
< p className = "font-medium text-slate-700" > Dhaka < / p >
< / div >
< div className = "p-3 bg-slate-50 rounded-lg" >
< p className = "text-xs text-slate-500" > Thana < / p >
< p className = "font-medium text-slate-700" > - < / p >
< / div >
< div className = "p-3 bg-slate-50 rounded-lg" >
< p className = "text-xs text-slate-500" > Zip Code < / p >
< p className = "font-medium text-slate-700" > 1205 < / p >
< / div >
2026-04-22 01:02:45 +06:00
< / div >
< / div >
) }
2026-05-14 13:54:02 +06:00
< / SectionCard >
2026-04-22 01:02:45 +06:00
2026-05-14 13:54:02 +06:00
< SectionCard title = "Permanent Address" icon = { Home } headerBg = "bg-emerald-50" headerBorder = "border-emerald-100" editKey = "permanentAddress" editingSection = { editingSection } setEditingSection = { setEditingSection } onEdit = { ( ) = > {
const parts = investor . address . split ( ',' ) . map ( s = > s . trim ( ) ) ;
setEditForm ( {
addressLine1 : parts.slice ( 0 , 2 ) . join ( ', ' ) ,
addressLine2 : parts.slice ( 2 , 4 ) . join ( ', ' ) ,
division : parts [ 4 ] || 'Dhaka' ,
district : parts [ 5 ] || 'Dhaka' ,
thana : parts [ 3 ] || '' ,
zipCode : parts [ 6 ] || '' ,
isSameAsPresent : true
} ) ;
} } editForm = { editForm } setEditForm = { setEditForm } >
{ editingSection === 'permanentAddress' ? (
2026-04-22 01:02:45 +06:00
< div >
2026-05-14 13:54:02 +06:00
< div className = "flex items-center gap-2 mb-4" >
< input type = "checkbox" id = "sameAsPresent" checked = { editForm . isSameAsPresent || false } onChange = { ( e ) = > setEditForm ( { . . . editForm , isSameAsPresent : e.target.checked } ) } className = "rounded text-investor" / >
< label htmlFor = "sameAsPresent" className = "text-sm text-slate-600" > Same as Present Address < / label >
< / div >
{ ! editForm . isSameAsPresent && (
< div className = "grid grid-cols-1 md:grid-cols-2 gap-3" >
< div className = "md:col-span-2" >
< label className = "text-xs text-slate-500 mb-1 block" > Address Line 1 ( House / Flat + Road ) < / label >
< input type = "text" value = { editForm . addressLine1 || '' } onChange = { ( e ) = > setEditForm ( { . . . editForm , addressLine1 : e.target.value } ) } className = "w-full px-3 py-2 border border-slate-200 rounded-lg text-sm" / >
< / div >
< div className = "md:col-span-2" >
< label className = "text-xs text-slate-500 mb-1 block" > Address Line 2 ( Block + Area ) < / label >
< input type = "text" value = { editForm . addressLine2 || '' } onChange = { ( e ) = > setEditForm ( { . . . editForm , addressLine2 : e.target.value } ) } className = "w-full px-3 py-2 border border-slate-200 rounded-lg text-sm" / >
< / div >
< div >
< label className = "text-xs text-slate-500 mb-1 block" > Division < / label >
< select value = { editForm . division || '' } onChange = { ( e ) = > setEditForm ( { . . . editForm , division : e.target.value } ) } className = "w-full px-3 py-2 border border-slate-200 rounded-lg text-sm" >
< option value = "Dhaka" > Dhaka < / option >
< option value = "Chittagong" > Chittagong < / option >
< option value = "Sylhet" > Sylhet < / option >
< option value = "Khulna" > Khulna < / option >
< option value = "Barisal" > Barisal < / option >
< option value = "Rangpur" > Rangpur < / option >
< option value = "Mymensingh" > Mymensingh < / option >
< / select >
< / div >
< div >
< label className = "text-xs text-slate-500 mb-1 block" > District < / label >
< select value = { editForm . district || '' } onChange = { ( e ) = > setEditForm ( { . . . editForm , district : e.target.value } ) } className = "w-full px-3 py-2 border border-slate-200 rounded-lg text-sm" >
< option value = "Dhaka" > Dhaka < / option >
< option value = "Gazipur" > Gazipur < / option >
< option value = "Narayanganj" > Narayanganj < / option >
< option value = "Tangail" > Tangail < / option >
< option value = "Kishoreganj" > Kishoreganj < / option >
< / select >
< / div >
< div >
< label className = "text-xs text-slate-500 mb-1 block" > Thana < / label >
< input type = "text" value = { editForm . thana || '' } onChange = { ( e ) = > setEditForm ( { . . . editForm , thana : e.target.value } ) } className = "w-full px-3 py-2 border border-slate-200 rounded-lg text-sm" / >
< / div >
< div >
< label className = "text-xs text-slate-500 mb-1 block" > Zip Code < / label >
< input type = "text" value = { editForm . zipCode || '' } onChange = { ( e ) = > setEditForm ( { . . . editForm , zipCode : e.target.value } ) } className = "w-full px-3 py-2 border border-slate-200 rounded-lg text-sm" / >
< / div >
< / div >
) }
2026-04-22 01:02:45 +06:00
< / div >
2026-05-14 13:54:02 +06:00
) : (
< div className = "space-y-2" >
< div className = "flex items-center gap-2 mb-2" >
< span className = "text-xs bg-blue-100 text-blue-700 px-2 py-1 rounded-full" > Same as Present < / span >
< / div >
< div className = "p-3 bg-slate-50 rounded-lg" >
< p className = "text-xs text-slate-500" > Address Line 1 < / p >
< p className = "font-medium text-slate-700" > { investor . address } < / p >
< / div >
< div className = "p-3 bg-slate-50 rounded-lg" >
< p className = "text-xs text-slate-500" > Landmark < / p >
< p className = "font-medium text-slate-700" > - < / p >
< / div >
< div className = "grid grid-cols-2 gap-2" >
< div className = "p-3 bg-slate-50 rounded-lg" >
< p className = "text-xs text-slate-500" > Division < / p >
< p className = "font-medium text-slate-700" > Dhaka < / p >
< / div >
< div className = "p-3 bg-slate-50 rounded-lg" >
< p className = "text-xs text-slate-500" > District < / p >
< p className = "font-medium text-slate-700" > Dhaka < / p >
< / div >
< div className = "p-3 bg-slate-50 rounded-lg" >
< p className = "text-xs text-slate-500" > Thana < / p >
< p className = "font-medium text-slate-700" > - < / p >
< / div >
< div className = "p-3 bg-slate-50 rounded-lg" >
< p className = "text-xs text-slate-500" > Zip Code < / p >
< p className = "font-medium text-slate-700" > 1205 < / p >
< / div >
2026-04-22 01:02:45 +06:00
< / div >
< / div >
) }
2026-05-14 13:54:02 +06:00
< / SectionCard >
2026-04-22 01:02:45 +06:00
< / div >
2026-05-14 13:54:02 +06:00
< / div >
2026-04-22 01:02:45 +06:00
{ 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" >
2026-05-14 19:49:57 +06:00
< div >
< 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 >
< / div >
2026-04-22 01:02:45 +06:00
< / div >
< div className = "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4" >
2026-05-14 19:49:57 +06:00
{ assignedBikes . map ( bike = > {
const investment = investor . investments ? . find ( ( inv : any ) = > inv . id === bike . investmentId ) ;
const planColors : Record < string , string > = {
silver : 'from-slate-400 to-slate-600' ,
gold : 'from-amber-400 to-amber-600' ,
platinum : 'from-purple-400 to-purple-600' ,
diamond : 'from-blue-400 to-blue-600' ,
} ;
const planBadges : Record < string , string > = {
silver : 'bg-slate-100 text-slate-600' ,
gold : 'bg-amber-100 text-amber-700' ,
platinum : 'bg-purple-100 text-purple-700' ,
diamond : 'bg-blue-100 text-blue-700' ,
} ;
const planBg : Record < string , string > = {
silver : 'bg-slate-50 border-slate-200' ,
gold : 'bg-amber-50 border-amber-200' ,
platinum : 'bg-purple-50 border-purple-200' ,
diamond : 'bg-blue-50 border-blue-200' ,
} ;
const rentalTypes : Record < string , { label : string ; color : string } > = {
single_rent : { label : 'Single Rent' , color : 'text-green-600' } ,
rent_to_own : { label : 'Rent to Own' , color : 'text-blue-600' } ,
share_ev : { label : 'Share EV' , color : 'text-purple-600' } ,
} ;
const statusConfig : Record < string , { bg : string ; color : string } > = {
rented : { bg : 'bg-green-100' , color : 'text-green-700' } ,
available : { bg : 'bg-blue-100' , color : 'text-blue-700' } ,
maintenance : { bg : 'bg-amber-100' , color : 'text-amber-700' } ,
retired : { bg : 'bg-slate-100' , color : 'text-slate-600' } ,
} ;
const rentalInfo = rentalTypes [ bike . rentalType || 'single_rent' ] ;
const planType = investment ? . planType || 'gold' ;
const status = statusConfig [ bike . status ] || statusConfig . available ;
return (
< Link
key = { bike . id }
href = { ` /bikes?bike= ${ bike . id } ` }
className = { ` block bg-white rounded-xl border ${ planBg [ planType ] } overflow-hidden hover:shadow-lg transition-all hover:scale-[1.02] cursor-pointer group ` }
>
< div className = { ` h-2 bg-gradient-to-r ${ planColors [ planType ] } ` } / >
< div className = "p-4" >
< div className = "flex items-start gap-3 mb-3" >
< div className = { ` w-12 h-12 rounded-xl bg-gradient-to-br ${ planColors [ planType ] } flex items-center justify-center shadow-sm ` } >
< Bike className = "w-6 h-6 text-white" / >
< / div >
< div className = "flex-1 min-w-0" >
< h4 className = "font-semibold text-slate-800 truncate" > { bike . model } < / h4 >
< p className = "text-sm text-slate-500" > { bike . brand } < / p >
< / div >
< span className = { ` px-2 py-1 rounded-full text-xs font-medium ${ status . bg } ${ status . color } capitalize ` } >
{ bike . status }
< / span >
2026-04-22 01:02:45 +06:00
< / div >
2026-05-14 19:49:57 +06:00
< div className = { ` inline-flex items-center gap-1.5 px-2.5 py-1 rounded-full text-xs font-medium ${ planBadges [ planType ] } capitalize mb-3 ` } >
< span className = { ` w-2 h-2 rounded-full ${
planType === 'silver' ? 'bg-slate-500' :
planType === 'gold' ? 'bg-amber-500' :
planType === 'platinum' ? 'bg-purple-500' : 'bg-blue-500'
} ` } />
{ planType } Plan • { investment ? . planName || 'Investment' }
< / div >
< div className = "grid grid-cols-2 gap-2 mb-3" >
< div className = "bg-white/80 rounded-lg p-2" >
< p className = "text-xs text-slate-400" > Plate < / p >
< p className = "text-sm font-medium text-slate-700 truncate" > { bike . plateNumber . split ( '-' ) . pop ( ) } < / p >
< / div >
< div className = "bg-white/80 rounded-lg p-2" >
< p className = "text-xs text-slate-400" > Location < / p >
< p className = "text-sm font-medium text-slate-700 truncate" > { bike . location } < / p >
< / div >
< / div >
< div className = "bg-white/80 rounded-lg p-3 space-y-2" >
< div className = "flex items-center justify-between" >
< span className = "text-xs text-slate-500" > Rental Type < / span >
< span className = { ` text-xs font-semibold ${ rentalInfo . color } ` } > { rentalInfo . label } < / span >
< / div >
< div className = "flex items-center justify-between" >
< span className = "text-xs text-slate-500" > Total Earnings < / span >
< span className = "text-sm font-bold text-green-600" > ৳ { bike . totalEarnings ? . toLocaleString ( ) || 0 } < / span >
< / div >
< div className = "flex items-center justify-between" >
< span className = "text-xs text-slate-500" > Battery < / span >
< span className = { ` text-xs font-medium ${
bike . batteryLevel > 50 ? 'text-green-600' :
bike . batteryLevel > 20 ? 'text-amber-600' : 'text-red-600'
} ` }>{bike.batteryLevel}%</span>
< / div >
2026-04-22 01:02:45 +06:00
< / div >
< / div >
2026-05-14 19:49:57 +06:00
< / Link >
) ;
} ) }
2026-04-22 01:02:45 +06:00
{ assignedBikes . length === 0 && (
2026-05-14 19:49:57 +06:00
< div className = "col-span-full text-center py-12 border-2 border-dashed border-slate-200 rounded-xl" >
< Bike className = "w-12 h-12 mx-auto mb-3 text-slate-300" / >
< p className = "text-slate-500" > No bikes assigned to this investor < / p >
< p className = "text-sm text-slate-400 mt-1" > Bikes will appear here once assigned to investments < / p >
2026-04-22 01:02:45 +06:00
< / div >
) }
< / div >
< / div >
) }
{ activeTab === 'investments' && (
< div className = "space-y-6" >
< div className = "flex items-center justify-between" >
2026-05-14 19:49:57 +06:00
< div >
< h3 className = "font-semibold text-slate-800" > Investment Plans < / h3 >
< p className = "text-sm text-slate-500" > Manage investment portfolios for this investor < / p >
< / 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" >
< Plus className = "w-4 h-4" / > Create Investment
2026-04-22 01:02:45 +06:00
< / button >
< / div >
2026-05-14 19:49:57 +06:00
< div className = "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4" >
{ investor . investments ? . map ( ( inv ) = > {
const planConfig : Record < string , { bg : string ; border : string ; icon : string } > = {
silver : { bg : 'bg-slate-100' , border : 'border-slate-300' , icon : 'text-slate-500' } ,
gold : { bg : 'bg-amber-100' , border : 'border-amber-300' , icon : 'text-amber-500' } ,
platinum : { bg : 'bg-purple-100' , border : 'border-purple-300' , icon : 'text-purple-500' } ,
diamond : { bg : 'bg-blue-100' , border : 'border-blue-300' , icon : 'text-blue-500' } ,
} ;
const style = planConfig [ inv . planType ] || planConfig . gold ;
return (
< div key = { inv . id } className = { ` bg-white rounded-xl border ${ style . border } overflow-hidden ` } >
< div className = { ` ${ style . bg } p-4 flex items-center justify-between ` } >
< div >
< h4 className = "font-semibold text-slate-800" > { inv . planName } < / h4 >
< p className = "text-sm text-slate-500 capitalize" > { inv . planType } Plan < / p >
< / div >
< span className = { ` text-xs font-medium px-2.5 py-1 rounded-full ${ inv . status === 'active' ? 'bg-green-100 text-green-700' : 'bg-slate-200 text-slate-600' } ` } >
{ inv . status }
< / span >
2026-04-22 01:02:45 +06:00
< / div >
2026-05-14 19:49:57 +06:00
< div className = "p-4 space-y-4" >
< div className = "grid grid-cols-2 gap-3" >
< div className = "bg-slate-50 rounded-lg p-3" >
< p className = "text-xs text-slate-500" > Investment < / p >
< p className = "font-bold text-slate-800" > ৳ { inv . totalInvestment . toLocaleString ( ) } < / p >
< / div >
< div className = "bg-purple-50 rounded-lg p-3" >
< p className = "text-xs text-purple-600" > Total Return < / p >
< p className = "font-bold text-purple-700" > ৳ { inv . actualEarnings . toLocaleString ( ) } < / p >
< / div >
< / div >
< div className = "bg-slate-50 rounded-lg p-3 space-y-1.5" >
< div className = "flex justify-between text-xs" >
< span className = "text-slate-400" > Duration < / span >
< span className = "font-medium" > 12 months < / span >
< / div >
< div className = "flex justify-between text-xs" >
< span className = "text-slate-400" > Lock - in Period < / span >
< span className = "font-medium" > 3 months < / span >
< / div >
< div className = "flex justify-between text-xs" >
< span className = "text-slate-400" > Early Exit Penalty < / span >
< span className = "font-medium text-red-500" > 10 % < / span >
< / div >
< / div >
< div className = "flex items-center justify-between text-sm" >
< span className = "text-slate-400" > { inv . startDate } - { inv . endDate || 'Ongoing' } < / span >
< span className = "capitalize text-slate-500" > { inv . paymentMethod } < / span >
< / div >
< div className = "pt-3 border-t border-slate-100" >
< p className = "text-xs text-slate-400 mb-2" > ID : # { inv . id ? . slice ( - 6 ) || 'N/A' } < / p >
< div className = "flex gap-2" >
< Link href = { ` /admin/investors/ ${ investor . id } /investments/ ${ inv . id } ` } className = "flex-1 py-2 text-sm font-medium text-slate-600 hover:bg-slate-50 rounded-lg border border-slate-200 text-center" >
View
< / Link >
< button className = "flex-1 py-2 text-sm font-medium text-investor hover:bg-investor/10 rounded-lg border border-investor/30" > Statement < / button >
< / div >
< / div >
2026-04-22 01:02:45 +06:00
< / div >
< / div >
2026-05-14 19:49:57 +06:00
) ;
} ) }
2026-04-22 01:02:45 +06:00
< / div >
2026-05-14 19:49:57 +06:00
{ ( ! investor . investments || investor . investments . length === 0 ) && (
< div className = "text-center py-16 bg-slate-50 rounded-xl border-2 border-dashed border-slate-200" >
< TrendingUp className = "w-12 h-12 mx-auto mb-3 text-slate-300" / >
< h4 className = "font-semibold text-slate-600 mb-2" > No Investments Yet < / h4 >
< p className = "text-slate-400 mb-4" > Create your first investment plan for this investor < / p >
< button onClick = { ( ) = > setShowCreateInvestmentModal ( true ) } className = "px-4 py-2 bg-investor text-white rounded-lg text-sm font-medium hover:bg-investor-dark" >
< Plus className = "w-4 h-4 inline mr-1" / > Create Investment
< / button >
< / div >
) }
2026-04-22 01:02:45 +06:00
< / 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" >
2026-05-14 20:15:39 +06:00
< h3 className = "font-semibold text-slate-800" > Bank Accounts ( { investor . bankAccounts ? . length || 0 } ) < / h3 >
2026-04-22 01:18:03 +06:00
< button onClick = { ( ) = > {
2026-05-14 20:15:39 +06:00
setEditingBankAccount ( { id : '' , bankName : '' , accountName : '' , accountNumber : '' , branch : '' , routing : '' , isPrimary : false } ) ;
2026-04-22 01:18:03 +06:00
setShowBankModal ( true ) ;
} } className = "text-sm text-investor hover:underline flex items-center gap-1" >
2026-05-14 20:15:39 +06:00
< Plus className = "w-4 h-4" / > Add Account
2026-04-22 01:18:03 +06:00
< / button >
< / div >
2026-04-22 01:02:45 +06:00
< div className = "space-y-3" >
2026-05-14 20:15:39 +06:00
{ investor . bankAccounts && investor . bankAccounts . length > 0 ? (
investor . bankAccounts . map ( ( account : any ) = > (
< div key = { account . id } className = "p-4 bg-white border border-slate-200 rounded-xl hover:shadow-md transition-all" >
< div className = "flex items-start justify-between mb-3" >
< div className = "flex items-center gap-3" >
< div className = { ` w-10 h-10 rounded-lg flex items-center justify-center ${ account . isPrimary ? 'bg-green-100' : 'bg-slate-100' } ` } >
< Banknote className = { ` w-5 h-5 ${ account . isPrimary ? 'text-green-600' : 'text-slate-500' } ` } / >
< / div >
< div >
< p className = "font-semibold text-slate-800" > { account . bankName } < / p >
< p className = "text-xs text-slate-500" > { account . branch } < / p >
< / div >
< / div >
< div className = "flex items-center gap-2" >
{ account . isPrimary && (
< span className = "px-2 py-1 bg-green-100 text-green-700 text-xs font-medium rounded-full" > Primary < / span >
) }
< button onClick = { ( ) = > {
setEditingBankAccount ( account ) ;
setShowBankModal ( true ) ;
} } className = "p-1.5 hover:bg-slate-100 rounded-lg text-slate-500" >
< Edit className = "w-4 h-4" / >
< / button >
< / div >
2026-04-22 01:18:03 +06:00
< / div >
2026-05-14 20:15:39 +06:00
< div className = "space-y-2 text-sm" >
< div className = "flex justify-between" >
< span className = "text-slate-500" > Account Name < / span >
< span className = "font-medium text-slate-700" > { account . accountName } < / span >
< / div >
< div className = "flex justify-between" >
< span className = "text-slate-500" > Account Number < / span >
< span className = "font-mono text-slate-700" > { account . accountNumber } < / span >
< / div >
{ account . routing && (
< div className = "flex justify-between" >
< span className = "text-slate-500" > Routing < / span >
< span className = "font-medium text-slate-700" > { account . routing } < / span >
< / div >
) }
2026-04-22 01:18:03 +06:00
< / div >
2026-04-22 01:02:45 +06:00
< / div >
2026-05-14 20:15:39 +06:00
) )
2026-04-22 01:18:03 +06:00
) : (
2026-05-14 20:15:39 +06:00
< div className = "text-center py-10 border-2 border-dashed border-slate-200 rounded-xl" >
< Banknote className = "w-10 h-10 mx-auto mb-3 text-slate-300" / >
< p className = "text-sm text-slate-500 mb-2" > No bank accounts added < / p >
< button onClick = { ( ) = > {
setEditingBankAccount ( { id : '' , bankName : '' , accountName : '' , accountNumber : '' , branch : '' , routing : '' , isPrimary : false } ) ;
setShowBankModal ( true ) ;
} } className = "px-4 py-2 text-sm bg-investor text-white rounded-lg hover:bg-investor-dark" >
Add First Account
< / button >
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" >
2026-05-14 13:54:02 +06:00
< 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'
} ` } />
2026-04-22 01:18:03 +06:00
< / div >
< div >
< p className = "text-sm font-medium text-slate-700" > { tx . description } < / p >
2026-04-26 14:56:12 +06:00
< div className = "flex items-center gap-2" >
< p className = "text-xs text-slate-400" > { tx . createdAt } < / p >
{ tx . referenceNumber && (
2026-05-14 13:54:02 +06:00
< button
2026-04-26 14:56:12 +06:00
onClick = { ( ) = > {
const getAccountingInfo = ( type : string , amount : number ) = > {
if ( type === 'investment' ) {
return {
debitAccount : 'Bank - City Bank (1200)' ,
creditAccount : 'Investor Liabilities (2200)' ,
amount : amount
} ;
} else if ( type === 'earning' || type === 'bike_earning' || type === 'investment_return' ) {
return {
debitAccount : 'Investor Liabilities (2200)' ,
creditAccount : 'Rental Income (4200)' ,
amount : amount
} ;
} else if ( type === 'withdrawal' ) {
return {
debitAccount : 'Investor Liabilities (2200)' ,
creditAccount : 'Bank - City Bank (1200)' ,
amount : amount
} ;
}
return {
debitAccount : 'N/A' ,
creditAccount : 'N/A' ,
amount : amount
} ;
} ;
const accounting = getAccountingInfo ( tx . type , tx . amount ) ;
setSelectedInvoice ( {
reference : tx.referenceNumber ,
date : tx.createdAt ,
type : tx . type ,
amount : tx.amount ,
description : tx.description ,
status : tx.status ,
investorName : investor.name ,
investorId : investor.id ,
debitAccount : accounting.debitAccount ,
creditAccount : accounting.creditAccount
} ) ;
setShowInvoiceModal ( true ) ;
} }
className = "text-xs text-investor hover:underline flex items-center gap-1"
>
• Ref : { tx . referenceNumber }
< BookOpen className = "w-3 h-3" / >
< / button >
) }
< / div >
2026-04-22 01:18:03 +06:00
< / div >
< / div >
< div className = "text-right" >
2026-05-14 13:54:02 +06:00
< p className = { ` text-sm font-medium ${ tx . type === 'earning' || tx . type === 'bike_earning' || tx . type === 'investment_return' || tx . type === 'referral_bonus' ? 'text-green-600' :
2026-04-22 01:18:03 +06:00
tx . type === 'withdrawal' || tx . type === 'penalty' || tx . type === 'adjustment' ? 'text-red-600' : 'text-blue-600'
2026-05-14 13:54:02 +06:00
} ` }>
2026-04-22 01:18:03 +06:00
{ 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 >
2026-05-14 13:54:02 +06:00
< 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'
} ` }>
2026-04-22 01:18:03 +06:00
{ 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 >
2026-05-14 13:54:02 +06:00
2026-04-22 01:18:03 +06:00
< 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-05-14 13:54:02 +06:00
< div className = { ` w-12 h-12 rounded-lg flex items-center justify-center ${ doc . type === 'nid' ? 'bg-blue-100' :
2026-04-22 01:18:03 +06:00
doc . type === 'passport' ? 'bg-purple-100' :
2026-05-14 13:54:02 +06:00
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' :
2026-04-22 01:18:03 +06:00
doc . type === 'passport' ? 'text-purple-600' :
2026-05-14 13:54:02 +06:00
doc . type === 'bank_statement' ? 'text-green-600' :
doc . type === 'tin_certificate' ? 'text-amber-600' : 'text-slate-600'
} ` } />
2026-04-22 01:18:03 +06:00
< / 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 >
2026-05-14 13:54:02 +06:00
< button onClick = { ( ) = > { if ( confirm ( 'Delete this document?' ) ) alert ( 'Document deleted' ) ; } } className = "p-2 hover:bg-red-50 rounded-lg" >
2026-04-22 01:18:03 +06:00
< 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" >
2026-05-14 13:54:02 +06:00
{ investor . kycStatus === 'verified'
2026-04-22 01:18:03 +06:00
? 'All documents have been verified. Investor is fully verified.'
: investor . kycStatus === 'pending'
2026-05-14 13:54:02 +06:00
? 'Documents are under review. Verification typically takes 24-48 hours.'
: 'Please upload required documents for verification.' }
2026-04-22 01:18:03 +06:00
< / 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 >
2026-05-14 13:54:02 +06:00
< select
2026-04-22 01:02:45 +06:00
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" >
2026-05-14 19:49:57 +06:00
< div className = "bg-white rounded-xl shadow-xl w-full max-w-3xl max-h-[90vh] overflow-hidden flex flex-col" >
2026-04-22 01:09:51 +06:00
< div className = "p-5 border-b border-slate-100 flex items-center justify-between" >
2026-05-14 19:49:57 +06:00
< div >
< h2 className = "text-lg font-bold text-slate-800" > Create New Investment < / h2 >
< p className = "text-sm text-slate-500" > Set up investment for { investor . name } < / p >
< / div >
2026-04-22 01:09:51 +06:00
< button onClick = { ( ) = > setShowCreateInvestmentModal ( false ) } className = "p-2 hover:bg-slate-100 rounded-lg" >
< X className = "w-5 h-5 text-slate-400" / >
< / button >
< / div >
2026-05-14 19:49:57 +06:00
< div className = "p-5 overflow-y-auto flex-1 space-y-5" >
< div >
< label className = "text-sm font-medium text-slate-600 mb-2 block" > Select Plan Template < / label >
< div className = "grid grid-cols-2 gap-3" >
{ [
{ id : 'inv_demo_1' , name : '1 Bike Plan' , tier : 'Economy' , evBasePrice : 200000 , minQuantity : 1 , duration : 12 , maxInvestment : 1000000 } ,
{ id : 'inv_demo_2' , name : '5 Bike Plan' , tier : 'Standard' , evBasePrice : 180000 , minQuantity : 5 , duration : 24 , maxInvestment : 5000000 } ,
] . map ( plan = > (
< button
key = { plan . id }
onClick = { ( ) = > {
setNewInvestment ( {
. . . newInvestment ,
planName : plan.name ,
planType : plan.tier.toLowerCase ( ) as any ,
totalInvestment : plan.evBasePrice * plan . minQuantity ,
monthlyReturn : 0
} ) ;
} }
className = { ` p-4 rounded-lg border-2 text-left transition-all ${ newInvestment . planName === plan . name ? 'border-investor bg-investor/5' : 'border-slate-200 hover:border-investor/50' } ` }
>
< p className = "font-semibold text-slate-800" > { plan . name } < / p >
< p className = "text-xs text-slate-500" > { plan . evBasePrice . toLocaleString ( ) } × { plan . minQuantity } bikes < / p >
< p className = "text-sm text-slate-600 mt-1" > Duration : { plan . duration } months < / p >
< / button >
) ) }
< / div >
< / div >
2026-04-22 01:09:51 +06:00
< div className = "grid grid-cols-2 gap-4" >
< div >
< label className = "text-sm font-medium text-slate-600 mb-1 block" > Plan Name * < / label >
2026-05-14 13:54:02 +06:00
< input
type = "text"
2026-04-22 01:09:51 +06:00
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"
2026-05-14 19:49:57 +06:00
placeholder = "Plan name"
2026-04-22 01:09:51 +06:00
/ >
< / div >
< div >
2026-05-14 19:49:57 +06:00
< label className = "text-sm font-medium text-slate-600 mb-1 block" > Plan Type < / label >
2026-05-14 13:54:02 +06:00
< select
2026-04-22 01:09:51 +06:00
value = { newInvestment . planType }
2026-05-14 19:49:57 +06:00
onChange = { ( e ) = > setNewInvestment ( { . . . newInvestment , planType : e.target.value as any } ) }
2026-04-22 01:09:51 +06:00
className = "w-full px-3 py-2 border border-slate-200 rounded-lg text-sm"
>
2026-05-14 19:49:57 +06:00
< option value = "silver" > Silver < / option >
< option value = "gold" > Gold < / option >
< option value = "platinum" > Platinum < / option >
< option value = "diamond" > Diamond < / option >
2026-04-22 01:09:51 +06:00
< / select >
< / div >
< / div >
2026-05-14 19:49:57 +06:00
< div className = "grid grid-cols-3 gap-4" >
< div >
< label className = "text-sm font-medium text-slate-600 mb-1 block" > EV Base Price ( ৳ ) < / label >
< input type = "number" value = { 200000 } className = "w-full px-3 py-2 border border-slate-200 rounded-lg text-sm bg-slate-50" / >
< / div >
< div >
< label className = "text-sm font-medium text-slate-600 mb-1 block" > Minimum Quantity ( Bikes ) < / label >
< input type = "number" value = { 1 } className = "w-full px-3 py-2 border border-slate-200 rounded-lg text-sm bg-slate-50" / >
< / div >
< div >
< label className = "text-sm font-medium text-slate-600 mb-1 block" > Min Investment ( ৳ ) < / label >
< input type = "number" value = { 200000 } disabled className = "w-full px-3 py-2 border border-slate-200 rounded-lg text-sm bg-slate-100 cursor-not-allowed" / >
< p className = "text-xs text-slate-400 mt-1" > = Qty × Base Price < / p >
2026-04-22 01:09:51 +06:00
< / div >
< / div >
2026-05-14 19:49:57 +06:00
< div className = "grid grid-cols-2 gap-4" >
2026-04-22 01:09:51 +06:00
< div >
< label className = "text-sm font-medium text-slate-600 mb-1 block" > Investment Amount ( ৳ ) * < / label >
2026-05-14 13:54:02 +06:00
< input
2026-04-22 01:09:51 +06:00
type = "number"
value = { newInvestment . totalInvestment }
2026-05-14 19:49:57 +06:00
onChange = { ( e ) = > setNewInvestment ( { . . . newInvestment , totalInvestment : Number ( e . target . value ) } ) }
className = "w-full px-3 py-2 border border-slate-200 rounded-lg text-sm bg-yellow-50"
2026-04-22 01:09:51 +06:00
/ >
< / div >
< div >
2026-05-14 19:49:57 +06:00
< label className = "text-sm font-medium text-slate-600 mb-1 block" > Max Investment ( ৳ ) < / label >
< input type = "number" value = { 1000000 } disabled className = "w-full px-3 py-2 border border-slate-200 rounded-lg text-sm bg-slate-100 cursor-not-allowed" / >
< / div >
< / div >
< div className = "grid grid-cols-3 gap-4" >
< div >
< label className = "text-sm font-medium text-slate-600 mb-1 block" > Duration ( Months ) < / label >
< input type = "number" value = { 12 } disabled className = "w-full px-3 py-2 border border-slate-200 rounded-lg text-sm bg-slate-100 cursor-not-allowed" / >
2026-04-22 01:09:51 +06:00
< / div >
< div >
2026-05-14 19:49:57 +06:00
< label className = "text-sm font-medium text-slate-600 mb-1 block" > Lock - in Period ( Months ) < / label >
< input type = "number" value = { 3 } disabled className = "w-full px-3 py-2 border border-slate-200 rounded-lg text-sm bg-slate-100 cursor-not-allowed" / >
< / div >
< div >
< label className = "text-sm font-medium text-slate-600 mb-1 block" > Early Exit Penalty ( % ) < / label >
< input type = "number" value = { 10 } disabled className = "w-full px-3 py-2 border border-slate-200 rounded-lg text-sm bg-slate-100 cursor-not-allowed" / >
< / div >
< / div >
< div className = "bg-amber-50 border border-amber-200 rounded-xl p-4" >
< h4 className = "text-sm font-semibold text-amber-800 mb-3 flex items-center gap-2" >
< TrendingUp className = "w-4 h-4" / >
FICO Share - Jaiben ' s Profit per Ride
< / h4 >
< p className = "text-xs text-amber-600 mb-3" > Profit sharing when bikes are rented to end customers < / p >
< div className = "grid grid-cols-3 gap-4" >
< div >
< label className = "text-xs text-slate-500 mb-1 block" > Single Rent ( % ) < / label >
< input type = "number" value = { 45 } disabled className = "w-full px-3 py-2 border border-amber-200 rounded-lg text-sm bg-white cursor-not-allowed" / >
< / div >
< div >
< label className = "text-xs text-slate-500 mb-1 block" > Rent to Own ( % ) < / label >
< input type = "number" value = { 55 } disabled className = "w-full px-3 py-2 border border-amber-200 rounded-lg text-sm bg-white cursor-not-allowed" / >
< / div >
< div >
< label className = "text-xs text-slate-500 mb-1 block" > Share an EV ( % ) < / label >
< input type = "number" value = { 60 } disabled className = "w-full px-3 py-2 border border-amber-200 rounded-lg text-sm bg-white cursor-not-allowed" / >
< / div >
2026-04-22 01:09:51 +06:00
< / 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 >
2026-05-14 13:54:02 +06:00
< input
2026-04-22 01:09:51 +06:00
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 >
2026-05-14 13:54:02 +06:00
< input
2026-04-22 01:09:51 +06:00
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 >
2026-05-14 19:49:57 +06:00
< label className = "text-sm font-medium text-slate-600 mb-1 block" > Payment Method < / label >
2026-05-14 13:54:02 +06:00
< select
2026-04-22 01:09:51 +06:00
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 >
2026-05-14 13:54:02 +06:00
< input
2026-04-22 01:09:51 +06:00
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 >
2026-05-14 19:49:57 +06:00
< label className = "text-sm font-medium text-slate-600 mb-1 block" > Description < / label >
2026-05-14 13:54:02 +06:00
< textarea
2026-04-22 01:09:51 +06:00
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 }
/ >
< / div >
2026-05-14 19:49:57 +06:00
< div className = "bg-green-50 border border-green-200 rounded-xl p-4" >
< h4 className = "font-semibold text-green-800 mb-3 flex items-center gap-2" >
< TrendingUp className = "w-4 h-4" / >
Auto - Journal Entry
< / h4 >
< div className = "bg-white rounded-lg p-4 border border-green-100" >
< div className = "flex items-center justify-between text-sm mb-2" >
< span className = "text-slate-500" > Date : < / span >
< span className = "font-medium" > { newInvestment . startDate || 'Not set' } < / span >
< / div >
< div className = "flex items-center justify-between text-sm mb-3" >
< span className = "text-slate-500" > Reference : < / span >
< span className = "font-medium" > { newInvestment . transactionReference || ` INV/ ${ new Date ( ) . getFullYear ( ) } /auto ` } < / span >
< / div >
< div className = "space-y-2" >
< div className = "flex items-center justify-between p-3 bg-green-50 rounded-lg border border-green-200" >
< div >
< p className = "text-xs text-green-600 font-medium uppercase" > Debit ( Dr ) < / p >
< p className = "font-medium text-slate-800" >
{ newInvestment . paymentMethod === 'bank' ? 'Bank - City Bank' : newInvestment . paymentMethod === 'cash' ? 'Cash in Hand' : 'bKash Business' } ( { newInvestment . paymentMethod === 'bank' ? '1200' : newInvestment . paymentMethod === 'cash' ? '1100' : '1300' } )
< / p >
2026-04-26 14:56:12 +06:00
< / div >
2026-05-14 19:49:57 +06:00
< p className = "font-bold text-green-700" > ৳ { newInvestment . totalInvestment . toLocaleString ( ) } < / p >
< / div >
< div className = "flex justify-center" >
< div className = "w-8 h-8 rounded-full bg-green-200 flex items-center justify-center" >
< span className = "text-green-600" > ▼ < / span >
2026-04-26 14:56:12 +06:00
< / div >
2026-05-14 19:49:57 +06:00
< / div >
< div className = "flex items-center justify-between p-3 bg-blue-50 rounded-lg border border-blue-200" >
< div >
< p className = "text-xs text-blue-600 font-medium uppercase" > Credit ( Cr ) < / p >
< p className = "font-medium text-slate-800" > Investor Liabilities ( 2200 ) < / p >
2026-04-26 14:56:12 +06:00
< / div >
2026-05-14 19:49:57 +06:00
< p className = "font-bold text-blue-700" > ৳ { newInvestment . totalInvestment . toLocaleString ( ) } < / p >
2026-04-26 14:56:12 +06:00
< / div >
< / div >
2026-05-14 19:49:57 +06:00
< / div >
< / div >
2026-04-22 01:09:51 +06:00
< / div >
< div className = "p-5 border-t border-slate-100 flex justify-end gap-3" >
2026-05-14 19:49:57 +06:00
< 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 >
2026-05-14 13:54:02 +06:00
< button
onClick = { handleCreateInvestment }
2026-04-22 01:09:51 +06:00
disabled = { ! newInvestment . planName || ! newInvestment . totalInvestment }
2026-05-14 19:49:57 +06:00
className = "px-4 py-2 bg-investor text-white rounded-lg text-sm font-medium hover:bg-investor-dark disabled:opacity-50 flex items-center gap-2"
2026-04-22 01:09:51 +06:00
>
2026-05-14 19:49:57 +06:00
< Plus className = "w-4 h-4" / > Create Investment
2026-04-22 01:09:51 +06:00
< / 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" >
2026-05-14 20:15:39 +06:00
< h2 className = "text-lg font-bold text-slate-800" > { editingBankAccount . id ? 'Edit' : 'Add' } Bank Account < / h2 >
2026-04-22 01:18:03 +06:00
< 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" >
2026-05-14 20:15:39 +06:00
{ bankSaveSuccess ? (
< div className = "text-center py-8" >
< div className = "w-16 h-16 bg-green-100 rounded-full flex items-center justify-center mx-auto mb-4" >
< Check className = "w-8 h-8 text-green-600" / >
< / div >
< h3 className = "text-lg font-bold text-slate-800 mb-2" > Bank Account Saved ! < / h3 >
< p className = "text-sm text-slate-500" >
{ editingBankAccount . isPrimary ? 'Primary account has been updated.' : 'Bank account has been saved successfully.' }
< / p >
< / div >
) : (
< >
< div >
< label className = "text-sm font-medium text-slate-600 mb-1 block" > Bank Name < span className = "text-red-500" > * < / span > < / label >
< input
type = "text"
value = { editingBankAccount . bankName }
onChange = { ( e ) = > {
setEditingBankAccount ( { . . . editingBankAccount , bankName : e.target.value } ) ;
setBankErrors ( { . . . bankErrors , bankName : '' } ) ;
} }
className = { ` w-full px-3 py-2 border rounded-lg text-sm ${ bankErrors . bankName ? 'border-red-300 bg-red-50' : 'border-slate-200' } ` }
placeholder = "e.g., Standard Chartered Bank"
/ >
{ bankErrors . bankName && < p className = "text-xs text-red-500 mt-1" > { bankErrors . bankName } < / p > }
< / div >
< div >
< label className = "text-sm font-medium text-slate-600 mb-1 block" > Branch < / label >
< input type = "text" value = { editingBankAccount . branch } onChange = { ( e ) = > setEditingBankAccount ( { . . . editingBankAccount , branch : 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 < span className = "text-red-500" > * < / span > < / label >
< input
type = "text"
value = { editingBankAccount . accountName }
onChange = { ( e ) = > {
setEditingBankAccount ( { . . . editingBankAccount , accountName : e.target.value } ) ;
setBankErrors ( { . . . bankErrors , accountName : '' } ) ;
} }
className = { ` w-full px-3 py-2 border rounded-lg text-sm ${ bankErrors . accountName ? 'border-red-300 bg-red-50' : 'border-slate-200' } ` }
placeholder = "Account holder name"
/ >
{ bankErrors . accountName && < p className = "text-xs text-red-500 mt-1" > { bankErrors . accountName } < / p > }
< / div >
< div >
< label className = "text-sm font-medium text-slate-600 mb-1 block" > Account Number < span className = "text-red-500" > * < / span > < / label >
< input
type = "text"
value = { editingBankAccount . accountNumber }
onChange = { ( e ) = > {
setEditingBankAccount ( { . . . editingBankAccount , accountNumber : e.target.value } ) ;
setBankErrors ( { . . . bankErrors , accountNumber : '' } ) ;
} }
className = { ` w-full px-3 py-2 border rounded-lg text-sm ${ bankErrors . accountNumber ? 'border-red-300 bg-red-50' : 'border-slate-200' } ` }
placeholder = "Account number"
/ >
{ bankErrors . accountNumber && < p className = "text-xs text-red-500 mt-1" > { bankErrors . accountNumber } < / p > }
< / div >
< div >
< label className = "text-sm font-medium text-slate-600 mb-1 block" > Routing Number < / label >
< input type = "text" value = { editingBankAccount . routing } onChange = { ( e ) = > setEditingBankAccount ( { . . . editingBankAccount , routing : e.target.value } ) } className = "w-full px-3 py-2 border border-slate-200 rounded-lg text-sm" placeholder = "Routing number" / >
< / div >
< div className = "flex items-center gap-3 p-3 bg-slate-50 rounded-lg" >
< input
type = "checkbox"
id = "isPrimary"
checked = { editingBankAccount . isPrimary }
onChange = { ( e ) = > setEditingBankAccount ( { . . . editingBankAccount , isPrimary : e.target.checked } ) }
className = "w-4 h-4 text-investor rounded border-slate-300"
/ >
< label htmlFor = "isPrimary" className = "text-sm text-slate-700" >
< span className = "font-medium" > Set as Primary Account < / span >
< p className = "text-xs text-slate-500" > Primary account will be used for withdrawals by default < / p >
< / label >
< / div >
< / >
) }
2026-04-22 01:18:03 +06:00
< / div >
< div className = "p-5 border-t border-slate-100 flex justify-between" >
2026-05-14 20:15:39 +06:00
{ bankSaveSuccess ? (
< div className = "flex gap-2 ml-auto" >
< button onClick = { ( ) = > { setShowBankModal ( false ) ; setBankSaveSuccess ( false ) ; } } className = "px-4 py-2 bg-investor text-white rounded-lg text-sm hover:bg-investor-dark" > Done < / button >
< / div >
) : (
< >
{ editingBankAccount . id && (
< button onClick = { ( ) = > setShowDeleteBankModal ( true ) } className = "px-4 py-2 border border-red-200 text-red-600 rounded-lg text-sm hover:bg-red-50 flex items-center gap-1" >
< Trash2 className = "w-4 h-4" / > 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 = { ( ) = > {
const errors : { bankName? : string ; accountName? : string ; accountNumber? : string } = { } ;
if ( ! editingBankAccount . bankName ) errors . bankName = 'Bank name is required' ;
if ( ! editingBankAccount . accountName ) errors . accountName = 'Account name is required' ;
if ( ! editingBankAccount . accountNumber ) errors . accountNumber = 'Account number is required' ;
if ( Object . keys ( errors ) . length > 0 ) {
setBankErrors ( errors ) ;
return ;
}
setBankErrors ( { } ) ;
setBankSaveSuccess ( true ) ;
} } className = "px-4 py-2 bg-investor text-white rounded-lg text-sm hover:bg-investor-dark" > Save < / button >
< / div >
< / >
2026-04-22 01:18:03 +06:00
) }
< / 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 >
) }
2026-05-14 20:15:39 +06:00
{ showDeleteBankModal && (
< div className = "fixed inset-0 bg-black/50 flex items-center justify-center z-[60] 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" >
< h3 className = "text-lg font-bold text-slate-800 flex items-center gap-2" >
< Trash2 className = "w-5 h-5 text-red-500" / > Delete Bank Account
< / h3 >
< button onClick = { ( ) = > setShowDeleteBankModal ( 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" >
< p className = "text-slate-600 mb-4" > Are you sure you want to delete this bank account ? < / p >
< div className = "bg-slate-50 rounded-lg p-4 space-y-2" >
< div className = "flex justify-between" >
< span className = "text-slate-500" > Bank < / span >
< span className = "font-medium" > { editingBankAccount . bankName } < / span >
< / div >
< div className = "flex justify-between" >
< span className = "text-slate-500" > Account < / span >
< span className = "font-mono" > { editingBankAccount . accountNumber } < / span >
< / div >
< / div >
{ editingBankAccount . isPrimary && (
< div className = "mt-3 p-3 bg-amber-50 border border-amber-200 rounded-lg flex items-center gap-2" >
< AlertTriangle className = "w-5 h-5 text-amber-600" / >
< p className = "text-sm text-amber-700" > This is the primary account . Deleting it may affect withdrawal settings . < / p >
< / div >
) }
< / div >
< div className = "p-5 border-t border-slate-100 flex justify-end gap-3" >
< button onClick = { ( ) = > setShowDeleteBankModal ( 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 = { ( ) = > {
console . log ( 'Deleting bank account:' , editingBankAccount . id ) ;
setShowDeleteBankModal ( false ) ;
setShowBankModal ( false ) ;
} }
className = "px-4 py-2 bg-red-500 text-white rounded-lg text-sm font-medium hover:bg-red-600"
>
Delete Account
< / button >
< / div >
< / div >
< / div >
) }
2026-04-22 01:18:03 +06:00
{ 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-26 14:56:12 +06:00
{ showJournalModal && (
< 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" > Journal Records < / h2 >
< button onClick = { ( ) = > setShowJournalModal ( 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" >
{ investorJournals . length > 0 ? (
< div className = "space-y-3" >
{ investorJournals . map ( ( journal , idx ) = > (
< div key = { idx } className = "bg-slate-50 rounded-lg p-4 border border-slate-200" >
< div className = "flex items-center justify-between mb-3" >
< div className = "flex items-center gap-2" >
< span className = "text-xs font-mono text-slate-500" > { journal . reference } < / span >
< span className = "text-xs px-2 py-0.5 rounded-full bg-green-100 text-green-700" > Auto < / span >
< / div >
< span className = "text-xs text-slate-500" > { journal . date } < / span >
< / div >
< div className = "space-y-2" >
< div className = "flex items-center justify-between bg-white p-2 rounded border border-slate-200" >
< div >
< p className = "text-sm font-medium" > Debit ( Dr ) < / p >
< p className = "text-xs text-slate-500" > Bank - City Bank ( 1200 ) < / p >
< / div >
< p className = "font-bold text-green-600" > ৳ { journal . amount . toLocaleString ( ) } < / p >
< / div >
< div className = "flex items-center justify-center py-0.5" >
< ArrowRight className = "w-4 h-4 text-slate-400 rotate-90" / >
< / div >
< div className = "flex items-center justify-between bg-white p-2 rounded border border-slate-200" >
< div >
< p className = "text-sm font-medium" > Credit ( Cr ) < / p >
< p className = "text-xs text-slate-500" > Investor Liabilities ( 2200 ) < / p >
< / div >
< p className = "font-bold text-red-600" > ৳ { journal . amount . toLocaleString ( ) } < / p >
< / div >
< / div >
< div className = "mt-2 pt-2 border-t border-slate-200 text-xs text-slate-500" >
{ journal . description }
< / div >
< / div >
) ) }
< / div >
) : (
< div className = "text-center py-8 text-slate-400" >
< BookOpen className = "w-12 h-12 mx-auto mb-2 opacity-50" / >
< p > No journal records yet < / p >
< p className = "text-sm" > Create an investment to see auto - journal entries < / p >
< / div >
) }
< / div >
< / div >
< / div >
) }
{ showInvoiceModal && selectedInvoice && (
< 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-lg" >
< div className = "p-5 border-b border-slate-100 flex items-center justify-between" >
< h2 className = "text-lg font-bold text-slate-800" > Invoice < / h2 >
< button onClick = { ( ) = > setShowInvoiceModal ( false ) } className = "p-2 hover:bg-slate-100 rounded-lg" >
< X className = "w-5 h-5 text-slate-400" / >
< / button >
< / div >
2026-05-14 13:54:02 +06:00
2026-04-26 14:56:12 +06:00
< div className = "p-6" id = "invoice-content" >
< 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 >
< p className = "text-xs text-slate-500" > EV Rental & Investment Company < / p >
< / div >
2026-05-14 13:54:02 +06:00
2026-04-26 14:56:12 +06:00
< div className = "flex justify-between mb-4" >
< div >
< p className = "text-xs text-slate-500" > Invoice No < / p >
< p className = "text-sm font-medium" > { selectedInvoice . reference } < / p >
< / div >
< div className = "text-right" >
< p className = "text-xs text-slate-500" > Date < / p >
< p className = "text-sm font-medium" > { selectedInvoice . date } < / p >
< / div >
< / div >
2026-05-14 13:54:02 +06:00
2026-04-26 14:56:12 +06:00
< div className = "mb-4" >
< p className = "text-xs text-slate-500" > Investor < / p >
< p className = "text-sm font-medium" > { selectedInvoice . investorName } < / p >
< p className = "text-xs text-slate-400" > { selectedInvoice . investorId } < / p >
< / div >
2026-05-14 13:54:02 +06:00
2026-04-26 14:56:12 +06:00
< table className = "w-full mb-4" >
< thead >
< tr className = "border-b border-slate-200" >
< th className = "text-left py-2 text-xs text-slate-500" > Description < / th >
< th className = "text-right py-2 text-xs text-slate-500" > Amount < / th >
< / tr >
< / thead >
< tbody >
< tr className = "border-b border-slate-100" >
< td className = "py-3 text-sm" > { selectedInvoice . description } < / td >
< td className = "py-3 text-sm text-right font-medium" > ৳ { selectedInvoice . amount . toLocaleString ( ) } < / td >
< / tr >
< / tbody >
< tfoot >
< tr >
< td className = "py-2 text-sm font-medium" > Total < / td >
< td className = "py-2 text-sm font-bold text-right" > ৳ { selectedInvoice . amount . toLocaleString ( ) } < / td >
< / tr >
< / tfoot >
< / table >
2026-05-14 13:54:02 +06:00
2026-04-26 14:56:12 +06:00
< div className = "flex justify-between mb-2" >
< span className = "text-xs text-slate-500" > Status < / span >
2026-05-14 13:54:02 +06:00
< span className = { ` text-xs px-2 py-1 rounded-full ${ selectedInvoice . status === 'completed' ? 'bg-green-100 text-green-700' :
2026-04-26 14:56:12 +06:00
selectedInvoice . status === 'pending' ? 'bg-amber-100 text-amber-700' : 'bg-slate-100 text-slate-700'
2026-05-14 13:54:02 +06:00
} ` }>
2026-04-26 14:56:12 +06:00
{ selectedInvoice . status }
< / span >
< / div >
2026-05-14 13:54:02 +06:00
2026-04-26 14:56:12 +06:00
< 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 >
< div className = "bg-slate-50 rounded-lg p-3 border border-slate-200" >
< div className = "flex items-center justify-between mb-2" >
< div >
< p className = "text-xs font-medium" > Debit ( Dr ) < / p >
< p className = "text-xs text-slate-500" > { selectedInvoice . debitAccount || 'N/A' } < / p >
< / div >
< p className = "text-sm font-bold" > ৳ { selectedInvoice . amount . toLocaleString ( ) } < / p >
< / div >
< div className = "flex items-center justify-center py-1" >
< ArrowRight className = "w-4 h-4 text-slate-400 rotate-90" / >
< / div >
< div className = "flex items-center justify-between" >
< div >
< p className = "text-xs font-medium" > Credit ( Cr ) < / p >
< p className = "text-xs text-slate-500" > { selectedInvoice . creditAccount || 'N/A' } < / p >
< / div >
< p className = "text-sm font-bold" > ৳ { selectedInvoice . amount . toLocaleString ( ) } < / p >
< / div >
< / div >
< / div >
2026-05-14 13:54:02 +06:00
2026-04-26 14:56:12 +06:00
< 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" > Generated on { new Date ( ) . toLocaleDateString ( ) } < / p >
< / div >
< / div >
2026-05-14 13:54:02 +06:00
2026-04-26 14:56:12 +06:00
< div className = "p-5 border-t border-slate-100 flex justify-between" >
2026-05-14 13:54:02 +06:00
< button
onClick = { ( ) = > window . print ( ) }
2026-04-26 14:56:12 +06:00
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
< / button >
2026-05-14 13:54:02 +06:00
< button
2026-04-26 14:56:12 +06:00
onClick = { ( ) = > {
import ( 'jspdf' ) . then ( jsPDF = > {
const doc = new jsPDF . default ( ) ;
doc . setFontSize ( 18 ) ;
doc . setTextColor ( 6 , 95 , 70 ) ;
doc . text ( 'JAIBEN Mobility Ltd' , 20 , 20 ) ;
doc . setFontSize ( 12 ) ;
doc . setTextColor ( 0 ) ;
doc . text ( 'Invoice: ' + selectedInvoice . reference , 20 , 30 ) ;
doc . text ( 'Date: ' + selectedInvoice . date , 20 , 38 ) ;
doc . text ( 'Investor: ' + selectedInvoice . investorName , 20 , 46 ) ;
doc . text ( 'Description: ' + selectedInvoice . description , 20 , 54 ) ;
doc . text ( 'Amount: ৳' + selectedInvoice . amount . toLocaleString ( ) , 20 , 64 ) ;
doc . text ( 'Status: ' + selectedInvoice . status , 20 , 72 ) ;
if ( selectedInvoice . debitAccount ) {
doc . setFontSize ( 10 ) ;
doc . setTextColor ( 100 ) ;
doc . text ( 'Double Entry Accounting:' , 20 , 85 ) ;
doc . text ( 'Dr: ' + selectedInvoice . debitAccount + ' ৳' + selectedInvoice . amount . toLocaleString ( ) , 20 , 93 ) ;
doc . text ( 'Cr: ' + selectedInvoice . creditAccount + ' ৳' + selectedInvoice . amount . toLocaleString ( ) , 20 , 101 ) ;
}
doc . setFontSize ( 9 ) ;
doc . setTextColor ( 150 ) ;
doc . text ( 'Thank you for your investment!' , 20 , 115 ) ;
doc . save ( ` invoice- ${ selectedInvoice . reference } .pdf ` ) ;
} ) ;
2026-05-14 13:54:02 +06:00
} }
2026-04-26 14:56:12 +06:00
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
< / button >
< button onClick = { ( ) = > setShowInvoiceModal ( false ) } className = "px-4 py-2 border border-slate-200 text-slate-600 rounded-lg text-sm hover:bg-slate-50" > Close < / button >
< / div >
< / div >
< / div >
) }
2026-05-14 19:49:57 +06:00
{ showInvestmentSuccessModal && lastCreatedInvestment && (
< 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-lg" >
< div className = "p-5 border-b border-slate-100 flex items-center justify-between bg-green-50" >
< div className = "flex items-center gap-3" >
< div className = "w-12 h-12 bg-green-100 rounded-full flex items-center justify-center" >
< Check className = "w-6 h-6 text-green-600" / >
< / div >
< div >
< h2 className = "text-lg font-bold text-green-800" > Investment Created ! < / h2 >
< p className = "text-sm text-green-600" > Auto - journal entry generated < / p >
< / div >
< / div >
< button onClick = { ( ) = > setShowInvestmentSuccessModal ( false ) } className = "p-2 hover:bg-green-100 rounded-lg" >
< X className = "w-5 h-5 text-green-400" / >
< / button >
< / div >
< div className = "p-5 space-y-4" >
< div className = "bg-slate-50 rounded-lg p-4 space-y-2" >
< div className = "flex justify-between" >
< span className = "text-sm text-slate-500" > Investment ID < / span >
< span className = "text-sm font-medium" > # { lastCreatedInvestment . id . slice ( - 8 ) } < / span >
< / div >
< div className = "flex justify-between" >
< span className = "text-sm text-slate-500" > Transaction Ref < / span >
< span className = "text-sm font-medium" > { lastCreatedInvestment . transactionId } < / span >
< / div >
< div className = "flex justify-between" >
< span className = "text-sm text-slate-500" > Amount < / span >
< span className = "text-sm font-bold text-green-600" > ৳ { lastCreatedInvestment . totalInvestment . toLocaleString ( ) } < / span >
< / div >
< div className = "flex justify-between" >
< span className = "text-sm text-slate-500" > Plan < / span >
< span className = "text-sm font-medium" > { lastCreatedInvestment . planName } < / span >
< / div >
< div className = "flex justify-between" >
< span className = "text-sm text-slate-500" > Date < / span >
< span className = "text-sm font-medium" > { lastCreatedInvestment . startDate } < / span >
< / div >
< / div >
< div className = "bg-green-50 border border-green-200 rounded-xl p-4" >
< h4 className = "text-sm font-semibold text-green-800 mb-3 flex items-center gap-2" >
< FileText className = "w-4 h-4" / >
Auto - Journal Entry
< / h4 >
< div className = "bg-white rounded-lg p-3 border border-green-100" >
< div className = "space-y-2" >
< div className = "flex items-center justify-between p-2 bg-green-50 rounded border border-green-200" >
< div >
< p className = "text-xs text-green-600 font-medium uppercase" > Debit ( Dr ) < / p >
< p className = "text-sm font-medium text-slate-800" > { lastCreatedInvestment . debitAccount ? . name } < / p >
< p className = "text-xs text-slate-400" > { lastCreatedInvestment . debitAccount ? . code } < / p >
< / div >
< p className = "font-bold text-green-700" > ৳ { lastCreatedInvestment . totalInvestment . toLocaleString ( ) } < / p >
< / div >
< div className = "flex justify-center" >
< div className = "w-6 h-6 rounded-full bg-green-200 flex items-center justify-center" >
< span className = "text-green-600 text-xs" > ▼ < / span >
< / div >
< / div >
< div className = "flex items-center justify-between p-2 bg-blue-50 rounded border border-blue-200" >
< div >
< p className = "text-xs text-blue-600 font-medium uppercase" > Credit ( Cr ) < / p >
< p className = "text-sm font-medium text-slate-800" > Investor Liabilities < / p >
< p className = "text-xs text-slate-400" > 2200 < / p >
< / div >
< p className = "font-bold text-blue-700" > ৳ { lastCreatedInvestment . totalInvestment . toLocaleString ( ) } < / p >
< / div >
< / div >
< / div >
< / div >
< / div >
< div className = "p-5 border-t border-slate-100 flex justify-end gap-3" >
< button onClick = { ( ) = > setShowInvestmentSuccessModal ( false ) } className = "px-4 py-2 bg-green-600 text-white rounded-lg text-sm font-medium hover:bg-green-700 flex items-center gap-2" >
< Check className = "w-4 h-4" / > Done
< / button >
< / div >
< / div >
< / div >
) }
2026-04-22 01:02:45 +06:00
< / div >
) ;
}