2026-05-15 01:25:48 +06:00
|
|
|
'use client';
|
|
|
|
|
|
|
|
|
|
import { useState } from 'react';
|
|
|
|
|
import {
|
|
|
|
|
Camera, Save, CheckCircle, Upload, Plus, Trash2,
|
|
|
|
|
ShieldCheck, CreditCard, Building2, Smartphone, User, MapPin, Phone, Briefcase,
|
|
|
|
|
Calendar, Mail, FileText, ChevronRight, Edit, Heart, PhoneCall, X, Eye, EyeOff,
|
|
|
|
|
Lock, Key, Shield, Activity, LogOut, AlertCircle, Trash, Pencil, Home,
|
|
|
|
|
Banknote,
|
|
|
|
|
TrashIcon
|
|
|
|
|
} from 'lucide-react';
|
|
|
|
|
import { investors } from '@/data/mockData';
|
|
|
|
|
import toast from 'react-hot-toast';
|
2026-05-15 17:56:16 +06:00
|
|
|
import InvestorNotification from '@/components/InvestorNotification';
|
2026-05-19 16:00:27 +06:00
|
|
|
import { logout } from '@/lib/auth';
|
|
|
|
|
|
2026-05-15 01:25:48 +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>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export default function InvestorProfilePage() {
|
|
|
|
|
const investor = investors.find(i => i.id === 'inv1') || investors[0];
|
|
|
|
|
const [activeTab, setActiveTab] = useState('personal');
|
|
|
|
|
const [editingSection, setEditingSection] = useState<string | null>(null);
|
|
|
|
|
const [editForm, setEditForm] = useState<any>({});
|
|
|
|
|
const [showPassword, setShowPassword] = useState({ current: false, new: false, confirm: false });
|
|
|
|
|
const [passwordForm, setPasswordForm] = useState({ current: '', new: '', confirm: '' });
|
|
|
|
|
const [twoFactorEnabled, setTwoFactorEnabled] = useState(false);
|
2026-05-15 02:16:32 +06:00
|
|
|
const [showUploadDocModal, setShowUploadDocModal] = useState(false);
|
|
|
|
|
const [uploadDocForm, setUploadDocForm] = useState({ docType: '', docNumber: '', docFile: null as File | null });
|
2026-05-15 01:25:48 +06:00
|
|
|
|
2026-05-19 20:45:10 +06:00
|
|
|
const [showApprovalModal, setShowApprovalModal] = useState(false);
|
|
|
|
|
const [approvalModalConfig, setApprovalModalConfig] = useState({ actionType: '', fieldName: '' });
|
|
|
|
|
|
|
|
|
|
const triggerApprovalRequest = (actionType: string, fieldName: string) => {
|
|
|
|
|
setApprovalModalConfig({ actionType, fieldName });
|
|
|
|
|
setShowApprovalModal(true);
|
|
|
|
|
};
|
|
|
|
|
|
2026-05-15 01:25:48 +06:00
|
|
|
const [showAddBankModal, setShowAddBankModal] = useState(false);
|
|
|
|
|
const [showEditBankModal, setShowEditBankModal] = useState(false);
|
|
|
|
|
const [showDeleteBankModal, setShowDeleteBankModal] = useState(false);
|
|
|
|
|
const [editingBank, setEditingBank] = useState<any>({ id: '', bankName: '', accountName: '', accountNumber: '', branch: '', routing: '', isPrimary: false });
|
|
|
|
|
const [bankToDelete, setBankToDelete] = useState<any>(null);
|
|
|
|
|
|
|
|
|
|
const [showAddMobileModal, setShowAddMobileModal] = useState(false);
|
|
|
|
|
const [showEditMobileModal, setShowEditMobileModal] = useState(false);
|
|
|
|
|
const [showDeleteMobileModal, setShowDeleteMobileModal] = useState(false);
|
|
|
|
|
const [showTaxModal, setShowTaxModal] = useState(false);
|
|
|
|
|
const [editingMobile, setEditingMobile] = useState({ provider: '', number: '', isPrimary: false });
|
|
|
|
|
const [editingMobileIndex, setEditingMobileIndex] = useState<number | null>(null);
|
|
|
|
|
const [editingTax, setEditingTax] = useState({ tinNumber: '', passportNumber: '' });
|
|
|
|
|
const [mobileToDelete, setMobileToDelete] = useState<any>(null);
|
|
|
|
|
|
|
|
|
|
const [newBankForm, setNewBankForm] = useState({ bankName: '', accountName: '', accountNumber: '', branch: '', routing: '', isPrimary: false });
|
|
|
|
|
const [newMobileForm, setNewMobileForm] = useState({ provider: '', number: '' });
|
|
|
|
|
|
|
|
|
|
const currentBalance = investor.totalEarnings - investor.totalWithdrawn - investor.pendingEarnings;
|
|
|
|
|
|
|
|
|
|
const sessionHistory = [
|
|
|
|
|
{ id: 1, device: 'iPhone 14 Pro', location: 'Dhaka, Bangladesh', time: '2 hours ago', current: true },
|
|
|
|
|
{ id: 2, device: 'Chrome on Windows', location: 'Dhaka, Bangladesh', time: '2 days ago', current: false },
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
const handlePasswordChange = () => {
|
|
|
|
|
if (passwordForm.new !== passwordForm.confirm) {
|
|
|
|
|
toast.error('Passwords do not match!');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (passwordForm.new.length < 8) {
|
|
|
|
|
toast.error('Password must be at least 8 characters!');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
toast.success('Password changed successfully!');
|
|
|
|
|
setPasswordForm({ current: '', new: '', confirm: '' });
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const handleSaveBank = () => {
|
|
|
|
|
setShowAddBankModal(false);
|
|
|
|
|
setShowEditBankModal(false);
|
|
|
|
|
setNewBankForm({ bankName: '', accountName: '', accountNumber: '', branch: '', routing: '', isPrimary: false });
|
2026-05-19 20:45:10 +06:00
|
|
|
triggerApprovalRequest('save/edit', 'Bank Account');
|
2026-05-15 01:25:48 +06:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const handleDeleteBank = () => {
|
|
|
|
|
setShowDeleteBankModal(false);
|
2026-05-19 20:45:10 +06:00
|
|
|
triggerApprovalRequest('delete', 'Bank Account');
|
2026-05-15 01:25:48 +06:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const handleSaveMobile = () => {
|
|
|
|
|
setShowAddMobileModal(false);
|
|
|
|
|
setShowEditMobileModal(false);
|
|
|
|
|
setNewMobileForm({ provider: '', number: '' });
|
2026-05-19 20:45:10 +06:00
|
|
|
triggerApprovalRequest('save/edit', 'Mobile Banking Account');
|
2026-05-15 01:25:48 +06:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const handleDeleteMobile = () => {
|
|
|
|
|
setShowDeleteMobileModal(false);
|
2026-05-19 20:45:10 +06:00
|
|
|
triggerApprovalRequest('delete', 'Mobile Banking Account');
|
2026-05-15 01:25:48 +06:00
|
|
|
};
|
|
|
|
|
|
2026-05-19 16:00:27 +06:00
|
|
|
const handleLogout = () => {
|
|
|
|
|
logout();
|
|
|
|
|
window.location.href = '/login';
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
2026-05-15 01:25:48 +06:00
|
|
|
const tabs = [
|
|
|
|
|
{ id: 'personal', label: 'Personal Info', icon: User },
|
|
|
|
|
{ id: 'nominee', label: 'Nominee & Emergency', icon: Heart },
|
|
|
|
|
{ id: 'financial', label: 'Financial', icon: CreditCard },
|
|
|
|
|
{ id: 'kyc', label: 'KYC', icon: FileText },
|
|
|
|
|
{ id: 'security', label: 'Security', icon: Lock },
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
return (
|
2026-05-15 18:07:15 +06:00
|
|
|
<div className="min-h-screen lg:pt-6 pt-0">
|
2026-05-15 17:56:16 +06:00
|
|
|
<InvestorNotification isMobile />
|
|
|
|
|
<div className="pt-18 lg:pt-0 p-4 sm:p-5 bg-slate-50 min-h-screen">
|
2026-05-15 18:25:29 +06:00
|
|
|
<div className="max-w-8xl mx-auto mb-12 lg:mb-0">
|
2026-05-15 17:56:16 +06:00
|
|
|
{/* Profile Header */}
|
|
|
|
|
<div className="bg-white rounded-xl shadow-sm border border-slate-100 overflow-hidden mb-4 sm:mb-6">
|
2026-05-19 16:00:27 +06:00
|
|
|
<div className="p-4 sm:p-5 flex flex-col md:flex-row items-start justify-between gap-4 md:gap-5">
|
|
|
|
|
<div className="flex flex-col sm:flex-row items-start gap-4 sm:gap-5 flex-1 w-full">
|
|
|
|
|
<div className="relative group shrink-0">
|
|
|
|
|
<div className="w-16 h-16 sm:w-20 sm:h-20 rounded-full bg-gradient-to-br from-purple-500 to-blue-500 flex items-center justify-center shadow-lg">
|
|
|
|
|
<span className="text-xl sm:text-2xl font-bold text-white">{investor.name.charAt(0)}</span>
|
|
|
|
|
</div>
|
|
|
|
|
<label className="absolute bottom-0 right-0 w-7 h-7 sm:w-8 sm: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-3.5 h-3.5 sm:w-4 sm:h-4 text-white" />
|
|
|
|
|
<input type="file" accept="image/*" className="hidden" />
|
|
|
|
|
</label>
|
2026-05-15 17:56:16 +06:00
|
|
|
</div>
|
|
|
|
|
|
2026-05-19 16:00:27 +06:00
|
|
|
<div className="flex-1 w-full">
|
|
|
|
|
<div className="flex flex-wrap items-center gap-2 mb-2">
|
|
|
|
|
<h1 className="text-xl sm:text-2xl font-bold text-slate-800">{investor.name}</h1>
|
|
|
|
|
<span className={`px-2 py-0.5 sm:px-2.5 sm:py-1 rounded-full text-xs font-medium ${investor.kycStatus === 'verified' ? 'bg-green-100 text-green-700' : 'bg-amber-100 text-amber-700'}`}>
|
|
|
|
|
<ShieldCheck className="w-3 h-3 inline mr-1" /> KYC {investor.kycStatus}
|
|
|
|
|
</span>
|
|
|
|
|
<span className={`px-2 py-0.5 sm:px-2.5 sm:py-1 rounded-full text-xs font-medium ${investor.status === 'active' ? 'bg-green-100 text-green-700' : 'bg-slate-100 text-slate-500'}`}>
|
|
|
|
|
{investor.status}
|
|
|
|
|
</span>
|
|
|
|
|
<span className={`px-2 py-0.5 sm:px-2.5 sm:py-1 rounded-full text-xs font-medium ${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>
|
|
|
|
|
<p className="text-xs sm:text-sm text-slate-500 mb-2">{investor.id} • {investor.email}</p>
|
|
|
|
|
<div className="flex flex-wrap items-center gap-x-3 gap-y-1">
|
|
|
|
|
<span className="text-xs font-medium px-2 py-0.5 rounded bg-purple-50 text-purple-700">Ref: {investor.referralCode}</span>
|
|
|
|
|
<span className="text-xs text-slate-400">{investor.totalReferrals} Referrals</span>
|
|
|
|
|
<span className="text-xs text-slate-400">• {investor.investments?.length || 0} Investments</span>
|
|
|
|
|
<span className="text-xs text-slate-400">• Referral Earnings: ৳{investor.referralEarnings?.toLocaleString() || 0}</span>
|
|
|
|
|
</div>
|
2026-05-15 17:56:16 +06:00
|
|
|
</div>
|
2026-05-15 01:25:48 +06:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
2026-05-19 16:00:27 +06:00
|
|
|
|
2026-05-15 17:56:16 +06:00
|
|
|
<div className="border-t border-slate-100 grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-6 divide-x divide-slate-100 bg-slate-50/50">
|
|
|
|
|
<div className="p-3 sm:p-4 text-center">
|
|
|
|
|
<p className="text-xs text-purple-600 font-medium">Invested</p>
|
|
|
|
|
<p className="text-base sm:text-lg font-bold text-slate-800">৳{investor.totalInvested.toLocaleString()}</p>
|
|
|
|
|
</div>
|
|
|
|
|
<div className="p-3 sm:p-4 text-center">
|
|
|
|
|
<p className="text-xs text-green-600 font-medium">Earnings</p>
|
|
|
|
|
<p className="text-base sm:text-lg font-bold text-green-600">৳{investor.totalEarnings.toLocaleString()}</p>
|
2026-05-15 01:25:48 +06:00
|
|
|
</div>
|
2026-05-15 17:56:16 +06:00
|
|
|
<div className="p-3 sm:p-4 text-center">
|
|
|
|
|
<p className="text-xs text-slate-600 font-medium">Withdrawn</p>
|
|
|
|
|
<p className="text-base sm:text-lg font-bold text-slate-800">৳{investor.totalWithdrawn.toLocaleString()}</p>
|
|
|
|
|
</div>
|
|
|
|
|
<div className="p-3 sm:p-4 text-center bg-white border-x border-slate-100">
|
|
|
|
|
<p className="text-xs text-investor font-medium">Balance</p>
|
|
|
|
|
<p className="text-base sm:text-lg font-bold text-investor">৳{currentBalance.toLocaleString()}</p>
|
|
|
|
|
</div>
|
|
|
|
|
<div className="p-3 sm:p-4 text-center">
|
|
|
|
|
<p className="text-xs text-slate-600 font-medium">Bikes</p>
|
|
|
|
|
<p className="text-base sm:text-lg font-bold text-slate-800">{investor.activeBikes}</p>
|
|
|
|
|
</div>
|
|
|
|
|
<div className="p-3 sm:p-4 text-center">
|
|
|
|
|
<p className="text-xs text-amber-600 font-medium">Pending</p>
|
|
|
|
|
<p className="text-base sm:text-lg font-bold text-amber-600">৳{investor.pendingEarnings.toLocaleString()}</p>
|
2026-05-15 01:25:48 +06:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
2026-05-15 17:56:16 +06:00
|
|
|
{/* Tabs */}
|
|
|
|
|
<div className="bg-white rounded-xl shadow-sm border border-slate-100 mb-4 sm:mb-6">
|
|
|
|
|
<div className="border-b border-slate-100 p-2 flex overflow-x-auto scrollbar-hide justify-between sm:justify-start sm:gap-2 gap-auto ">
|
|
|
|
|
{tabs.map(tab => {
|
|
|
|
|
const Icon = tab.icon;
|
|
|
|
|
return (
|
|
|
|
|
<button
|
|
|
|
|
key={tab.id}
|
|
|
|
|
onClick={() => setActiveTab(tab.id)}
|
|
|
|
|
className={`shrink-0 flex items-center justify-center w-12 sm:w-auto px-3 sm:px-4 py-2.5 rounded-lg text-xs sm:text-sm font-medium transition-all ${activeTab === tab.id ? 'bg-investor text-white shadow-md' : 'text-slate-500 hover:bg-slate-100'}`}
|
|
|
|
|
>
|
|
|
|
|
<Icon className="w-4 h-4 sm:mr-2" />
|
|
|
|
|
<span className="hidden sm:inline">{tab.label}</span>
|
|
|
|
|
</button>
|
|
|
|
|
);
|
|
|
|
|
})}
|
2026-05-15 01:25:48 +06:00
|
|
|
</div>
|
|
|
|
|
|
2026-05-15 17:56:16 +06:00
|
|
|
<div className="p-4 sm:p-5">
|
|
|
|
|
{/* Personal Info Tab */}
|
|
|
|
|
{activeTab === 'personal' && (
|
|
|
|
|
<div className="flex flex-col lg:flex-row gap-4 lg:gap-6">
|
|
|
|
|
<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 sm:grid-cols-2 gap-3">
|
|
|
|
|
<div>
|
|
|
|
|
<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>
|
|
|
|
|
<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-05-15 01:25:48 +06:00
|
|
|
</div>
|
2026-05-15 17:56:16 +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-05-15 01:25:48 +06:00
|
|
|
</div>
|
2026-05-15 17:56:16 +06:00
|
|
|
)}
|
|
|
|
|
</SectionCard>
|
|
|
|
|
|
|
|
|
|
<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>
|
|
|
|
|
<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>
|
|
|
|
|
<div>
|
|
|
|
|
<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" />
|
|
|
|
|
</div>
|
|
|
|
|
<div>
|
|
|
|
|
<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>
|
2026-05-15 01:25:48 +06:00
|
|
|
</div>
|
2026-05-15 17:56:16 +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">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-05-15 01:25:48 +06:00
|
|
|
</div>
|
2026-05-15 17:56:16 +06:00
|
|
|
)}
|
|
|
|
|
</SectionCard>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div className="flex-1 space-y-4">
|
|
|
|
|
|
|
|
|
|
<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] || '1205',
|
|
|
|
|
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>
|
|
|
|
|
<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 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>
|
2026-05-15 01:25:48 +06:00
|
|
|
</div>
|
2026-05-15 17:56:16 +06:00
|
|
|
) : (
|
|
|
|
|
<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>
|
|
|
|
|
</div>
|
2026-05-15 01:25:48 +06:00
|
|
|
</div>
|
2026-05-15 17:56:16 +06:00
|
|
|
)}
|
|
|
|
|
</SectionCard>
|
2026-05-15 01:25:48 +06:00
|
|
|
|
2026-05-15 17:56:16 +06:00
|
|
|
<SectionCard title="Permanent Address" icon={Home} headerBg="bg-indigo-50" headerBorder="border-indigo-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] || '1205',
|
|
|
|
|
isSameAsPresent: true
|
|
|
|
|
});
|
|
|
|
|
}}
|
|
|
|
|
editForm={editForm} setEditForm={setEditForm}>
|
|
|
|
|
{editingSection === 'permanentAddress' ? (
|
2026-05-15 01:25:48 +06:00
|
|
|
<div>
|
2026-05-15 17:56:16 +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</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</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-05-15 01:25:48 +06:00
|
|
|
</div>
|
2026-05-15 17:56:16 +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>
|
|
|
|
|
</div>
|
2026-05-15 01:25:48 +06:00
|
|
|
</div>
|
2026-05-15 17:56:16 +06:00
|
|
|
)}
|
|
|
|
|
</SectionCard>
|
|
|
|
|
<SectionCard title="Notes" icon={FileText} headerBg="bg-amber-50" headerBorder="border-amber-100"
|
|
|
|
|
editKey="note" editingSection={editingSection} setEditingSection={setEditingSection}
|
|
|
|
|
onEdit={() => setEditForm({ notes: investor.notes || '' })}
|
|
|
|
|
editForm={editForm} setEditForm={setEditForm}>
|
|
|
|
|
{editingSection === 'note' ? (
|
2026-05-15 01:25:48 +06:00
|
|
|
<div>
|
2026-05-15 17:56:16 +06:00
|
|
|
<textarea value={editForm.notes || ''} onChange={(e) => setEditForm({ ...editForm, notes: e.target.value })} className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm" rows={3} placeholder="Add notes about this investor..." />
|
2026-05-15 01:25:48 +06:00
|
|
|
</div>
|
2026-05-15 17:56:16 +06:00
|
|
|
) : (
|
|
|
|
|
<p className="font-medium text-slate-700">{investor.notes || 'No notes added yet.'}</p>
|
|
|
|
|
)}
|
|
|
|
|
</SectionCard>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
2026-05-15 01:25:48 +06:00
|
|
|
</div>
|
|
|
|
|
|
2026-05-15 17:56:16 +06:00
|
|
|
)}
|
2026-05-15 01:25:48 +06:00
|
|
|
|
2026-05-15 17:56:16 +06:00
|
|
|
{/* Nominee Tab */}
|
|
|
|
|
{activeTab === 'nominee' && (
|
|
|
|
|
<div className="flex flex-col lg:flex-row gap-4 lg:gap-6">
|
|
|
|
|
<div className="flex-1">
|
|
|
|
|
<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 || '',
|
|
|
|
|
nomineeShare: (investor as any).nomineeShare || '',
|
|
|
|
|
nomineeAddress: (investor as any).nomineeAddress || ''
|
|
|
|
|
})} 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-05-15 01:25:48 +06:00
|
|
|
</div>
|
2026-05-15 17:56:16 +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-05-15 01:25:48 +06:00
|
|
|
</div>
|
2026-05-15 17:56:16 +06:00
|
|
|
)}
|
|
|
|
|
</SectionCard>
|
|
|
|
|
</div>
|
|
|
|
|
<div className="flex-1">
|
|
|
|
|
<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">
|
|
|
|
|
<div>
|
|
|
|
|
<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>
|
2026-05-15 01:25:48 +06:00
|
|
|
</div>
|
2026-05-15 17:56:16 +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">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></div>
|
2026-05-15 01:25:48 +06:00
|
|
|
</div>
|
2026-05-15 17:56:16 +06:00
|
|
|
)}
|
|
|
|
|
</SectionCard>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
|
|
{/* Financial Tab */}
|
|
|
|
|
{activeTab === 'financial' && (
|
|
|
|
|
<div className="space-y-6">
|
|
|
|
|
<div className="grid lg:grid-cols-2 gap-6">
|
|
|
|
|
<div>
|
|
|
|
|
<div className="flex items-center justify-between mb-4">
|
|
|
|
|
<h3 className="font-semibold text-slate-800">Bank Accounts ({(investor as any).bankAccounts?.length || 0})</h3>
|
|
|
|
|
<button onClick={() => { setEditingBank({ id: '', bankName: '', accountName: '', accountNumber: '', branch: '', routing: '', isPrimary: false }); setShowAddBankModal(true); }} className="text-sm text-investor hover:underline flex items-center gap-1">
|
|
|
|
|
<Plus className="w-4 h-4" /> Add Account
|
|
|
|
|
</button>
|
2026-05-15 01:25:48 +06:00
|
|
|
</div>
|
2026-05-15 17:56:16 +06:00
|
|
|
<div className="space-y-3">
|
|
|
|
|
{(investor as any).bankAccounts && (investor as any).bankAccounts.length > 0 ? (
|
|
|
|
|
(investor as any).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 bg-slate-100">
|
|
|
|
|
<Building2 className="w-5 h-5 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">
|
|
|
|
|
<button onClick={() => { setEditingBank(account); setShowEditBankModal(true); }} className="p-1.5 hover:bg-slate-100 rounded-lg text-slate-500">
|
|
|
|
|
<Edit className="w-4 h-4" />
|
|
|
|
|
</button>
|
|
|
|
|
<button onClick={() => { setBankToDelete(account); setShowDeleteBankModal(true); }} className="p-1.5 hover:bg-red-50 rounded-lg text-red-400">
|
|
|
|
|
<Trash className="w-4 h-4" />
|
|
|
|
|
</button>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<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>
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
))
|
|
|
|
|
) : (
|
|
|
|
|
<div className="text-center py-10 border-2 border-dashed border-slate-200 rounded-xl">
|
|
|
|
|
<Building2 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={() => { setEditingBank({ id: '', bankName: '', accountName: '', accountNumber: '', branch: '', routing: '', isPrimary: false }); setShowAddBankModal(true); }} className="px-4 py-2 text-sm bg-investor text-white rounded-lg hover:bg-investor-dark">
|
|
|
|
|
Add First Account
|
|
|
|
|
</button>
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
2026-05-15 01:25:48 +06:00
|
|
|
</div>
|
2026-05-15 17:56:16 +06:00
|
|
|
</div>
|
2026-05-15 01:25:48 +06:00
|
|
|
|
2026-05-15 17:56:16 +06:00
|
|
|
<div>
|
|
|
|
|
<div className="flex items-center justify-between mb-4">
|
|
|
|
|
<h3 className="font-semibold text-slate-800">Mobile Banking</h3>
|
|
|
|
|
<button onClick={() => { setEditingMobile({ provider: '', number: '', isPrimary: false }); setEditingMobileIndex(null); setShowAddMobileModal(true); }} className="text-sm text-investor hover:underline flex items-center gap-1">
|
|
|
|
|
<Plus className="w-4 h-4" /> Add
|
|
|
|
|
</button>
|
|
|
|
|
</div>
|
|
|
|
|
<div className="space-y-3">
|
|
|
|
|
{(investor as any).mobileBanking && (
|
|
|
|
|
<div className="flex items-center gap-3 p-3 bg-purple-50 rounded-lg">
|
|
|
|
|
<Smartphone className="w-5 h-5 text-purple-500" />
|
|
|
|
|
<div className="flex-1">
|
|
|
|
|
<p className="text-xs text-purple-600 font-medium">{(investor as any).mobileBanking}</p>
|
|
|
|
|
<p className="text-xs text-slate-400">{(investor as any).mobileBankingNumber}</p>
|
2026-05-15 01:25:48 +06:00
|
|
|
</div>
|
2026-05-15 17:56:16 +06:00
|
|
|
<button onClick={() => { setEditingMobile({ provider: (investor as any).mobileBanking || '', number: (investor as any).mobileBankingNumber || '', isPrimary: true }); setEditingMobileIndex(-1); setShowEditMobileModal(true); }} className="p-1 hover:bg-purple-100 rounded">
|
|
|
|
|
<Edit className="w-4 h-4 text-purple-500" />
|
|
|
|
|
</button>
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
{(investor as any).additionalMobileBanking?.map((mb: any, idx: number) => (
|
|
|
|
|
<div key={idx} className="flex items-center gap-3 p-3 bg-slate-50 rounded-lg">
|
|
|
|
|
<Smartphone 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>
|
2026-05-15 01:25:48 +06:00
|
|
|
</div>
|
2026-05-15 17:56:16 +06:00
|
|
|
{mb.verified ? (
|
|
|
|
|
<span className="text-xs bg-green-100 text-green-700 px-2 py-1 rounded-full">Verified</span>
|
|
|
|
|
) : (
|
|
|
|
|
<span className="text-xs bg-amber-100 text-amber-700 px-2 py-1 rounded-full">Pending</span>
|
|
|
|
|
)}
|
|
|
|
|
<button onClick={() => { setEditingMobile({ provider: mb.provider, number: mb.number, isPrimary: false }); setEditingMobileIndex(idx); setShowEditMobileModal(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">
|
|
|
|
|
<Trash className="w-4 h-4 text-red-400" />
|
|
|
|
|
</button>
|
|
|
|
|
</div>
|
|
|
|
|
))}
|
|
|
|
|
{(!((investor as any).mobileBanking) && (!((investor as any).additionalMobileBanking) || ((investor as any).additionalMobileBanking).length === 0)) && (
|
|
|
|
|
<div className="text-center py-8 text-slate-400 border-2 border-dashed border-slate-200 rounded-lg">
|
|
|
|
|
<Smartphone className="w-8 h-8 mx-auto mb-2 opacity-50" />
|
|
|
|
|
<p className="text-sm">No mobile banking added</p>
|
2026-05-15 01:25:48 +06:00
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
|
2026-05-15 17:56:16 +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 as any).passportNumber || '' }); setShowTaxModal(true); }} className="text-sm text-investor hover:underline flex items-center gap-1">
|
|
|
|
|
<Edit className="w-4 h-4" /> {investor.tinNumber || (investor as any).passportNumber ? 'Edit' : 'Add'}
|
|
|
|
|
</button>
|
2026-05-15 01:25:48 +06:00
|
|
|
</div>
|
2026-05-15 17:56:16 +06:00
|
|
|
<div className="space-y-3">
|
|
|
|
|
{investor.tinNumber || (investor as any).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" />
|
2026-05-15 01:25:48 +06:00
|
|
|
<div>
|
2026-05-15 17:56:16 +06:00
|
|
|
<p className="text-xs text-slate-500">TIN</p>
|
|
|
|
|
<p className="font-medium text-slate-700">{investor.tinNumber}</p>
|
2026-05-15 01:25:48 +06:00
|
|
|
</div>
|
|
|
|
|
</div>
|
2026-05-15 17:56:16 +06:00
|
|
|
)}
|
|
|
|
|
{(investor as any).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 as any).passportNumber}</p>
|
2026-05-15 01:25:48 +06:00
|
|
|
</div>
|
2026-05-15 17:56:16 +06:00
|
|
|
</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-05-15 01:25:48 +06:00
|
|
|
</div>
|
2026-05-15 17:56:16 +06:00
|
|
|
)}
|
|
|
|
|
</div>
|
2026-05-15 01:25:48 +06:00
|
|
|
</div>
|
|
|
|
|
</div>
|
2026-05-15 17:56:16 +06:00
|
|
|
</div>
|
|
|
|
|
)}
|
2026-05-15 01:25:48 +06:00
|
|
|
|
2026-05-15 17:56:16 +06:00
|
|
|
{/* KYC Tab */}
|
|
|
|
|
{activeTab === 'kyc' && (
|
|
|
|
|
<div className="space-y-4">
|
|
|
|
|
<SectionCard title="KYC Documents" icon={FileText} headerBg="bg-green-50" headerBorder="border-green-100">
|
|
|
|
|
<div className="space-y-4">
|
|
|
|
|
<div className={`p-4 rounded-lg border ${investor.kycStatus === 'verified' ? 'bg-green-50 border-green-200' : 'bg-amber-50 border-amber-200'}`}>
|
|
|
|
|
<div className="flex items-center gap-3">
|
|
|
|
|
<div className={`w-10 h-10 rounded-lg flex items-center justify-center ${investor.kycStatus === 'verified' ? 'bg-green-100' : 'bg-amber-100'}`}>
|
|
|
|
|
<ShieldCheck className={`w-5 h-5 ${investor.kycStatus === 'verified' ? 'text-green-600' : 'text-amber-600'}`} />
|
2026-05-15 01:25:48 +06:00
|
|
|
</div>
|
2026-05-15 17:56:16 +06:00
|
|
|
<div>
|
|
|
|
|
<p className={`font-semibold ${investor.kycStatus === 'verified' ? 'text-green-700' : 'text-amber-700'}`}>Status: {investor.kycStatus.toUpperCase()}</p>
|
|
|
|
|
<p className="text-xs text-slate-500">{investor.kycStatus === 'verified' ? 'All documents verified' : 'Documents under review'}</p>
|
2026-05-15 01:25:48 +06:00
|
|
|
</div>
|
|
|
|
|
</div>
|
2026-05-15 17:56:16 +06:00
|
|
|
</div>
|
2026-05-15 01:25:48 +06:00
|
|
|
|
2026-05-15 17:56:16 +06:00
|
|
|
<div className="grid gap-3">
|
|
|
|
|
{investor.kycDocuments && investor.kycDocuments.map((doc: any, idx: number) => (
|
|
|
|
|
<div key={idx} className="flex items-center justify-between p-4 bg-slate-50 rounded-lg border border-slate-200">
|
|
|
|
|
<div className="flex items-center gap-3">
|
|
|
|
|
<div className="w-10 h-10 bg-investor/10 rounded-lg flex items-center justify-center">
|
|
|
|
|
<FileText className="w-5 h-5 text-investor" />
|
2026-05-15 01:25:48 +06:00
|
|
|
</div>
|
|
|
|
|
<div>
|
2026-05-15 17:56:16 +06:00
|
|
|
<p className="font-medium text-slate-700 capitalize">{doc.type}</p>
|
|
|
|
|
<p className="text-xs text-slate-400">{doc.number || 'Document uploaded'}</p>
|
2026-05-15 01:25:48 +06:00
|
|
|
</div>
|
|
|
|
|
</div>
|
2026-05-15 17:56:16 +06:00
|
|
|
<span className={`px-3 py-1 rounded-full text-xs font-medium ${doc.verified ? 'bg-green-100 text-green-700' : 'bg-amber-100 text-amber-700'}`}>
|
|
|
|
|
{doc.verified ? 'Verified' : 'Pending'}
|
|
|
|
|
</span>
|
|
|
|
|
</div>
|
|
|
|
|
))}
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<button onClick={() => setShowUploadDocModal(true)} className="w-full py-3 border-2 border-dashed border-slate-200 rounded-lg text-slate-500 hover:border-investor hover:text-investor transition-colors flex items-center justify-center gap-2">
|
|
|
|
|
<Upload className="w-4 h-4" /> Upload Document
|
|
|
|
|
</button>
|
2026-05-15 01:25:48 +06:00
|
|
|
</div>
|
2026-05-15 17:56:16 +06:00
|
|
|
</SectionCard>
|
2026-05-15 01:25:48 +06:00
|
|
|
</div>
|
2026-05-15 17:56:16 +06:00
|
|
|
)}
|
2026-05-15 01:25:48 +06:00
|
|
|
|
2026-05-15 17:56:16 +06:00
|
|
|
{/* Security Tab */}
|
|
|
|
|
{activeTab === 'security' && (
|
|
|
|
|
<div className="grid md:grid-cols-2 gap-6">
|
2026-05-15 01:25:48 +06:00
|
|
|
<div className="space-y-4">
|
2026-05-15 17:56:16 +06:00
|
|
|
<SectionCard title="Change Password" icon={Lock} headerBg="bg-slate-50" headerBorder="border-slate-100">
|
|
|
|
|
<div className="space-y-4">
|
2026-05-15 01:25:48 +06:00
|
|
|
<div>
|
2026-05-15 17:56:16 +06:00
|
|
|
<label className="text-xs text-slate-500 mb-1 block">Current Password</label>
|
|
|
|
|
<div className="relative">
|
|
|
|
|
<input type={showPassword.current ? 'text' : 'password'} value={passwordForm.current} onChange={(e) => setPasswordForm({ ...passwordForm, current: e.target.value })} className="w-full px-3 py-2 pr-10 border border-slate-200 rounded-lg text-sm" placeholder="Enter current password" />
|
|
|
|
|
<button type="button" onClick={() => setShowPassword({ ...showPassword, current: !showPassword.current })} className="absolute right-3 top-1/2 -translate-y-1/2 p-1">{showPassword.current ? <EyeOff className="w-4 h-4 text-slate-400" /> : <Eye className="w-4 h-4 text-slate-400" />}</button>
|
2026-05-15 01:25:48 +06:00
|
|
|
</div>
|
|
|
|
|
</div>
|
2026-05-15 17:56:16 +06:00
|
|
|
<div>
|
|
|
|
|
<label className="text-xs text-slate-500 mb-1 block">New Password</label>
|
|
|
|
|
<div className="relative">
|
|
|
|
|
<input type={showPassword.new ? 'text' : 'password'} value={passwordForm.new} onChange={(e) => setPasswordForm({ ...passwordForm, new: e.target.value })} className="w-full px-3 py-2 pr-10 border border-slate-200 rounded-lg text-sm" placeholder="Min 8 characters" />
|
|
|
|
|
<button type="button" onClick={() => setShowPassword({ ...showPassword, new: !showPassword.new })} className="absolute right-3 top-1/2 -translate-y-1/2 p-1">{showPassword.new ? <EyeOff className="w-4 h-4 text-slate-400" /> : <Eye className="w-4 h-4 text-slate-400" />}</button>
|
|
|
|
|
</div>
|
2026-05-15 01:25:48 +06:00
|
|
|
</div>
|
2026-05-15 17:56:16 +06:00
|
|
|
<div>
|
|
|
|
|
<label className="text-xs text-slate-500 mb-1 block">Confirm New Password</label>
|
|
|
|
|
<div className="relative">
|
|
|
|
|
<input type={showPassword.confirm ? 'text' : 'password'} value={passwordForm.confirm} onChange={(e) => setPasswordForm({ ...passwordForm, confirm: e.target.value })} className="w-full px-3 py-2 pr-10 border border-slate-200 rounded-lg text-sm" placeholder="Confirm new password" />
|
|
|
|
|
<button type="button" onClick={() => setShowPassword({ ...showPassword, confirm: !showPassword.confirm })} className="absolute right-3 top-1/2 -translate-y-1/2 p-1">{showPassword.confirm ? <EyeOff className="w-4 h-4 text-slate-400" /> : <Eye className="w-4 h-4 text-slate-400" />}</button>
|
|
|
|
|
</div>
|
2026-05-15 01:25:48 +06:00
|
|
|
</div>
|
2026-05-15 17:56:16 +06:00
|
|
|
<button onClick={handlePasswordChange} className="px-4 py-2 bg-investor text-white rounded-lg text-sm font-medium hover:bg-investor-dark flex items-center gap-2">
|
|
|
|
|
<Key className="w-4 h-4" /> Update Password
|
|
|
|
|
</button>
|
2026-05-15 01:25:48 +06:00
|
|
|
</div>
|
2026-05-15 17:56:16 +06:00
|
|
|
</SectionCard>
|
2026-05-15 01:25:48 +06:00
|
|
|
|
2026-05-15 17:56:16 +06:00
|
|
|
<SectionCard title="Two-Factor Authentication" icon={Shield} headerBg="bg-purple-50" headerBorder="border-purple-100">
|
|
|
|
|
<div className="flex items-center justify-between">
|
|
|
|
|
<div className="flex items-center gap-3">
|
|
|
|
|
<div className="w-10 h-10 bg-purple-100 rounded-lg flex items-center justify-center">
|
|
|
|
|
<Shield className="w-5 h-5 text-purple-600" />
|
|
|
|
|
</div>
|
|
|
|
|
<div>
|
|
|
|
|
<p className="font-medium text-slate-700">Add extra security</p>
|
|
|
|
|
<p className="text-xs text-slate-500">Requires code from phone when logging in</p>
|
|
|
|
|
</div>
|
2026-05-15 01:25:48 +06:00
|
|
|
</div>
|
2026-05-15 17:56:16 +06:00
|
|
|
<button onClick={() => setTwoFactorEnabled(!twoFactorEnabled)} className={`px-4 py-2 rounded-lg text-sm font-medium ${twoFactorEnabled ? 'bg-green-100 text-green-700' : 'bg-investor text-white hover:bg-investor-dark'}`}>
|
|
|
|
|
{twoFactorEnabled ? 'Enabled' : 'Enable'}
|
|
|
|
|
</button>
|
2026-05-15 01:25:48 +06:00
|
|
|
</div>
|
2026-05-15 17:56:16 +06:00
|
|
|
</SectionCard>
|
2026-05-15 01:25:48 +06:00
|
|
|
|
2026-05-15 17:56:16 +06:00
|
|
|
<SectionCard title="Active Sessions" icon={Activity} headerBg="bg-blue-50" headerBorder="border-blue-100">
|
|
|
|
|
<div className="space-y-3">
|
|
|
|
|
{sessionHistory.map(session => (
|
|
|
|
|
<div key={session.id} className="flex items-center gap-4 p-4 bg-slate-50 rounded-lg border border-slate-200">
|
|
|
|
|
<div className="w-10 h-10 bg-investor/10 rounded-lg flex items-center justify-center">
|
|
|
|
|
<Smartphone className="w-5 h-5 text-investor" />
|
|
|
|
|
</div>
|
|
|
|
|
<div className="flex-1">
|
|
|
|
|
<div className="flex items-center gap-2">
|
|
|
|
|
<p className="font-medium text-slate-700">{session.device}</p>
|
|
|
|
|
{session.current && <span className="px-2 py-0.5 bg-green-100 text-green-700 text-xs rounded-full">Current</span>}
|
|
|
|
|
</div>
|
|
|
|
|
<p className="text-xs text-slate-400">{session.location} • {session.time}</p>
|
2026-05-15 01:25:48 +06:00
|
|
|
</div>
|
2026-05-19 16:00:27 +06:00
|
|
|
{!session.current ? (
|
|
|
|
|
<button className="px-3 py-1.5 text-xs font-medium text-red-600 hover:bg-red-50 rounded-lg">Revoke</button>
|
|
|
|
|
) : (
|
|
|
|
|
<button onClick={handleLogout} className="px-3 py-1.5 text-xs font-medium text-red-600 hover:bg-red-50 rounded-lg">Log Out</button>
|
|
|
|
|
)}
|
2026-05-15 01:25:48 +06:00
|
|
|
</div>
|
2026-05-15 17:56:16 +06:00
|
|
|
))}
|
2026-05-19 16:00:27 +06:00
|
|
|
<button onClick={handleLogout} className="w-full py-3 bg-red-50 text-red-600 rounded-lg text-sm font-medium hover:bg-red-100 flex items-center justify-center gap-2">
|
2026-05-15 17:56:16 +06:00
|
|
|
<LogOut className="w-4 h-4" /> Sign Out All Devices
|
|
|
|
|
</button>
|
|
|
|
|
</div>
|
|
|
|
|
</SectionCard>
|
|
|
|
|
</div>
|
2026-05-15 01:25:48 +06:00
|
|
|
|
2026-05-15 17:56:16 +06:00
|
|
|
<div className="flex items-center justify-center">
|
|
|
|
|
<div className="bg-gradient-to-br from-slate-50 to-purple-50 rounded-2xl p-8 w-full h-full flex flex-col items-center justify-center min-h-[400px]">
|
|
|
|
|
<div className="w-32 h-32 bg-gradient-to-br from-purple-500 to-indigo-600 rounded-full flex items-center justify-center mb-6 shadow-lg">
|
|
|
|
|
<Lock className="w-16 h-16 text-white" />
|
2026-05-15 01:25:48 +06:00
|
|
|
</div>
|
2026-05-15 17:56:16 +06:00
|
|
|
<h3 className="text-xl font-bold text-slate-800 mb-2">Keep Your Account Secure</h3>
|
|
|
|
|
<p className="text-sm text-slate-500 text-center max-w-xs">Use a strong password with letters, numbers, and symbols to protect your account from unauthorized access.</p>
|
|
|
|
|
<div className="mt-6 flex items-center gap-4">
|
|
|
|
|
<div className="flex items-center gap-2 text-sm text-slate-600">
|
|
|
|
|
<div className="w-8 h-8 bg-green-100 rounded-full flex items-center justify-center"><Shield className="w-4 h-4 text-green-600" /></div>
|
|
|
|
|
<span>256-bit Encryption</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div className="flex items-center gap-2 text-sm text-slate-600">
|
|
|
|
|
<div className="w-8 h-8 bg-blue-100 rounded-full flex items-center justify-center"><Activity className="w-4 h-4 text-blue-600" /></div>
|
|
|
|
|
<span>Real-time Monitoring</span>
|
|
|
|
|
</div>
|
2026-05-15 01:25:48 +06:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
2026-05-15 17:56:16 +06:00
|
|
|
)}
|
|
|
|
|
</div>
|
2026-05-15 01:25:48 +06:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
2026-05-15 17:56:16 +06:00
|
|
|
{/* Bank Modals */}
|
|
|
|
|
{showAddBankModal && (
|
|
|
|
|
<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">
|
|
|
|
|
<h3 className="text-lg font-bold text-slate-800">Add Bank Account</h3>
|
|
|
|
|
<button onClick={() => setShowAddBankModal(false)} className="p-1 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-xs text-slate-500 mb-1 block">Bank Name *</label><input type="text" value={newBankForm.bankName} onChange={(e) => setNewBankForm({ ...newBankForm, bankName: e.target.value })} className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm" placeholder="e.g., Standard Chartered" /></div>
|
|
|
|
|
<div><label className="text-xs text-slate-500 mb-1 block">Account Name *</label><input type="text" value={newBankForm.accountName} onChange={(e) => setNewBankForm({ ...newBankForm, accountName: 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">Account Number *</label><input type="text" value={newBankForm.accountNumber} onChange={(e) => setNewBankForm({ ...newBankForm, accountNumber: e.target.value })} className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm" /></div>
|
|
|
|
|
<div className="grid grid-cols-2 gap-4">
|
|
|
|
|
<div><label className="text-xs text-slate-500 mb-1 block">Branch</label><input type="text" value={newBankForm.branch} onChange={(e) => setNewBankForm({ ...newBankForm, branch: 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">Routing</label><input type="text" value={newBankForm.routing} onChange={(e) => setNewBankForm({ ...newBankForm, routing: e.target.value })} className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm" /></div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div className="p-5 border-t border-slate-100 flex justify-end gap-3">
|
|
|
|
|
<button onClick={() => setShowAddBankModal(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={handleSaveBank} disabled={!newBankForm.bankName || !newBankForm.accountNumber} className="px-4 py-2 bg-investor text-white rounded-lg text-sm font-medium hover:bg-investor-dark disabled:opacity-50">Save</button>
|
2026-05-15 01:25:48 +06:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
2026-05-15 17:56:16 +06:00
|
|
|
)}
|
2026-05-15 01:25:48 +06:00
|
|
|
|
2026-05-15 17:56:16 +06:00
|
|
|
{showEditBankModal && (
|
|
|
|
|
<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">
|
|
|
|
|
<h3 className="text-lg font-bold text-slate-800">Edit Bank Account</h3>
|
|
|
|
|
<button onClick={() => setShowEditBankModal(false)} className="p-1 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-xs text-slate-500 mb-1 block">Bank Name</label><input type="text" value={editingBank.bankName} onChange={(e) => setEditingBank({ ...editingBank, bankName: e.target.value })} className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm" /></div>
|
|
|
|
|
<div><label className="text-xs text-slate-500 mb-1 block">Account Name</label><input type="text" value={editingBank.accountName} onChange={(e) => setEditingBank({ ...editingBank, accountName: 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">Account Number</label><input type="text" value={editingBank.accountNumber} onChange={(e) => setEditingBank({ ...editingBank, accountNumber: e.target.value })} className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm" /></div>
|
|
|
|
|
<div className="grid grid-cols-2 gap-4">
|
|
|
|
|
<div><label className="text-xs text-slate-500 mb-1 block">Branch</label><input type="text" value={editingBank.branch} onChange={(e) => setEditingBank({ ...editingBank, branch: 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">Routing</label><input type="text" value={editingBank.routing} onChange={(e) => setEditingBank({ ...editingBank, routing: e.target.value })} className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm" /></div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div className="p-5 border-t border-slate-100 flex justify-end gap-3">
|
|
|
|
|
<button onClick={() => setShowEditBankModal(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={handleSaveBank} className="px-4 py-2 bg-investor text-white rounded-lg text-sm font-medium hover:bg-investor-dark">Save Changes</button>
|
2026-05-15 01:25:48 +06:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
2026-05-15 17:56:16 +06:00
|
|
|
)}
|
2026-05-15 01:25:48 +06:00
|
|
|
|
2026-05-15 17:56:16 +06:00
|
|
|
{showDeleteBankModal && bankToDelete && (
|
|
|
|
|
<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">
|
|
|
|
|
<h3 className="text-lg font-bold text-slate-800">Delete Bank Account</h3>
|
|
|
|
|
<button onClick={() => setShowDeleteBankModal(false)} className="p-1 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="p-4 bg-slate-50 rounded-lg"><p className="font-medium text-slate-800">{bankToDelete.bankName}</p><p className="text-sm text-slate-500">{bankToDelete.accountNumber}</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={handleDeleteBank} className="px-4 py-2 bg-red-500 text-white rounded-lg text-sm font-medium hover:bg-red-600">Delete</button>
|
|
|
|
|
</div>
|
2026-05-15 01:25:48 +06:00
|
|
|
</div>
|
|
|
|
|
</div>
|
2026-05-15 17:56:16 +06:00
|
|
|
)}
|
2026-05-15 01:25:48 +06:00
|
|
|
|
2026-05-15 17:56:16 +06:00
|
|
|
{/* Mobile Modals */}
|
|
|
|
|
{showAddMobileModal && (
|
|
|
|
|
<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">
|
|
|
|
|
<h3 className="text-lg font-bold text-slate-800">Add Mobile Banking</h3>
|
|
|
|
|
<button onClick={() => setShowAddMobileModal(false)} className="p-1 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-xs text-slate-500 mb-1 block">Provider *</label><select value={newMobileForm.provider} onChange={(e) => setNewMobileForm({ ...newMobileForm, 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="SureCash">SureCash</option></select></div>
|
|
|
|
|
<div><label className="text-xs text-slate-500 mb-1 block">Account Number *</label><input type="text" value={newMobileForm.number} onChange={(e) => setNewMobileForm({ ...newMobileForm, number: e.target.value })} className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm" placeholder="01XXXXXXXXX" /></div>
|
|
|
|
|
</div>
|
|
|
|
|
<div className="p-5 border-t border-slate-100 flex justify-end gap-3">
|
|
|
|
|
<button onClick={() => setShowAddMobileModal(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={handleSaveMobile} disabled={!newMobileForm.provider || !newMobileForm.number} className="px-4 py-2 bg-investor text-white rounded-lg text-sm font-medium hover:bg-investor-dark disabled:opacity-50">Save</button>
|
|
|
|
|
</div>
|
2026-05-15 01:25:48 +06:00
|
|
|
</div>
|
|
|
|
|
</div>
|
2026-05-15 17:56:16 +06:00
|
|
|
)}
|
2026-05-15 01:25:48 +06:00
|
|
|
|
2026-05-15 17:56:16 +06:00
|
|
|
{showEditMobileModal && (
|
|
|
|
|
<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">
|
|
|
|
|
<h3 className="text-lg font-bold text-slate-800">Edit Mobile Banking</h3>
|
|
|
|
|
<button onClick={() => setShowEditMobileModal(false)} className="p-1 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-xs text-slate-500 mb-1 block">Provider</label><input type="text" value={editingMobile.provider} onChange={(e) => setEditingMobile({ ...editingMobile, provider: 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">Account Number</label><input type="text" value={editingMobile.number} onChange={(e) => setEditingMobile({ ...editingMobile, number: e.target.value })} className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm" /></div>
|
|
|
|
|
</div>
|
|
|
|
|
<div className="p-5 border-t border-slate-100 flex justify-end gap-3">
|
|
|
|
|
<button onClick={() => setShowEditMobileModal(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={handleSaveMobile} className="px-4 py-2 bg-investor text-white rounded-lg text-sm font-medium hover:bg-investor-dark">Save Changes</button>
|
|
|
|
|
</div>
|
2026-05-15 01:25:48 +06:00
|
|
|
</div>
|
|
|
|
|
</div>
|
2026-05-15 17:56:16 +06:00
|
|
|
)}
|
2026-05-15 01:25:48 +06:00
|
|
|
|
2026-05-15 17:56:16 +06:00
|
|
|
{showDeleteMobileModal && mobileToDelete && (
|
|
|
|
|
<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">
|
|
|
|
|
<h3 className="text-lg font-bold text-slate-800">Delete Mobile Banking</h3>
|
|
|
|
|
<button onClick={() => setShowDeleteMobileModal(false)} className="p-1 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 mobile banking account?</p>
|
|
|
|
|
<div className="p-4 bg-slate-50 rounded-lg"><p className="font-medium text-slate-800">{mobileToDelete.provider}</p><p className="text-sm text-slate-500 font-mono">{mobileToDelete.number}</p></div>
|
|
|
|
|
</div>
|
|
|
|
|
<div className="p-5 border-t border-slate-100 flex justify-end gap-3">
|
|
|
|
|
<button onClick={() => setShowDeleteMobileModal(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={handleDeleteMobile} className="px-4 py-2 bg-red-500 text-white rounded-lg text-sm font-medium hover:bg-red-600">Delete</button>
|
|
|
|
|
</div>
|
2026-05-15 01:25:48 +06:00
|
|
|
</div>
|
|
|
|
|
</div>
|
2026-05-15 17:56:16 +06:00
|
|
|
)}
|
2026-05-15 01:25:48 +06:00
|
|
|
|
2026-05-15 17:56:16 +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">
|
|
|
|
|
<h3 className="text-lg font-bold text-slate-800">Tax Information</h3>
|
|
|
|
|
<button onClick={() => setShowTaxModal(false)} className="p-1 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-xs text-slate-500 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="e.g., 1234567890" />
|
|
|
|
|
</div>
|
|
|
|
|
<div>
|
|
|
|
|
<label className="text-xs text-slate-500 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="e.g., AB1234567" />
|
|
|
|
|
</div>
|
2026-05-15 01:25:48 +06:00
|
|
|
</div>
|
2026-05-15 17:56:16 +06:00
|
|
|
<div className="p-5 border-t border-slate-100 flex justify-end gap-3">
|
|
|
|
|
<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>
|
2026-05-19 20:45:10 +06:00
|
|
|
<button onClick={() => { setShowTaxModal(false); triggerApprovalRequest('save/edit', 'Tax Information'); }} className="px-4 py-2 bg-investor text-white rounded-lg text-sm font-medium hover:bg-investor-dark">Save</button>
|
2026-05-15 01:25:48 +06:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
2026-05-15 17:56:16 +06:00
|
|
|
)}
|
2026-05-15 02:16:32 +06:00
|
|
|
|
2026-05-15 17:56:16 +06:00
|
|
|
{showUploadDocModal && (
|
|
|
|
|
<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">
|
|
|
|
|
<h3 className="text-lg font-bold text-slate-800">Upload Document</h3>
|
|
|
|
|
<button onClick={() => setShowUploadDocModal(false)} className="p-1.5 hover:bg-slate-100 rounded-lg">
|
|
|
|
|
<X className="w-5 h-5 text-slate-400" />
|
|
|
|
|
</button>
|
2026-05-15 02:16:32 +06:00
|
|
|
</div>
|
2026-05-15 17:56:16 +06:00
|
|
|
<div className="p-5 space-y-4">
|
|
|
|
|
<div>
|
|
|
|
|
<label className="text-xs text-slate-500 mb-1 block">Document Type *</label>
|
|
|
|
|
<select
|
|
|
|
|
value={uploadDocForm.docType}
|
|
|
|
|
onChange={(e) => setUploadDocForm({ ...uploadDocForm, docType: e.target.value })}
|
|
|
|
|
className="w-full px-3 py-2.5 border border-slate-200 rounded-lg text-sm bg-white"
|
|
|
|
|
>
|
|
|
|
|
<option value="">Select Document Type</option>
|
|
|
|
|
<option value="nid">National ID (NID)</option>
|
|
|
|
|
<option value="passport">Passport</option>
|
|
|
|
|
<option value="driving_license">Driving License</option>
|
|
|
|
|
<option value="tax_certificate">Tax Certificate</option>
|
|
|
|
|
<option value="birth_certificate">Birth Certificate</option>
|
|
|
|
|
</select>
|
|
|
|
|
</div>
|
|
|
|
|
<div>
|
|
|
|
|
<label className="text-xs text-slate-500 mb-1 block">Document Number</label>
|
2026-05-15 02:16:32 +06:00
|
|
|
<input
|
2026-05-15 17:56:16 +06:00
|
|
|
type="text"
|
|
|
|
|
value={uploadDocForm.docNumber}
|
|
|
|
|
onChange={(e) => setUploadDocForm({ ...uploadDocForm, docNumber: e.target.value })}
|
|
|
|
|
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm"
|
|
|
|
|
placeholder="Enter document number"
|
2026-05-15 02:16:32 +06:00
|
|
|
/>
|
|
|
|
|
</div>
|
2026-05-15 17:56:16 +06:00
|
|
|
<div>
|
|
|
|
|
<label className="text-xs text-slate-500 mb-1 block">Upload File *</label>
|
|
|
|
|
<div className="border-2 border-dashed border-slate-200 rounded-lg p-6 text-center hover:border-investor transition-colors cursor-pointer"
|
|
|
|
|
onClick={() => document.getElementById('docFileInput')?.click()}
|
|
|
|
|
>
|
|
|
|
|
{uploadDocForm.docFile ? (
|
|
|
|
|
<div className="flex items-center justify-center gap-2 text-green-600">
|
|
|
|
|
<FileText className="w-5 h-5" />
|
|
|
|
|
<span className="text-sm font-medium">{uploadDocForm.docFile.name}</span>
|
|
|
|
|
</div>
|
|
|
|
|
) : (
|
|
|
|
|
<>
|
|
|
|
|
<Upload className="w-8 h-8 mx-auto mb-2 text-slate-300" />
|
|
|
|
|
<p className="text-sm text-slate-500">Click to upload or drag and drop</p>
|
|
|
|
|
<p className="text-xs text-slate-400 mt-1">PDF, JPG, PNG (max 5MB)</p>
|
|
|
|
|
</>
|
|
|
|
|
)}
|
|
|
|
|
<input
|
|
|
|
|
id="docFileInput"
|
|
|
|
|
type="file"
|
|
|
|
|
accept=".pdf,.jpg,.jpeg,.png"
|
|
|
|
|
className="hidden"
|
|
|
|
|
onChange={(e) => {
|
|
|
|
|
const file = e.target.files?.[0];
|
|
|
|
|
if (file) setUploadDocForm({ ...uploadDocForm, docFile: file });
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div className="p-5 border-t border-slate-100 flex justify-end gap-3 bg-slate-50">
|
|
|
|
|
<button onClick={() => setShowUploadDocModal(false)} className="px-4 py-2 border border-slate-200 text-slate-600 rounded-lg text-sm font-medium hover:bg-white">Cancel</button>
|
|
|
|
|
<button
|
|
|
|
|
onClick={() => {
|
|
|
|
|
if (!uploadDocForm.docType || !uploadDocForm.docFile) {
|
|
|
|
|
toast.error('Please fill all required fields');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
toast.success('Document uploaded successfully!');
|
|
|
|
|
setShowUploadDocModal(false);
|
|
|
|
|
setUploadDocForm({ docType: '', docNumber: '', docFile: null });
|
|
|
|
|
}}
|
|
|
|
|
className="px-4 py-2 bg-investor text-white rounded-lg text-sm font-medium hover:bg-investor-dark"
|
|
|
|
|
>
|
|
|
|
|
Upload
|
|
|
|
|
</button>
|
2026-05-15 02:16:32 +06:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
2026-05-15 17:56:16 +06:00
|
|
|
)}
|
2026-05-19 20:45:10 +06:00
|
|
|
|
|
|
|
|
{showApprovalModal && (
|
|
|
|
|
<div className="fixed inset-0 bg-black/60 backdrop-blur-sm flex items-center justify-center z-50 p-4">
|
|
|
|
|
<div className="bg-white rounded-2xl shadow-2xl w-full max-w-md overflow-hidden border border-slate-100 animate-in fade-in zoom-in duration-200">
|
|
|
|
|
<div className="p-6 text-center space-y-4">
|
|
|
|
|
<div className="w-16 h-16 bg-amber-50 rounded-full flex items-center justify-center mx-auto text-amber-500 border border-amber-200">
|
|
|
|
|
<ShieldCheck className="w-8 h-8" />
|
|
|
|
|
</div>
|
|
|
|
|
<div className="space-y-2">
|
|
|
|
|
<h3 className="text-xl font-bold text-slate-800">Verification Request Submitted</h3>
|
|
|
|
|
<p className="text-sm text-slate-500 leading-relaxed">
|
|
|
|
|
Your request to <strong className="text-slate-700">{approvalModalConfig.actionType}</strong> your <strong className="text-slate-700">{approvalModalConfig.fieldName}</strong> has been successfully sent to JAIBEN administrators.
|
|
|
|
|
</p>
|
|
|
|
|
<p className="text-xs text-slate-400 bg-slate-50 p-2.5 rounded-lg border border-slate-100 italic">
|
|
|
|
|
For security reasons, all updates to bank credentials, mobile wallets, or tax IDs require manual review. You will be notified once our team verifies the changes.
|
|
|
|
|
</p>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div className="p-4 bg-slate-50 border-t border-slate-100 flex justify-center">
|
|
|
|
|
<button
|
|
|
|
|
onClick={() => setShowApprovalModal(false)}
|
|
|
|
|
className="w-full py-2.5 bg-investor hover:bg-investor-dark text-white rounded-xl text-sm font-semibold transition-all shadow-md shadow-investor/10"
|
|
|
|
|
>
|
|
|
|
|
Understood & Continue
|
|
|
|
|
</button>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
2026-05-15 17:56:16 +06:00
|
|
|
</div>
|
2026-05-15 01:25:48 +06:00
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
}
|