Files
JML/src/app/admin/kyc/page.tsx

2596 lines
128 KiB
TypeScript
Raw Normal View History

'use client';
import { useState, useEffect } from 'react';
import Link from 'next/link';
import { useRouter } from 'next/navigation';
import {
Shield, Search, Filter, Check, X, Clock, User, Phone, MapPin, FileText,
Eye, Download, Send, MessageSquare, AlertCircle, DollarSign, Bike,
Store, Users, ChevronDown, ChevronUp, Bell, MoreHorizontal, Image as ImageIcon,
Upload, CheckCircle, XCircle, Camera, AlertTriangle, Edit, Globe, Wallet, Calendar,
CreditCard, FileSignature, MapPinned, Key, BatteryCharging, Briefcase, Plus
} from 'lucide-react';
import toast from 'react-hot-toast';
export type ApplicationSource = 'app' | 'web' | 'walkin' | 'referral';
export type KYCType = 'biker' | 'investor' | 'swapstation' | 'merchant' | 'general';
export type RiderPlan = 'single_rent' | 'rent_to_own' | 'share_ev';
export type VerificationStage = 'application' | 'document_collection' | 'risk_check' | 'plan_selection' | 'payment' | 'agreement' | 'allocated' | 'active';
interface NomineeDetails {
name: string;
phone: string;
relationship: string;
nid: string;
}
interface EmploymentInfo {
company: string;
monthlyEarning: number;
whyEV: string;
experience: string;
}
interface RiskCheck {
nidVerified: boolean;
nomineeNidVerified: boolean;
deliveryPlatformStatus: 'active' | 'inactive' | 'suspended';
paymentReliability: 'good' | 'fair' | 'poor';
notes: string;
checkedAt?: string;
checkedBy?: string;
}
interface Agreement {
dailyRentObligation: number;
latePenalty: number;
damageTerms: string;
vehicleRules: string;
signedAt?: string;
signedBy?: string;
}
interface EVAllocation {
evId?: string;
bikeModel?: string;
batteryId?: string;
hubLocation?: string;
assignedAt?: string;
gpsActivated: boolean;
checklist?: string[];
}
interface Document {
id: string;
name: string;
status: 'pending' | 'uploaded' | 'approved' | 'rejected';
imageUrl?: string;
rejectedReason?: string;
uploadedAt?: string;
}
interface Request {
id: string;
applicationSource: ApplicationSource;
sourceDetails?: string;
name: string;
phone: string;
email: string;
type: KYCType;
status: 'pending' | 'documents_needed' | 'under_review' | 'risk_check' | 'approved' | 'rejected';
verificationStage: VerificationStage;
submittedAt: string;
location: string;
address: string;
requiredDocuments: Document[];
riderPlan?: RiderPlan;
nomineeDetails?: NomineeDetails;
employmentInfo?: EmploymentInfo;
riskCheck?: RiskCheck;
agreement?: Agreement;
evAllocation?: EVAllocation;
securityDeposit?: number;
advancePayment?: number;
paymentMethod?: 'bank' | 'wallet' | 'cash';
bikeRequested?: string;
scheduleDate?: string;
appointmentDate?: string;
notes: string[];
smsHistory: { id: string; message: string; sentAt: string; sentBy: string }[];
}
const mockRequests: Request[] = [
{
id: 'REQ001',
applicationSource: 'app',
name: 'Rahim Ahmed',
phone: '01712345678',
email: 'rahim@email.com',
type: 'biker',
status: 'pending',
verificationStage: 'application',
submittedAt: '2024-03-20',
location: 'Gulshan, Dhaka',
address: 'House 12, Road 5, Gulshan 1',
requiredDocuments: [
{ id: 'd1', name: 'NID Front', status: 'uploaded', uploadedAt: '2024-03-20' },
{ id: 'd2', name: 'NID Back', status: 'uploaded', uploadedAt: '2024-03-20' },
{ id: 'd3', name: 'Driving License', status: 'pending' },
{ id: 'd4', name: 'Profile Photo', status: 'uploaded', uploadedAt: '2024-03-20' },
],
riderPlan: 'single_rent',
employmentInfo: { company: 'Foodpanda', monthlyEarning: 2500, whyEV: 'Low maintenance, good for delivery', experience: '3 years bike riding' },
notes: ['Downloaded app and applied through mobile'],
smsHistory: [],
},
{
id: 'REQ002',
applicationSource: 'walkin',
sourceDetails: 'Gulshan Hub',
name: 'Karim Hasan',
phone: '01712345679',
email: 'karim@email.com',
type: 'investor',
status: 'documents_needed',
verificationStage: 'document_collection',
submittedAt: '2024-03-19',
location: 'Banani, Dhaka',
address: 'Flat 3B, House 22, Banani',
requiredDocuments: [
{ id: 'd5', name: 'NID', status: 'uploaded', uploadedAt: '2024-03-19' },
{ id: 'd6', name: 'TIN Certificate', status: 'pending' },
{ id: 'd7', name: 'Bank Statement', status: 'pending' },
],
smsHistory: [
{ id: 'sms1', message: 'Please upload your TIN certificate and latest bank statement', sentAt: '2024-03-19', sentBy: 'admin' },
{ id: 'sms2', message: 'I will upload them today', sentAt: '2024-03-19', sentBy: 'user' },
],
notes: ['Walked in at Gulshan office - referred by current biker'],
},
{
id: 'REQ003',
applicationSource: 'web',
name: 'Jamal Store',
phone: '01712345680',
email: 'jamal@shop.com',
type: 'swapstation',
status: 'under_review',
verificationStage: 'plan_selection',
submittedAt: '2024-03-18',
location: 'Mirpur, Dhaka',
address: 'Shop 45, Mirpur Market',
requiredDocuments: [
{ id: 'd8', name: 'Trade License', status: 'uploaded', uploadedAt: '2024-03-18' },
{ id: 'd9', name: 'NID', status: 'uploaded', uploadedAt: '2024-03-18' },
{ id: 'd10', name: 'Shop Photos', status: 'uploaded', uploadedAt: '2024-03-18' },
],
notes: ['Applied through website'],
smsHistory: [],
},
{
id: 'REQ004',
applicationSource: 'app',
name: 'Sofiq Rahman',
phone: '01712345681',
email: 'sofiq@email.com',
type: 'biker',
status: 'approved',
verificationStage: 'active',
submittedAt: '2024-03-15',
location: 'Dhanmondi, Dhaka',
address: 'Road 8, Dhanmondi',
requiredDocuments: [
{ id: 'd11', name: 'NID', status: 'approved', uploadedAt: '2024-03-15' },
{ id: 'd12', name: 'Driving License', status: 'approved', uploadedAt: '2024-03-15' },
{ id: 'd13', name: 'Profile Photo', status: 'approved', uploadedAt: '2024-03-15' },
],
riderPlan: 'rent_to_own',
nomineeDetails: { name: 'Fatema Begum', phone: '01712345699', relationship: 'Wife', nid: '1234567890123' },
employmentInfo: { company: 'Pathao', monthlyEarning: 3000, whyEV: 'Want to own EV eventually', experience: '5 years motorcycle experience' },
riskCheck: { nidVerified: true, nomineeNidVerified: true, deliveryPlatformStatus: 'active', paymentReliability: 'good', notes: 'Verified - clean record', checkedAt: '2024-03-15', checkedBy: 'Admin' },
agreement: { dailyRentObligation: 500, latePenalty: 100, damageTerms: 'Standard terms', vehicleRules: 'Follow JAIBEN guidelines', signedAt: '2024-03-15', signedBy: 'Sofiq Rahman' },
evAllocation: { evId: 'EV-004', bikeModel: 'AIMA Lightning', batteryId: 'BAT-044', hubLocation: 'Dhanmondi Hub', assignedAt: '2024-03-15', gpsActivated: true, checklist: ['Front light working', 'Brakes OK', 'Horn working', 'Tire pressure OK'] },
securityDeposit: 10000,
advancePayment: 500,
paymentMethod: 'bank',
bikeRequested: 'AIMA Lightning',
scheduleDate: '2024-03-15',
appointmentDate: '2024-03-15',
notes: ['Approved and active - EV allocated'],
smsHistory: [],
},
{
id: 'REQ005',
applicationSource: 'referral',
sourceDetails: 'Rahim (BIKER-001)',
name: 'Mizanur Investment',
phone: '01712345682',
email: 'mizan@invest.com',
type: 'investor',
status: 'rejected',
verificationStage: 'application',
submittedAt: '2024-03-10',
location: 'Uttara, Dhaka',
address: 'Sector 4, Uttara',
requiredDocuments: [
{ id: 'd14', name: 'NID', status: 'rejected', rejectedReason: 'Image is blurry and unreadable', uploadedAt: '2024-03-10' },
{ id: 'd15', name: 'TIN Certificate', status: 'uploaded', uploadedAt: '2024-03-10' },
{ id: 'd16', name: 'Bank Statement', status: 'uploaded', uploadedAt: '2024-03-10' },
],
smsHistory: [
{ id: 'sms3', message: 'Your NID document is not clear. Please re-upload.', sentAt: '2024-03-10', sentBy: 'admin' },
],
notes: ['NID was unclear/blurry'],
},
{
id: 'REQ006',
applicationSource: 'web',
name: 'Ripon Mia',
phone: '01712345683',
email: 'ripon@email.com',
type: 'biker',
status: 'under_review',
verificationStage: 'risk_check',
submittedAt: '2024-03-21',
location: 'Mohakhali, Dhaka',
address: 'House 8, Mohakhali',
requiredDocuments: [
{ id: 'd17', name: 'NID', status: 'uploaded', uploadedAt: '2024-03-21' },
{ id: 'd18', name: 'Driving License', status: 'uploaded', uploadedAt: '2024-03-21' },
{ id: 'd19', name: 'Profile Photo', status: 'uploaded', uploadedAt: '2024-03-21' },
],
riderPlan: 'single_rent',
nomineeDetails: { name: 'Rashid', phone: '01798765432', relationship: 'Brother', nid: '9876543210987' },
employmentInfo: { company: ' ssl', monthlyEarning: 2000, whyEV: 'Better income than fuel bike', experience: '2 years' },
notes: [],
smsHistory: [],
},
];
const statusColors: Record<string, string> = {
pending: 'bg-amber-100 text-amber-700',
documents_needed: 'bg-orange-100 text-orange-700',
under_review: 'bg-blue-100 text-blue-700',
risk_check: 'bg-purple-100 text-purple-700',
approved: 'bg-green-100 text-green-700',
rejected: 'bg-red-100 text-red-700',
};
const statusLabels: Record<string, string> = {
pending: 'Pending',
documents_needed: 'Documents Needed',
under_review: 'Under Review',
risk_check: 'Risk Check',
approved: 'Approved',
rejected: 'Rejected',
};
const stageLabels: Record<string, string> = {
application: 'Application',
document_collection: 'Documents',
risk_check: 'Risk Check',
plan_selection: 'Plan Selection',
payment: 'Payment',
agreement: 'Agreement',
allocated: 'EV Allocated',
active: 'Active',
};
const sourceLabels: Record<string, string> = {
app: 'Mobile App',
web: 'Website',
walkin: 'Walk-in',
referral: 'Referral',
};
const sourceColors: Record<string, string> = {
app: 'bg-blue-100 text-blue-700',
web: 'bg-green-100 text-green-700',
walkin: 'bg-amber-100 text-amber-700',
referral: 'bg-purple-100 text-purple-700',
};
const planLabels: Record<string, string> = {
daily_rent: 'Daily Rent',
weekly_rent: 'Weekly Rent',
monthly_rent: 'Monthly Rent',
rent_to_own: 'Rent-to-Own',
share_ev: 'Share EV',
};
const typeIcons: Record<string, any> = {
biker: Bike,
investor: DollarSign,
swapstation: Store,
merchant: Users,
};
const typeColors: Record<string, string> = {
biker: 'bg-blue-100 text-blue-700',
investor: 'bg-purple-100 text-purple-700',
swapstation: 'bg-green-100 text-green-700',
merchant: 'bg-orange-100 text-orange-700',
general: 'bg-slate-100 text-slate-700',
};
const sourceIcons: Record<string, any> = {
app: Phone,
web: Globe,
walkin: User,
referral: Users,
};
export default function RequestsPage() {
const router = useRouter();
const [activeTab, setActiveTab] = useState<'all' | 'biker' | 'investor' | 'swapstation' | 'merchant'>('all');
const [requests, setRequests] = useState<Request[]>(mockRequests);
const [searchQuery, setSearchQuery] = useState('');
const [statusFilter, setStatusFilter] = useState('all');
const [hubFilter, setHubFilter] = useState('all');
const [selectedRequest, setSelectedRequest] = useState<Request | null>(null);
const [showMessageModal, setShowMessageModal] = useState(false);
const [showDetailsModal, setShowDetailsModal] = useState(false);
const [showNewApplicationModal, setShowNewApplicationModal] = useState(false);
const [messageText, setMessageText] = useState('');
const [showActionModal, setShowActionModal] = useState(false);
const [actionType, setActionType] = useState<'approve' | 'reject' | 'documents'>('approve');
const [rejectReason, setRejectReason] = useState('');
const [selectedDocId, setSelectedDocId] = useState<string | null>(null);
const handleApproveDocument = (docId: string) => {
if (!selectedRequest) return;
const updatedRequests = requests.map(req => {
if (req.id === selectedRequest.id) {
return {
...req,
requiredDocuments: req.requiredDocuments.map(doc =>
doc.id === docId ? { ...doc, status: 'approved' as const } : doc
)
};
}
return req;
});
setRequests(updatedRequests);
toast.success('Document approved!');
};
const handleRejectDocument = (docId: string, reason: string) => {
if (!selectedRequest || !reason.trim()) {
toast.error('Please enter a reason for rejection');
return;
}
const updatedRequests = requests.map(req => {
if (req.id === selectedRequest.id) {
return {
...req,
requiredDocuments: req.requiredDocuments.map(doc =>
doc.id === docId ? { ...doc, status: 'rejected' as const, rejectedReason: reason } : doc
)
};
}
return req;
});
setRequests(updatedRequests);
setRejectReason('');
toast.error('Document rejected!');
};
const filteredRequests = requests.filter(req => {
const matchesTab = activeTab === 'all' || req.type === activeTab;
const matchesSearch = req.name.toLowerCase().includes(searchQuery.toLowerCase()) ||
req.phone.includes(searchQuery) ||
req.email.toLowerCase().includes(searchQuery.toLowerCase()) ||
req.id.toLowerCase().includes(searchQuery.toLowerCase());
const matchesStatus = statusFilter === 'all' || req.status === statusFilter;
const matchesHub = hubFilter === 'all' || req.sourceDetails?.toLowerCase().includes(hubFilter.toLowerCase());
return matchesTab && matchesSearch && matchesStatus && matchesHub;
});
const pending = requests.filter(r => r.status === 'pending' || r.status === 'documents_needed').length;
const underReview = requests.filter(r => r.status === 'under_review').length;
const approved = requests.filter(r => r.status === 'approved').length;
const handleSendMessage = () => {
if (selectedRequest && messageText.trim()) {
const updatedRequests = requests.map(req => {
if (req.id === selectedRequest.id) {
return {
...req,
status: 'documents_needed' as const,
smsHistory: [
...req.smsHistory,
{ id: `sms-${Date.now()}`, message: messageText, sentAt: new Date().toISOString(), sentBy: 'admin' }
],
notes: [...req.notes, messageText]
};
}
return req;
});
setRequests(updatedRequests);
setShowMessageModal(false);
setMessageText('');
toast.success(`SMS sent to ${selectedRequest.phone}`);
}
};
const handleAction = (request: Request, action: 'approve' | 'reject' | 'documents') => {
setSelectedRequest(request);
setActionType(action);
setShowActionModal(true);
};
const confirmAction = () => {
if (!selectedRequest) return;
let newStatus: Request['status'] = selectedRequest.status;
let successMessage = '';
if (actionType === 'approve') {
newStatus = 'approved';
successMessage = selectedRequest.type === 'biker'
? `Approved! SMS sent to ${selectedRequest.phone}: Welcome! Your biker request has been approved.`
: `Approved! SMS sent to ${selectedRequest.phone}: Welcome! Your investor request has been approved.`;
} else if (actionType === 'reject') {
newStatus = 'rejected';
successMessage = `Rejected! SMS sent to ${selectedRequest.phone}: Sorry, your request has been rejected.`;
} else if (actionType === 'documents') {
newStatus = 'documents_needed';
successMessage = `Documents requested! SMS sent to ${selectedRequest.phone}: Please upload required documents.`;
}
const updatedRequests = requests.map(req =>
req.id === selectedRequest.id ? { ...req, status: newStatus } : req
);
setRequests(updatedRequests);
setShowActionModal(false);
toast.success(successMessage);
};
return (
<div className="p-4 lg:p-6">
<div className="flex flex-col lg:flex-row lg:items-center lg:justify-between gap-4 mb-6">
<div>
<h1 className="text-2xl lg:text-3xl font-extrabold text-slate-800">Requests & Verification</h1>
<p className="text-sm text-slate-500 mt-1">Manage biker, investor, and shop requests</p>
</div>
<div className="flex items-center gap-2">
<button
onClick={() => setShowNewApplicationModal(true)}
className="py-2 px-4 bg-accent text-white rounded-lg text-sm font-medium hover:bg-accent-dark flex items-center gap-2"
>
<Plus className="w-4 h-4" /> New Application
</button>
<button className="py-2 px-4 border border-slate-200 rounded-lg text-sm font-medium text-slate-600 hover:bg-slate-50 flex items-center gap-2">
<Download className="w-4 h-4" /> Export
</button>
</div>
</div>
<div className="grid grid-cols-2 lg:grid-cols-4 gap-4 mb-6">
<div className="bg-white rounded-xl p-5 shadow-sm border border-slate-100">
<div className="flex items-center gap-3">
<div className="w-12 h-12 rounded-xl bg-amber-50 flex items-center justify-center">
<Clock className="w-6 h-6 text-amber-600" />
</div>
<div>
<p className="text-2xl font-extrabold text-slate-800">{pending}</p>
<p className="text-sm text-slate-500">Pending</p>
</div>
</div>
</div>
<div className="bg-white rounded-xl p-5 shadow-sm border border-slate-100">
<div className="flex items-center gap-3">
<div className="w-12 h-12 rounded-xl bg-blue-50 flex items-center justify-center">
<Eye className="w-6 h-6 text-blue-600" />
</div>
<div>
<p className="text-2xl font-extrabold text-slate-800">{underReview}</p>
<p className="text-sm text-slate-500">Under Review</p>
</div>
</div>
</div>
<div className="bg-white rounded-xl p-5 shadow-sm border border-slate-100">
<div className="flex items-center gap-3">
<div className="w-12 h-12 rounded-xl bg-green-50 flex items-center justify-center">
<Check className="w-6 h-6 text-green-600" />
</div>
<div>
<p className="text-2xl font-extrabold text-slate-800">{approved}</p>
<p className="text-sm text-slate-500">Approved</p>
</div>
</div>
</div>
<div className="bg-white rounded-xl p-5 shadow-sm border border-slate-100">
<div className="flex items-center gap-3">
<div className="w-12 h-12 rounded-xl bg-slate-100 flex items-center justify-center">
<Users className="w-6 h-6 text-slate-600" />
</div>
<div>
<p className="text-2xl font-extrabold text-slate-800">{requests.length}</p>
<p className="text-sm text-slate-500">Total Requests</p>
</div>
</div>
</div>
</div>
<div className="bg-white rounded-xl shadow-sm border border-slate-100 mb-6">
<div className="p-4 border-b border-slate-100">
<div className="flex flex-col lg:flex-row lg:items-center gap-4">
<div className="flex items-center gap-2 flex-wrap">
<button
onClick={() => setActiveTab('all')}
className={`px-3 py-1.5 rounded-lg text-sm font-medium ${activeTab === 'all' ? 'bg-slate-800 text-white' : 'border border-slate-200 text-slate-600 hover:bg-slate-50'}`}
>
All
</button>
<button
onClick={() => setActiveTab('biker')}
className={`px-3 py-1.5 rounded-lg text-sm font-medium flex items-center gap-1 ${activeTab === 'biker' ? 'bg-slate-800 text-white' : 'border border-slate-200 text-slate-600 hover:bg-slate-50'}`}
>
<Bike className="w-4 h-4" /> Bikers
</button>
<button
onClick={() => setActiveTab('investor')}
className={`px-3 py-1.5 rounded-lg text-sm font-medium flex items-center gap-1 ${activeTab === 'investor' ? 'bg-slate-800 text-white' : 'border border-slate-200 text-slate-600 hover:bg-slate-50'}`}
>
<DollarSign className="w-4 h-4" /> Investors
</button>
<button
onClick={() => setActiveTab('swapstation')}
className={`px-3 py-1.5 rounded-lg text-sm font-medium flex items-center gap-1 ${activeTab === 'swapstation' ? 'bg-slate-800 text-white' : 'border border-slate-200 text-slate-600 hover:bg-slate-50'}`}
>
<Store className="w-4 h-4" /> Swap Stations
</button>
<button
onClick={() => setActiveTab('merchant')}
className={`px-3 py-1.5 rounded-lg text-sm font-medium flex items-center gap-1 ${activeTab === 'merchant' ? 'bg-slate-800 text-white' : 'border border-slate-200 text-slate-600 hover:bg-slate-50'}`}
>
<Users className="w-4 h-4" /> Merchants
</button>
</div>
<div className="flex-1">
<div className="relative">
<Search className="w-4 h-4 absolute left-3 top-1/2 -translate-y-1/2 text-slate-400" />
<input
type="text"
placeholder="Search by name, phone, email..."
value={searchQuery}
onChange={(e) => setSearchQuery(e.target.value)}
className="w-full lg:w-64 pl-9 pr-4 py-2 border border-slate-200 rounded-lg text-sm"
/>
</div>
</div>
<select
value={statusFilter}
onChange={(e) => setStatusFilter(e.target.value)}
className="py-2 px-3 border border-slate-200 rounded-lg text-sm font-medium text-slate-600"
>
<option value="all">All Status</option>
<option value="pending">Pending</option>
<option value="documents_needed">Documents Needed</option>
<option value="under_review">Under Review</option>
<option value="risk_check">Risk Check</option>
<option value="approved">Approved</option>
<option value="rejected">Rejected</option>
</select>
<select
value={hubFilter}
onChange={(e) => setHubFilter(e.target.value)}
className="py-2 px-3 border border-slate-200 rounded-lg text-sm font-medium text-slate-600"
>
<option value="all">All Hubs</option>
<option value="Gulshan">Gulshan Hub</option>
<option value="Banani">Banani Hub</option>
<option value="Dhanmondi">Dhanmondi Hub</option>
<option value="Mirpur">Mirpur Hub</option>
<option value="Uttara">Uttara Hub</option>
</select>
</div>
</div>
<div className="divide-y divide-slate-50">
{filteredRequests.map(request => {
const TypeIcon = typeIcons[request.type];
return (
<Link key={request.id} href={`/admin/kyc/${request.id}`} className="block p-5 hover:bg-slate-50 transition-colors">
<div className="flex flex-col lg:flex-row lg:items-start gap-4">
<div className="flex items-center gap-4">
<div className="w-12 h-12 rounded-full bg-slate-100 flex items-center justify-center">
<User className="w-6 h-6 text-slate-600" />
</div>
<div>
<div className="flex items-center gap-2">
<p className="font-semibold text-slate-800">{request.name}</p>
<span className={`inline-flex items-center gap-1 text-xs font-medium px-2 py-0.5 rounded-full ${typeColors[request.type]}`}>
<TypeIcon className="w-3 h-3" /> {request.type}
</span>
<span className={`inline-flex items-center gap-1 text-xs font-medium px-2 py-0.5 rounded-full ${sourceColors[request.applicationSource]}`}>
<Phone className="w-3 h-3" /> {sourceLabels[request.applicationSource]}
</span>
</div>
<p className="text-sm text-slate-500 flex items-center gap-2">
<Phone className="w-3 h-3" /> {request.phone}
<span className="text-slate-300">|</span>
<MapPin className="w-3 h-3" /> {request.location}
</p>
</div>
</div>
<div className="flex-1">
<div className="flex flex-wrap gap-4 text-sm text-slate-600">
<p className="flex items-center gap-1">
<Clock className="w-3 h-3" /> {request.submittedAt}
</p>
<p className="flex items-center gap-1">
<FileText className="w-3 h-3" /> Docs: {request.requiredDocuments.filter(d => d.status === 'uploaded' || d.status === 'approved').length}/{request.requiredDocuments.length}
</p>
{request.type === 'biker' && request.verificationStage && (
<span className={`inline-flex items-center gap-1 text-xs font-medium px-2 py-0.5 rounded-full bg-cyan-100 text-cyan-700`}>
<Check className="w-3 h-3" /> {stageLabels[request.verificationStage]}
</span>
)}
{request.smsHistory.length > 0 && (
<p className="flex items-center gap-1 text-blue-600">
<MessageSquare className="w-3 h-3" /> {request.smsHistory.length} msg
</p>
)}
</div>
</div>
<div className="flex items-center gap-3">
<span className={`inline-flex items-center gap-1 text-xs font-medium px-2.5 py-1 rounded-full ${statusColors[request.status]}`}>
{request.status === 'pending' && <Clock className="w-3 h-3" />}
{request.status === 'documents_needed' && <AlertCircle className="w-3 h-3" />}
{request.status === 'under_review' && <Eye className="w-3 h-3" />}
{request.status === 'approved' && <Check className="w-3 h-3" />}
{request.status === 'rejected' && <X className="w-3 h-3" />}
{statusLabels[request.status]}
</span>
{request.status !== 'approved' && request.status !== 'rejected' && (
<div className="flex gap-2">
{request.type === 'biker' && request.status === 'under_review' && (
<button
onClick={() => handleAction(request, 'approve')}
className="py-1.5 px-3 bg-green-600 text-white text-xs font-semibold rounded-lg hover:bg-green-700 flex items-center gap-1"
>
<Check className="w-3 h-3" /> Make Biker
</button>
)}
{request.type === 'investor' && request.status === 'under_review' && (
<button
onClick={() => handleAction(request, 'approve')}
className="py-1.5 px-3 bg-purple-600 text-white text-xs font-semibold rounded-lg hover:bg-purple-700 flex items-center gap-1"
>
<DollarSign className="w-3 h-3" /> Make Investor
</button>
)}
{request.type === 'swapstation' && request.status === 'under_review' && (
<button
onClick={() => handleAction(request, 'approve')}
className="py-1.5 px-3 bg-green-600 text-white text-xs font-semibold rounded-lg hover:bg-green-700 flex items-center gap-1"
>
<Store className="w-3 h-3" /> Approve Shop
</button>
)}
<button
onClick={(e) => { e.preventDefault(); router.push(`/admin/kyc/${request.id}`); }}
className="py-1.5 px-3 border border-slate-200 text-slate-600 text-xs font-semibold rounded-lg hover:bg-slate-50 flex items-center gap-1"
>
<Eye className="w-3 h-3" /> Details
</button>
</div>
)}
</div>
</div>
</Link>
);
})}
{filteredRequests.length === 0 && (
<div className="p-12 text-center">
<Users className="w-12 h-12 text-slate-300 mx-auto mb-4" />
<p className="text-slate-500">No requests found</p>
</div>
)}
</div>
</div>
{showMessageModal && selectedRequest && (
<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-4 border-b border-slate-100 flex items-center justify-between">
<h3 className="font-semibold text-slate-800">SMS to {selectedRequest.phone}</h3>
<button onClick={() => setShowMessageModal(false)} className="p-1 hover:bg-slate-100 rounded">
<X className="w-5 h-5 text-slate-400" />
</button>
</div>
<div className="p-4 space-y-4">
<div className="bg-slate-50 p-3 rounded-lg">
<p className="text-sm text-slate-600">Phone: {selectedRequest.phone}</p>
<p className="text-sm text-slate-600">Type: {selectedRequest.type}</p>
</div>
<div>
<label className="text-sm font-medium text-slate-600 mb-2 block">Quick Messages</label>
<div className="flex flex-wrap gap-2">
<button
onClick={() => setMessageText('Please upload your required documents to proceed with your KYC application.')}
className="px-3 py-1.5 bg-slate-100 text-slate-600 text-xs rounded-lg hover:bg-slate-200"
>
Documents Required
</button>
<button
onClick={() => setMessageText('Your KYC application is now under review. We will notify you once the process is completed.')}
className="px-3 py-1.5 bg-slate-100 text-slate-600 text-xs rounded-lg hover:bg-slate-200"
>
Under Review
</button>
<button
onClick={() => setMessageText('Your application is pending final approval. You will be notified once approved.')}
className="px-3 py-1.5 bg-slate-100 text-slate-600 text-xs rounded-lg hover:bg-slate-200"
>
Pending Approval
</button>
</div>
</div>
<div>
<label className="text-sm font-medium text-slate-600 mb-2 block">Message</label>
<textarea
value={messageText}
onChange={(e) => setMessageText(e.target.value)}
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm"
rows={4}
placeholder="Type your message..."
></textarea>
<p className="text-xs text-slate-400 mt-1">This message will be sent via SMS to {selectedRequest.phone}</p>
</div>
</div>
<div className="p-4 border-t border-slate-100 flex justify-end gap-2">
<button
onClick={() => setShowMessageModal(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={handleSendMessage}
disabled={!messageText.trim()}
className="px-4 py-2 bg-accent text-white rounded-lg text-sm hover:bg-accent-dark disabled:opacity-50 flex items-center gap-2"
>
<Send className="w-4 h-4" /> Send Message
</button>
</div>
</div>
</div>
)}
{showDetailsModal && selectedRequest && (
<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">
<div className="p-4 border-b border-slate-100 flex items-center justify-between">
<h3 className="font-semibold text-slate-800">Request Details - {selectedRequest.id}</h3>
<button onClick={() => setShowDetailsModal(false)} className="p-1 hover:bg-slate-100 rounded">
<X className="w-5 h-5 text-slate-400" />
</button>
</div>
<div className="p-4 overflow-y-auto max-h-[70vh]">
<div className="grid grid-cols-2 gap-4 mb-6">
<div className="bg-slate-50 p-4 rounded-lg">
<p className="text-xs text-slate-500">Name</p>
<p className="font-semibold text-slate-800">{selectedRequest.name}</p>
</div>
<div className="bg-slate-50 p-4 rounded-lg">
<p className="text-xs text-slate-500">Phone</p>
<p className="font-semibold text-slate-800">{selectedRequest.phone}</p>
</div>
<div className="bg-slate-50 p-4 rounded-lg">
<p className="text-xs text-slate-500">Email</p>
<p className="font-semibold text-slate-800">{selectedRequest.email}</p>
</div>
<div className="bg-slate-50 p-4 rounded-lg">
<p className="text-xs text-slate-500">Location</p>
<p className="font-semibold text-slate-800">{selectedRequest.location}</p>
</div>
</div>
{selectedRequest.type === 'biker' && (
<div className="mb-6">
<h4 className="font-semibold text-slate-700 mb-3 flex items-center gap-2">
<Bike className="w-5 h-5 text-accent" /> Bike Details
</h4>
<div className="bg-slate-50 p-4 rounded-lg">
<div className="grid grid-cols-2 gap-4">
<div>
<label className="text-xs text-slate-500 block mb-1">Bike Model</label>
<select
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm"
value={selectedRequest.bikeRequested || ''}
onChange={(e) => {
const updated = requests.map(r =>
r.id === selectedRequest.id
? { ...r, bikeRequested: e.target.value }
: r
);
setRequests(updated);
}}
>
<option value="">Select Bike Model</option>
<option value="AIMA Lightning">AIMA Lightning</option>
<option value="Yadea DT3">Yadea DT3</option>
<option value="Etron ET50">Etron ET50</option>
<option value="AIMA i3">AIMA i3</option>
<option value="TVS iQube">TVS iQube</option>
<option value="Benling Aura">Benling Aura</option>
<option value="Okinawa Ridge">Okinawa Ridge</option>
<option value="Hero Optima">Hero Optima</option>
<option value="Ampere Magnus">Ampere Magnus</option>
<option value="Other">Other</option>
</select>
</div>
<div>
<label className="text-xs text-slate-500 block mb-1">Brand</label>
<input
type="text"
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm"
placeholder="Enter details"
value={selectedRequest.evAllocation?.bikeModel || ''}
onChange={(e) => {
const updated = requests.map(r =>
r.id === selectedRequest.id
? { ...r, evAllocation: { ...r.evAllocation!, bikeModel: e.target.value } }
: r
);
setRequests(updated);
}}
/>
</div>
</div>
</div>
</div>
)}
<div className="mb-6">
<h4 className="font-semibold text-slate-700 mb-3 flex items-center gap-2">
<FileText className="w-5 h-5 text-accent" /> Documents
</h4>
<div className="space-y-2">
{selectedRequest.requiredDocuments.map((doc, idx) => (
<div key={idx} className="flex items-center justify-between p-3 bg-slate-50 rounded-lg">
<div className="flex items-center gap-2">
{doc.status === 'pending' ? (
<Upload className="w-4 h-4 text-amber-400" />
) : doc.status === 'uploaded' ? (
<FileText className="w-4 h-4 text-blue-400" />
) : doc.status === 'approved' ? (
<CheckCircle className="w-4 h-4 text-green-500" />
) : (
<XCircle className="w-4 h-4 text-red-500" />
)}
<div>
<span className="text-sm text-slate-600">{doc.name}</span>
{doc.uploadedAt && <span className="text-xs text-slate-400 ml-2">{doc.uploadedAt}</span>}
</div>
</div>
<div className="flex items-center gap-2">
{doc.status === 'pending' && (
<span className="text-xs text-amber-600 flex items-center gap-1">
<Upload className="w-3 h-3" /> Waiting for upload
</span>
)}
{(doc.status === 'uploaded' || doc.status === 'approved') && (
<button
onClick={() => handleApproveDocument(doc.id)}
className="p-1.5 bg-green-100 text-green-600 rounded-lg hover:bg-green-200"
title="Approve"
>
<CheckCircle className="w-4 h-4" />
</button>
)}
{(doc.status === 'uploaded' || doc.status === 'approved') && (
<button
onClick={() => {
const reason = prompt('Enter rejection reason:');
if (reason) handleRejectDocument(doc.id, reason);
}}
className="p-1.5 bg-red-100 text-red-600 rounded-lg hover:bg-red-200"
title="Reject"
>
<XCircle className="w-4 h-4" />
</button>
)}
{doc.status === 'rejected' && (
<span className="inline-flex items-center gap-1 text-xs font-medium px-2 py-1 rounded-full bg-red-100 text-red-700">
<XCircle className="w-3 h-3" /> Rejected
</span>
)}
{doc.status === 'approved' && (
<span className="inline-flex items-center gap-1 text-xs font-medium px-2 py-1 rounded-full bg-green-100 text-green-700">
<CheckCircle className="w-3 h-3" /> Approved
</span>
)}
{doc.status === 'rejected' && doc.rejectedReason && (
<div className="text-xs text-red-600 mt-1">Reason: {doc.rejectedReason}</div>
)}
</div>
</div>
))}
</div>
</div>
{selectedRequest.type === 'biker' && selectedRequest.bikeRequested && (
<div className="mb-6">
<h4 className="font-semibold text-slate-700 mb-3 flex items-center gap-2">
<Camera className="w-5 h-5 text-accent" /> Bike Images (When Taking Bike)
</h4>
<div className="grid grid-cols-4 gap-3">
{['Front', 'Back', 'Left Side', 'Right Side'].map((view) => (
<div key={view} className="aspect-square bg-slate-100 rounded-lg flex flex-col items-center justify-center cursor-pointer hover:bg-slate-200 transition-colors">
<Camera className="w-8 h-8 text-slate-400 mb-2" />
<span className="text-xs text-slate-500">{view}</span>
<span className="text-xs text-amber-500 mt-1">Upload</span>
</div>
))}
</div>
<button className="mt-3 px-4 py-2 border border-dashed border-slate-300 rounded-lg text-sm text-slate-500 hover:border-accent hover:text-accent w-full">
+ Add More Images
</button>
</div>
)}
{selectedRequest.smsHistory.length > 0 && (
<div className="mb-6">
<h4 className="font-semibold text-slate-700 mb-3">SMS History</h4>
<div className="space-y-2">
{selectedRequest.smsHistory.slice().reverse().map((msg) => (
<div key={msg.id} className={`p-3 rounded-lg ${msg.sentBy === 'admin' ? 'bg-blue-50' : 'bg-slate-50'}`}>
<div className="flex items-center justify-between mb-1">
<span className={`text-xs font-medium ${msg.sentBy === 'admin' ? 'text-blue-600' : 'text-slate-600'}`}>
{msg.sentBy === 'admin' ? 'Admin' : 'User'}
</span>
<span className="text-xs text-slate-400">{msg.sentAt}</span>
</div>
<p className="text-sm text-slate-700">{msg.message}</p>
</div>
))}
</div>
</div>
)}
{selectedRequest.notes.length > 0 && (
<div className="mb-6">
<h4 className="font-semibold text-slate-700 mb-3">Notes</h4>
<div className="space-y-2">
{selectedRequest.notes.map((note, idx) => (
<div key={idx} className="p-3 bg-amber-50 rounded-lg">
<p className="text-sm text-slate-700">{note}</p>
</div>
))}
</div>
</div>
)}
</div>
<div className="p-4 border-t border-slate-100 flex justify-end gap-2">
{selectedRequest.status !== 'approved' && selectedRequest.status !== 'rejected' && (
<>
{selectedRequest.type === 'biker' && (
<button
onClick={() => { setShowDetailsModal(false); handleAction(selectedRequest, 'approve'); }}
className="px-4 py-2 bg-green-600 text-white rounded-lg text-sm hover:bg-green-700 flex items-center gap-2"
>
<Check className="w-4 h-4" /> Make Biker
</button>
)}
{selectedRequest.type === 'investor' && (
<button
onClick={() => { setShowDetailsModal(false); handleAction(selectedRequest, 'approve'); }}
className="px-4 py-2 bg-purple-600 text-white rounded-lg text-sm hover:bg-purple-700 flex items-center gap-2"
>
<DollarSign className="w-4 h-4" /> Make Investor
</button>
)}
{selectedRequest.type === 'swapstation' && (
<button
onClick={() => { setShowDetailsModal(false); handleAction(selectedRequest, 'approve'); }}
className="px-4 py-2 bg-green-600 text-white rounded-lg text-sm hover:bg-green-700 flex items-center gap-2"
>
<Store className="w-4 h-4" /> Approve Shop
</button>
)}
</>
)}
<button
onClick={() => setShowDetailsModal(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>
)}
{showActionModal && selectedRequest && (
<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-4 border-b border-slate-100">
<h3 className="font-semibold text-slate-800">
{actionType === 'approve' ? 'Approve Request' : actionType === 'reject' ? 'Reject Request' : 'Request Documents'}
</h3>
</div>
<div className="p-4">
<p className="text-sm text-slate-600 mb-4">
{actionType === 'approve' && `Are you sure you want to approve ${selectedRequest.name} as a ${selectedRequest.type}?`}
{actionType === 'reject' && `Are you sure you want to reject ${selectedRequest.name}'s request?`}
{actionType === 'documents' && `Send a message to ${selectedRequest.name} requesting required documents.`}
</p>
<div className="bg-slate-50 p-3 rounded-lg">
<p className="text-sm"><strong>Name:</strong> {selectedRequest.name}</p>
<p className="text-sm"><strong>Phone:</strong> {selectedRequest.phone}</p>
<p className="text-sm"><strong>Type:</strong> {selectedRequest.type}</p>
</div>
</div>
<div className="p-4 border-t border-slate-100 flex justify-end gap-2">
<button
onClick={() => setShowActionModal(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={confirmAction}
className={`px-4 py-2 text-white rounded-lg text-sm flex items-center gap-2 ${actionType === 'approve' ? 'bg-green-600 hover:bg-green-700' :
actionType === 'reject' ? 'bg-red-600 hover:bg-red-700' :
'bg-amber-600 hover:bg-amber-700'
}`}
>
{actionType === 'approve' && <><Check className="w-4 h-4" /> Confirm Approve</>}
{actionType === 'reject' && <><X className="w-4 h-4" /> Confirm Reject</>}
{actionType === 'documents' && <><Send className="w-4 h-4" /> Send Request</>}
</button>
</div>
</div>
</div>
)}
<NewApplicationModal
isOpen={showNewApplicationModal}
onClose={() => setShowNewApplicationModal(false)}
onSave={(data) => {
const newRequest: Request = {
id: `REQ${String(Date.now()).slice(-6)}`,
applicationSource: data.applicationSource || 'walkin',
sourceDetails: data.sourceDetails || '',
name: data.name || '',
phone: data.phone || '',
email: data.email || '',
type: data.type || 'biker',
location: data.location || '',
address: data.address || '',
status: 'pending',
verificationStage: 'application',
submittedAt: new Date().toISOString().split('T')[0],
requiredDocuments: data.type === 'biker' ? [
{ id: 'doc1', name: 'NID Front', status: 'pending' },
{ id: 'doc2', name: 'NID Back', status: 'pending' },
{ id: 'doc3', name: 'Driving License', status: 'pending' },
{ id: 'doc4', name: 'Profile Photo', status: 'pending' },
] : data.type === 'investor' ? [
{ id: 'doc1', name: 'NID', status: 'pending' },
{ id: 'doc2', name: 'TIN Certificate', status: 'pending' },
{ id: 'doc3', name: 'Bank Statement', status: 'pending' },
] : [
{ id: 'doc1', name: 'NID', status: 'pending' },
{ id: 'doc2', name: 'Trade License', status: 'pending' },
{ id: 'doc3', name: 'Shop Photo', status: 'pending' },
],
riderPlan: data.riderPlan,
employmentInfo: data.employmentInfo,
nomineeDetails: data.nomineeDetails,
securityDeposit: data.securityDeposit,
advancePayment: data.advancePayment,
paymentMethod: data.paymentMethod,
bikeRequested: data.bikeRequested,
scheduleDate: data.scheduleDate,
notes: [],
smsHistory: [],
};
setRequests([newRequest, ...requests]);
setShowNewApplicationModal(false);
toast.success('Application created successfully!');
}}
/>
</div>
);
}
function NewApplicationModal({ isOpen, onClose, onSave }: { isOpen: boolean; onClose: () => void; onSave: (data: Partial<Request>) => void }) {
const [formData, setFormData] = useState<{
applicationSource: string;
sourceDetails: string;
type: string;
status: string;
hubId: string;
name: string;
phone: string;
altPhone: string;
email: string;
dateOfBirth: string;
gender: string;
bloodGroup: string;
occupation: string;
nid: string;
passport: string;
presentAddress: { line1: string; line2: string; division: string; district: string; zip: string; country: string };
permanentAddress: { sameAsPresent: boolean; line1: string; line2: string; division: string; district: string; zip: string; country: string };
emergencyContact: { name: string; phone: string; relation: string; email: string; address: string };
drivingLicense: { number: string; class: string; issueDate: string; expiryDate: string; status: string };
membershipType: string;
referralCode: string;
referredBy: string;
employmentInfo: { company: string; monthlyEarning: number; whyEV: string; experience: string };
nomineeDetails: { name: string; phone: string; relationship: string; nid: string; dob: string; email: string; address: string; percentage: number };
riderPlan: string;
evModel: string;
evCondition: string;
scheduleDate: string;
investmentPlan: { planName: string; planType: string; bikes: number; amount: number; monthlyReturn: number; expectedROI: number };
swapStationPlan: { planType: string; cabinets: number; amount: number; batteries: number; monthlyRent: number };
merchantPlan: { companyCategory: string; bikersRequested: number; amount: number; monthlyBudget: number; requiredArea: string };
requiredDocuments: Document[];
}>({
applicationSource: 'walkin',
sourceDetails: '',
type: 'biker',
status: 'pending',
hubId: '',
name: '',
phone: '',
altPhone: '',
email: '',
dateOfBirth: '',
gender: '',
bloodGroup: '',
occupation: '',
nid: '',
passport: '',
presentAddress: { line1: '', line2: '', division: '', district: '', zip: '', country: 'Bangladesh' },
permanentAddress: { sameAsPresent: false, line1: '', line2: '', division: '', district: '', zip: '', country: 'Bangladesh' },
emergencyContact: { name: '', phone: '', relation: '', email: '', address: '' },
drivingLicense: { number: '', class: '', issueDate: '', expiryDate: '', status: 'not_applied' },
membershipType: 'basic',
referralCode: '',
referredBy: '',
employmentInfo: { company: '', monthlyEarning: 0, whyEV: '', experience: '' },
nomineeDetails: { name: '', phone: '', relationship: '', nid: '', dob: '', email: '', address: '', percentage: 100 },
riderPlan: 'daily_rent',
evModel: '',
evCondition: 'new',
scheduleDate: '',
investmentPlan: { planName: '', planType: '', bikes: 1, amount: 0, monthlyReturn: 0, expectedROI: 0 },
swapStationPlan: { planType: '', cabinets: 8, amount: 0, batteries: 0, monthlyRent: 0 },
merchantPlan: { companyCategory: '', bikersRequested: 0, amount: 0, monthlyBudget: 0, requiredArea: '' },
requiredDocuments: [],
});
const [step, setStep] = useState(1);
const updateField = (path: string, value: any) => {
setFormData(prev => {
const keys = path.split('.');
if (keys.length === 1) return { ...prev, [keys[0]]: value };
const updated = { ...prev };
let obj: any = updated;
for (let i = 0; i < keys.length - 1; i++) {
if (!obj[keys[i]]) obj[keys[i]] = {};
obj = obj[keys[i]];
}
obj[keys[keys.length - 1]] = value;
return updated;
});
};
const updateDocStatus = (docId: string, status: 'pending' | 'uploaded' | 'approved' | 'rejected') => {
setFormData(prev => ({
...prev,
requiredDocuments: prev.requiredDocuments.map(d =>
d.id === docId ? { ...d, status, uploadedAt: status === 'uploaded' ? new Date().toISOString().split('T')[0] : d.uploadedAt } : d
),
}));
};
useEffect(() => {
if (isOpen && formData.type) {
const docs = getDocumentsForType(formData.type as KYCType);
setFormData(prev => ({ ...prev, requiredDocuments: docs }));
}
}, [isOpen, formData.type]);
const getDocumentsForType = (kycType: string): Document[] => {
const docs: Record<string, Document[]> = {
biker: [
{ id: 'doc1', name: 'NID Front', status: 'pending' },
{ id: 'doc2', name: 'NID Back', status: 'pending' },
{ id: 'doc3', name: 'Driving License', status: 'pending' },
{ id: 'doc4', name: 'Profile Photo', status: 'pending' },
{ id: 'doc5', name: 'Bank Account Card', status: 'pending' },
{ id: 'doc6', name: 'Mobile Wallet Info', status: 'pending' },
],
investor: [
{ id: 'doc1', name: 'NID', status: 'pending' },
{ id: 'doc2', name: 'TIN Certificate', status: 'pending' },
{ id: 'doc3', name: 'Bank Statement', status: 'pending' },
{ id: 'doc4', name: 'Photo', status: 'pending' },
],
swapstation: [
{ id: 'doc1', name: 'Trade License', status: 'pending' },
{ id: 'doc2', name: 'Owner NID', status: 'pending' },
{ id: 'doc3', name: 'Station Photos', status: 'pending' },
{ id: 'doc4', name: 'Electricity Connection Bill', status: 'pending' },
{ id: 'doc5', name: 'Station Layout/Blueprint', status: 'pending' },
],
merchant: [
{ id: 'doc1', name: 'NID', status: 'pending' },
{ id: 'doc2', name: 'Trade License', status: 'pending' },
{ id: 'doc3', name: 'Shop/Store Photo', status: 'pending' },
],
};
return docs[kycType] || docs.biker;
};
const handleSave = () => {
const newRequest: Request = {
id: `REQ${String(Date.now()).slice(-6)}`,
applicationSource: formData.applicationSource as ApplicationSource,
sourceDetails: formData.sourceDetails,
name: formData.name,
phone: formData.phone,
email: formData.email,
type: formData.type as KYCType,
status: formData.status as Request['status'],
verificationStage: 'application',
submittedAt: new Date().toISOString().split('T')[0],
location: `${formData.presentAddress.division}, ${formData.presentAddress.district}`,
address: `${formData.presentAddress.line1}, ${formData.presentAddress.line2}, ${formData.presentAddress.district}, ${formData.presentAddress.zip}`,
requiredDocuments: formData.requiredDocuments,
riderPlan: formData.riderPlan as RiderPlan,
employmentInfo: formData.employmentInfo,
nomineeDetails: formData.nomineeDetails,
notes: [],
smsHistory: [],
};
onSave(newRequest);
};
if (!isOpen) return null;
return (
<div className="fixed inset-0 bg-black/50 flex items-center justify-center z-50 p-2 sm:p-4">
<div className="bg-white rounded-xl shadow-xl w-full max-w-4xl max-h-[95vh] overflow-hidden flex flex-col">
<div className="p-4 border-b border-slate-100 flex items-center justify-between flex-shrink-0">
<div>
<h3 className="font-semibold text-slate-800 text-lg">New KYC Application</h3>
<p className="text-xs text-slate-500">Step {step} of 5 - {step === 1 ? 'Basic Info' : step === 2 ? 'Employment' : step === 3 ? 'Nominee' : step === 4 ? 'Plan Selection' : 'Documents'}</p>
</div>
<button onClick={onClose} className="p-1.5 hover:bg-slate-100 rounded-lg">
<X className="w-5 h-5 text-slate-400" />
</button>
</div>
<div className="px-4 py-3 bg-slate-50 border-b border-slate-100 flex-shrink-0">
<div className="flex items-center gap-2">
{[
{ n: 1, l: 'Basic', icon: User },
{ n: 2, l: 'Employment', icon: Briefcase },
{ n: 3, l: 'Nominee', icon: Users },
{ n: 4, l: 'Plan', icon: Calendar },
{ n: 5, l: 'Docs', icon: FileText },
].map((s, idx) => (
<div key={s.n} className={`flex-1 flex items-center gap-2 ${idx > 0 ? 'justify-start pl-2' : ''}`}>
<div className={`w-7 h-7 rounded-full flex items-center justify-center text-xs font-semibold ${step >= s.n ? 'bg-accent text-white' : 'bg-slate-200 text-slate-500'
}`}>
{step > s.n ? <Check className="w-4 h-4" /> : <s.icon className="w-3.5 h-3.5" />}
</div>
<span className={`text-xs hidden sm:inline ${step >= s.n ? 'text-slate-700' : 'text-slate-400'}`}>{s.l}</span>
{idx < 4 && <div className={`flex-1 h-0.5 rounded-full ${step > s.n ? 'bg-accent' : 'bg-slate-200'}`} />}
</div>
))}
</div>
</div>
<div className="flex-1 overflow-y-auto p-4 sm:p-6">
{step === 1 && (
<div className="space-y-5">
<div className="bg-blue-50/80 p-4 rounded-xl border border-blue-100">
<h4 className="font-semibold text-blue-900 mb-3 flex items-center gap-2 text-sm">
<Shield className="w-4 h-4" /> Application Details
</h4>
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3">
<div>
<label className="text-xs font-medium text-slate-600 mb-1 block">Application Source</label>
<select
value={formData.applicationSource}
onChange={(e) => updateField('applicationSource', e.target.value)}
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm bg-white"
>
<option value="walkin">Walk-in</option>
<option value="app">Mobile App</option>
<option value="web">Website</option>
</select>
</div>
<div>
<label className="text-xs font-medium text-slate-600 mb-1 block">KYC Type</label>
<select
value={formData.type}
onChange={(e) => updateField('type', e.target.value)}
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm bg-white"
>
<option value="biker">Biker (Rider)</option>
<option value="investor">Investor</option>
<option value="swapstation">Swap Station</option>
<option value="merchant">Merchant</option>
</select>
</div>
<div>
<label className="text-xs font-medium text-slate-600 mb-1 block">Status</label>
<select
value={formData.status}
onChange={(e) => updateField('status', e.target.value)}
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm bg-white"
>
<option value="pending">Pending</option>
<option value="active">Active</option>
<option value="inactive">Inactive</option>
<option value="blocked">Blocked</option>
</select>
</div>
<div>
<label className="text-xs font-medium text-slate-600 mb-1 block">Hub</label>
<select
value={formData.hubId}
onChange={(e) => updateField('hubId', e.target.value)}
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm bg-white"
>
<option value="">Select Hub</option>
<option value="hub1">Gulshan Hub</option>
<option value="hub2">Banani Hub</option>
<option value="hub3">Dhanmondi Hub</option>
<option value="hub4">Mirpur Hub</option>
<option value="hub5">Uttara Hub</option>
</select>
</div>
<div>
<label className="text-xs font-medium text-slate-600 mb-1 block">Membership Type</label>
<select
value={formData.membershipType}
onChange={(e) => updateField('membershipType', e.target.value)}
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm bg-white"
>
<option value="basic">Basic</option>
<option value="premium">Premium</option>
<option value="vip">VIP</option>
</select>
</div>
<div>
<label className="text-xs font-medium text-slate-600 mb-1 block">Referral Code</label>
<input
type="text"
value={formData.referralCode}
onChange={(e) => updateField('referralCode', e.target.value)}
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm"
placeholder="Optional"
/>
</div>
</div>
</div>
<div className="bg-indigo-50/80 p-4 rounded-xl border border-indigo-100">
<h4 className="font-semibold text-indigo-900 mb-3 flex items-center gap-2 text-sm">
<User className="w-4 h-4" /> Personal Information
</h4>
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3">
<div className="sm:col-span-2 lg:col-span-1">
<label className="text-xs font-medium text-slate-600 mb-1 block">Full Name *</label>
<input
type="text"
value={formData.name}
onChange={(e) => updateField('name', e.target.value)}
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm"
placeholder="Enter full name"
/>
</div>
<div>
<label className="text-xs font-medium text-slate-600 mb-1 block">Phone Number *</label>
<input
type="text"
value={formData.phone}
onChange={(e) => updateField('phone', e.target.value)}
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm"
placeholder="01XXXXXXXXX"
/>
</div>
<div>
<label className="text-xs font-medium text-slate-600 mb-1 block">Alternate Phone</label>
<input
type="text"
value={formData.altPhone}
onChange={(e) => updateField('altPhone', e.target.value)}
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm"
placeholder="Optional"
/>
</div>
<div>
<label className="text-xs font-medium text-slate-600 mb-1 block">Email</label>
<input
type="email"
value={formData.email}
onChange={(e) => updateField('email', e.target.value)}
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm"
placeholder="email@example.com"
/>
</div>
<div>
<label className="text-xs font-medium text-slate-600 mb-1 block">Date of Birth</label>
<input
type="date"
value={formData.dateOfBirth}
onChange={(e) => updateField('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 font-medium text-slate-600 mb-1 block">Gender</label>
<select
value={formData.gender}
onChange={(e) => updateField('gender', e.target.value)}
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm bg-white"
>
<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 font-medium text-slate-600 mb-1 block">Blood Group</label>
<select
value={formData.bloodGroup}
onChange={(e) => updateField('bloodGroup', e.target.value)}
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm bg-white"
>
<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="AB+">AB+</option>
<option value="AB-">AB-</option>
<option value="O+">O+</option>
<option value="O-">O-</option>
</select>
</div>
<div>
<label className="text-xs font-medium text-slate-600 mb-1 block">NID *</label>
<input
type="text"
value={formData.nid}
onChange={(e) => updateField('nid', e.target.value)}
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm"
placeholder="NID number"
/>
</div>
<div>
<label className="text-xs font-medium text-slate-600 mb-1 block">Passport</label>
<input
type="text"
value={formData.passport}
onChange={(e) => updateField('passport', e.target.value)}
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm"
placeholder="Passport number (optional)"
/>
</div>
</div>
</div>
<div className="bg-emerald-50/80 p-4 rounded-xl border border-emerald-100">
<h4 className="font-semibold text-emerald-900 mb-3 flex items-center gap-2 text-sm">
<MapPin className="w-4 h-4" /> Present Address
</h4>
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3">
<div className="sm:col-span-2">
<label className="text-xs font-medium text-slate-600 mb-1 block">Address Line 1 *</label>
<input
type="text"
value={formData.presentAddress.line1}
onChange={(e) => updateField('presentAddress.line1', e.target.value)}
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm"
placeholder="House No, Road, Area"
/>
</div>
<div>
<label className="text-xs font-medium text-slate-600 mb-1 block">Address Line 2</label>
<input
type="text"
value={formData.presentAddress.line2}
onChange={(e) => updateField('presentAddress.line2', e.target.value)}
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm"
placeholder="Additional info"
/>
</div>
<div>
<label className="text-xs font-medium text-slate-600 mb-1 block">Division *</label>
<select
value={formData.presentAddress.division}
onChange={(e) => updateField('presentAddress.division', e.target.value)}
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm bg-white"
>
<option value="">Select Division</option>
<option value="Dhaka">Dhaka</option>
<option value="Chattogram">Chattogram</option>
<option value="Khulna">Khulna</option>
<option value="Barishal">Barishal</option>
<option value="Rajshahi">Rajshahi</option>
<option value="Rangpur">Rangpur</option>
<option value="Mymensingh">Mymensingh</option>
<option value="Sylhet">Sylhet</option>
</select>
</div>
<div>
<label className="text-xs font-medium text-slate-600 mb-1 block">District *</label>
<input
type="text"
value={formData.presentAddress.district}
onChange={(e) => updateField('presentAddress.district', e.target.value)}
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm"
placeholder="District"
/>
</div>
<div>
<label className="text-xs font-medium text-slate-600 mb-1 block">Zip Code *</label>
<input
type="text"
value={formData.presentAddress.zip}
onChange={(e) => updateField('presentAddress.zip', e.target.value)}
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm"
placeholder="Zip"
/>
</div>
<div>
<label className="text-xs font-medium text-slate-600 mb-1 block">Country *</label>
<input
type="text"
value={formData.presentAddress.country}
onChange={(e) => updateField('presentAddress.country', e.target.value)}
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm"
placeholder="Country"
/>
</div>
</div>
</div>
<div className="bg-red-50/80 p-4 rounded-xl border border-red-100">
<h4 className="font-semibold text-red-900 mb-3 flex items-center gap-2 text-sm">
<MapPinned className="w-4 h-4" /> Permanent Address
</h4>
<div className="flex items-center justify-between mb-3">
<label className="flex items-center gap-2 cursor-pointer">
<input
type="checkbox"
checked={formData.permanentAddress.sameAsPresent}
onChange={(e) => updateField('permanentAddress.sameAsPresent', e.target.checked)}
className="w-4 h-4 text-accent rounded"
/>
<span className="text-xs text-slate-600">Same as Present Address</span>
</label>
</div>
{!formData.permanentAddress.sameAsPresent && (
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3">
<div className="sm:col-span-2">
<label className="text-xs font-medium text-slate-600 mb-1 block">Address Line 1 *</label>
<input
type="text"
value={formData.permanentAddress.line1}
onChange={(e) => updateField('permanentAddress.line1', e.target.value)}
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm"
placeholder="Permanent address"
disabled={formData.permanentAddress.sameAsPresent}
/>
</div>
<div>
<label className="text-xs font-medium text-slate-600 mb-1 block">Address Line 2</label>
<input
type="text"
value={formData.permanentAddress.line2}
onChange={(e) => updateField('permanentAddress.line2', e.target.value)}
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm"
placeholder="Additional info"
disabled={formData.permanentAddress.sameAsPresent}
/>
</div>
<div>
<label className="text-xs font-medium text-slate-600 mb-1 block">Division *</label>
<select
value={formData.permanentAddress.division}
onChange={(e) => updateField('permanentAddress.division', e.target.value)}
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm bg-white" disabled={formData.permanentAddress.sameAsPresent}>
<option value="">Select Division</option>
<option value="Dhaka">Dhaka</option>
<option value="Chattogram">Chattogram</option>
<option value="Khulna">Khulna</option>
<option value="Barishal">Barishal</option>
<option value="Rajshahi">Rajshahi</option>
<option value="Rangpur">Rangpur</option>
<option value="Mymensingh">Mymensingh</option>
<option value="Sylhet">Sylhet</option>
</select>
</div>
<div>
<label className="text-xs font-medium text-slate-600 mb-1 block">District *</label>
<select
value={formData.permanentAddress.district}
onChange={(e) => updateField('permanentAddress.district', e.target.value)}
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm bg-white" disabled={formData.permanentAddress.sameAsPresent}>
<option value="">Select District</option>
<option value="Dhaka">Dhaka</option>
<option value="Gazipur">Gazipur</option>
<option value="Narayanganj">Narayanganj</option>
<option value="Chattogram">Chattogram</option>
<option value="Cumilla">Cumilla</option>
<option value="Bogura">Bogura</option>
<option value="Rajshahi">Rajshahi</option>
<option value="Khulna">Khulna</option>
<option value="Sylhet">Sylhet</option>
<option value="Barishal">Barishal</option>
<option value="Rangpur">Rangpur</option>
</select>
</div>
<div>
<label className="text-xs font-medium text-slate-600 mb-1 block">Zip Code *</label>
<input
type="text"
value={formData.permanentAddress.zip}
onChange={(e) => updateField('permanentAddress.zip', e.target.value)}
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm"
placeholder="Zip code"
disabled={formData.permanentAddress.sameAsPresent}
/>
</div>
<div>
<label className="text-xs font-medium text-slate-600 mb-1 block">Country *</label>
<input
type="text"
value={formData.permanentAddress.country}
onChange={(e) => updateField('permanentAddress.country', e.target.value)}
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm"
placeholder="Bangladesh"
defaultValue="Bangladesh"
disabled={formData.permanentAddress.sameAsPresent}
/>
</div>
</div>
)}
</div>
{formData.type === 'biker' && (
<div className="bg-amber-50/80 p-4 rounded-xl border border-amber-100">
<h4 className="font-semibold text-amber-900 mb-3 flex items-center gap-2 text-sm">
<Key className="w-4 h-4" /> Driving License
</h4>
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3">
<div>
<label className="text-xs font-medium text-slate-600 mb-1 block">License Number *</label>
<input
type="text"
value={formData.drivingLicense.number}
onChange={(e) => updateField('drivingLicense.number', e.target.value)}
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm"
placeholder="License number"
/>
</div>
<div>
<label className="text-xs font-medium text-slate-600 mb-1 block">Class *</label>
<select
value={formData.drivingLicense.class}
onChange={(e) => updateField('drivingLicense.class', e.target.value)}
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm bg-white"
>
<option value="">Select Class</option>
<option value="C">Class C</option>
<option value="D">Class D</option>
<option value="E">Class E</option>
<option value="F">Class F</option>
</select>
</div>
<div>
<label className="text-xs font-medium text-slate-600 mb-1 block">Status *</label>
<select
value={formData.drivingLicense.status}
onChange={(e) => updateField('drivingLicense.status', e.target.value)}
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm bg-white"
>
<option value="not_applied">Not Applied</option>
<option value="applied">Applied</option>
<option value="issued">Issued</option>
<option value="expired">Expired</option>
</select>
</div>
<div>
<label className="text-xs font-medium text-slate-600 mb-1 block">Issue Date *</label>
<input
type="date"
value={formData.drivingLicense.issueDate}
onChange={(e) => updateField('drivingLicense.issueDate', e.target.value)}
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm"
/>
</div>
<div>
<label className="text-xs font-medium text-slate-600 mb-1 block">Expiry Date *</label>
<input
type="date"
value={formData.drivingLicense.expiryDate}
onChange={(e) => updateField('drivingLicense.expiryDate', e.target.value)}
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm"
/>
</div>
</div>
</div>
)}
</div>
)}
{step === 2 && formData.type === 'biker' && (
<div className="space-y-5">
<div className="bg-purple-50/80 p-4 rounded-xl border border-purple-100">
<h4 className="font-semibold text-purple-900 mb-3 flex items-center gap-2 text-sm">
<Briefcase className="w-4 h-4" /> Employment Information
</h4>
<div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
<div>
<label className="text-xs font-medium text-slate-600 mb-1 block">Current Company</label>
<input
type="text"
value={formData.employmentInfo.company}
onChange={(e) => updateField('employmentInfo.company', e.target.value)}
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm"
placeholder="e.g., Foodpanda, ssl, Pathao"
/>
</div>
<div>
<label className="text-xs font-medium text-slate-600 mb-1 block">Monthly Earning (Tk)</label>
<input
type="number"
value={formData.employmentInfo.monthlyEarning}
onChange={(e) => updateField('employmentInfo.monthlyEarning', Number(e.target.value))}
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm"
placeholder="0"
/>
</div>
<div>
<label className="text-xs font-medium text-slate-600 mb-1 block">Occupation</label>
<input
type="text"
value={formData.occupation}
onChange={(e) => updateField('occupation', e.target.value)}
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm"
placeholder="Your occupation"
/>
</div>
<div className="sm:col-span-2">
<label className="text-xs font-medium text-slate-600 mb-1 block">Why want EV?</label>
<textarea
value={formData.employmentInfo.whyEV}
onChange={(e) => updateField('employmentInfo.whyEV', e.target.value)}
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm"
rows={3}
placeholder="Reason for choosing EV..."
/>
</div>
<div className="sm:col-span-2">
<label className="text-xs font-medium text-slate-600 mb-1 block">Driving Experience</label>
<input
type="text"
value={formData.employmentInfo.experience}
onChange={(e) => updateField('employmentInfo.experience', e.target.value)}
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm"
placeholder="e.g., 3 years motorcycle experience"
/>
</div>
</div>
</div>
</div>
)}
{step === 2 && formData.type === 'investor' && (
<div className="space-y-5">
<div className="bg-purple-50/80 p-4 rounded-xl border border-purple-100">
<h4 className="font-semibold text-purple-900 mb-3 flex items-center gap-2 text-sm">
<Briefcase className="w-4 h-4" /> Investment Information
</h4>
<div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
<div>
<label className="text-xs font-medium text-slate-600 mb-1 block">Company/Business Name</label>
<input
type="text"
value={formData.employmentInfo.company}
onChange={(e) => updateField('employmentInfo.company', e.target.value)}
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm"
placeholder="Your business name"
/>
</div>
<div>
<label className="text-xs font-medium text-slate-600 mb-1 block">Monthly Income (Tk)</label>
<input
type="number"
value={formData.employmentInfo.monthlyEarning}
onChange={(e) => updateField('employmentInfo.monthlyEarning', Number(e.target.value))}
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm"
placeholder="0"
/>
</div>
<div className="sm:col-span-2">
<label className="text-xs font-medium text-slate-600 mb-1 block">Investment Source</label>
<input
type="text"
value={formData.employmentInfo.whyEV}
onChange={(e) => updateField('employmentInfo.whyEV', 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>
<label className="text-xs font-medium text-slate-600 mb-1 block">Profession/Occupation</label>
<input
type="text"
value={formData.occupation}
onChange={(e) => updateField('occupation', e.target.value)}
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm"
placeholder="Your profession"
/>
</div>
</div>
</div>
</div>
)}
{(step === 2 && (formData.type === 'swapstation' || formData.type === 'merchant')) && (
<div className="space-y-5">
{formData.type === 'swapstation' ? (
<div className="bg-purple-50/80 p-4 rounded-xl border border-purple-100">
<h4 className="font-semibold text-purple-900 mb-3 flex items-center gap-2 text-sm">
<Briefcase className="w-4 h-4" /> Station Business Information
</h4>
<div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
<div>
<label className="text-xs font-medium text-slate-600 mb-1 block">Station Name</label>
<input
type="text"
value={formData.employmentInfo.company}
onChange={(e) => updateField('employmentInfo.company', e.target.value)}
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm"
placeholder="Your station name"
/>
</div>
<div>
<label className="text-xs font-medium text-slate-600 mb-1 block">Station Phone</label>
<input
type="text"
value={formData.phone}
onChange={(e) => updateField('phone', e.target.value)}
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm"
placeholder="01XXXXXXXXX"
/>
</div>
<div>
<label className="text-xs font-medium text-slate-600 mb-1 block">Station Address</label>
<input
type="text"
value={formData.presentAddress.line1}
onChange={(e) => updateField('presentAddress.line1', e.target.value)}
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm"
placeholder="Station address"
/>
</div>
<div>
<label className="text-xs font-medium text-slate-600 mb-1 block">Trade License Number</label>
<input
type="text"
value={formData.nid}
onChange={(e) => updateField('nid', e.target.value)}
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm"
placeholder="Trade license number"
/>
</div>
<div>
<label className="text-xs font-medium text-slate-600 mb-1 block">TIN Number</label>
<input
type="text"
value={formData.passport}
onChange={(e) => updateField('passport', 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-xs font-medium text-slate-600 mb-1 block">Monthly Rent/Income (Tk)</label>
<input
type="number"
value={formData.employmentInfo.monthlyEarning}
onChange={(e) => updateField('employmentInfo.monthlyEarning', Number(e.target.value))}
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm"
placeholder="0"
/>
</div>
<div className="sm:col-span-2">
<label className="text-xs font-medium text-slate-600 mb-1 block">Station Location (Google Map Link)</label>
<input
type="text"
value={formData.employmentInfo.whyEV}
onChange={(e) => updateField('employmentInfo.whyEV', e.target.value)}
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm"
placeholder="https://maps.google.com/..."
/>
</div>
<div className="sm:col-span-2">
<label className="text-xs font-medium text-slate-600 mb-1 block">Business Description</label>
<textarea
value={formData.employmentInfo.experience}
onChange={(e) => updateField('employmentInfo.experience', e.target.value)}
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm"
rows={3}
placeholder="Describe your swap station business..."
/>
</div>
</div>
</div>
) : null}
</div>
)}
{(step === 2 && formData.type === 'merchant') && (
<div className="space-y-5">
<div className="bg-purple-50/80 p-4 rounded-xl border border-purple-100">
<h4 className="font-semibold text-purple-900 mb-3 flex items-center gap-2 text-sm">
<Briefcase className="w-4 h-4" /> Company Information (Merchant)
</h4>
<div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
<div>
<label className="text-xs font-medium text-slate-600 mb-1 block">Company Name</label>
<input
type="text"
value={formData.employmentInfo.company}
onChange={(e) => updateField('employmentInfo.company', e.target.value)}
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm"
placeholder="e.g., Foodpanda, Uber, Pathao"
/>
</div>
<div>
<label className="text-xs font-medium text-slate-600 mb-1 block">Company Phone</label>
<input
type="text"
value={formData.phone}
onChange={(e) => updateField('phone', e.target.value)}
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm"
placeholder="01XXXXXXXXX"
/>
</div>
<div>
<label className="text-xs font-medium text-slate-600 mb-1 block">Company Email</label>
<input
type="email"
value={formData.email}
onChange={(e) => updateField('email', e.target.value)}
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm"
placeholder="company@email.com"
/>
</div>
<div>
<label className="text-xs font-medium text-slate-600 mb-1 block">Trade License Number</label>
<input
type="text"
value={formData.nid}
onChange={(e) => updateField('nid', e.target.value)}
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm"
placeholder="Trade license number"
/>
</div>
<div>
<label className="text-xs font-medium text-slate-600 mb-1 block">TIN Number</label>
<input
type="text"
value={formData.passport}
onChange={(e) => updateField('passport', 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-xs font-medium text-slate-600 mb-1 block">Monthly Revenue (Tk)</label>
<input
type="number"
value={formData.employmentInfo.monthlyEarning}
onChange={(e) => updateField('employmentInfo.monthlyEarning', Number(e.target.value))}
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm"
placeholder="0"
/>
</div>
<div className="sm:col-span-2">
<label className="text-xs font-medium text-slate-600 mb-1 block">Company Address</label>
<input
type="text"
value={formData.presentAddress.line1}
onChange={(e) => updateField('presentAddress.line1', e.target.value)}
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm"
placeholder="Company headquarters address"
/>
</div>
<div className="sm:col-span-2">
<label className="text-xs font-medium text-slate-600 mb-1 block">Delivery Platform</label>
<select
value={formData.employmentInfo.whyEV}
onChange={(e) => updateField('employmentInfo.whyEV', e.target.value)}
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm bg-white"
>
<option value="">Select Platform</option>
<option value="Foodpanda">Foodpanda</option>
<option value="Uber">Uber</option>
<option value="Pathao">Pathao</option>
<option value="SSL Commercial">SSL Commercial</option>
<option value="Others">Others</option>
</select>
</div>
<div className="sm:col-span-2">
<label className="text-xs font-medium text-slate-600 mb-1 block">Company Description</label>
<textarea
value={formData.employmentInfo.experience}
onChange={(e) => updateField('employmentInfo.experience', e.target.value)}
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm"
rows={3}
placeholder="Describe your company business..."
/>
</div>
</div>
</div>
</div>
)}
{(step === 3 && (formData.type === 'biker' || formData.type === 'investor' || formData.type === 'swapstation' || formData.type === 'merchant')) && (
<div className="space-y-5">
<div className="bg-pink-50/80 p-4 rounded-xl border border-pink-100">
<h4 className="font-semibold text-pink-900 mb-3 flex items-center gap-2 text-sm">
<Users className="w-4 h-4" /> Nominee Details
</h4>
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3">
<div>
<label className="text-xs font-medium text-slate-600 mb-1 block">Nominee Name *</label>
<input
type="text"
value={formData.nomineeDetails.name}
onChange={(e) => updateField('nomineeDetails.name', e.target.value)}
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm"
placeholder="Nominee name"
/>
</div>
<div>
<label className="text-xs font-medium text-slate-600 mb-1 block">Relationship *</label>
<select
value={formData.nomineeDetails.relationship}
onChange={(e) => updateField('nomineeDetails.relationship', e.target.value)}
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm bg-white"
>
<option value="">Select</option>
<option value="Spouse">Spouse</option>
<option value="Father">Father</option>
<option value="Mother">Mother</option>
<option value="Brother">Brother</option>
<option value="Sister">Sister</option>
<option value="Office">Office</option>
<option value="Other">Other</option>
</select>
</div>
<div>
<label className="text-xs font-medium text-slate-600 mb-1 block">Nominee Phone *</label>
<input
type="text"
value={formData.nomineeDetails.phone}
onChange={(e) => updateField('nomineeDetails.phone', e.target.value)}
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm"
placeholder="Phone number"
/>
</div>
<div>
<label className="text-xs font-medium text-slate-600 mb-1 block">Nominee NID *</label>
<input
type="text"
value={formData.nomineeDetails.nid}
onChange={(e) => updateField('nomineeDetails.nid', e.target.value)}
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm"
placeholder="NID number"
/>
</div>
<div>
<label className="text-xs font-medium text-slate-600 mb-1 block">Nominee Date of Birth</label>
<input
type="date"
value={formData.nomineeDetails.dob}
onChange={(e) => updateField('nomineeDetails.dob', e.target.value)}
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm"
/>
</div>
<div>
<label className="text-xs font-medium text-slate-600 mb-1 block">Nominee Email</label>
<input
type="email"
value={formData.nomineeDetails.email}
onChange={(e) => updateField('nomineeDetails.email', e.target.value)}
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm"
placeholder="email@example.com"
/>
</div>
<div className="sm:col-span-3">
<label className="text-xs font-medium text-slate-600 mb-1 block">Nominee Address *</label>
<input
type="text"
value={formData.nomineeDetails.address}
onChange={(e) => updateField('nomineeDetails.address', e.target.value)}
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm"
placeholder="Address"
/>
</div>
</div>
</div>
<div className="bg-red-50/80 p-4 rounded-xl border border-red-100 mt-4">
<h4 className="font-semibold text-red-900 mb-3 flex items-center gap-2 text-sm">
<Phone className="w-4 h-4" /> Emergency Contact
</h4>
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3">
<div>
<label className="text-xs font-medium text-slate-600 mb-1 block">Contact Name *</label>
<input
type="text"
value={formData.emergencyContact.name}
onChange={(e) => updateField('emergencyContact.name', e.target.value)}
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm"
placeholder="Contact name"
/>
</div>
<div>
<label className="text-xs font-medium text-slate-600 mb-1 block">Phone *</label>
<input
type="text"
value={formData.emergencyContact.phone}
onChange={(e) => updateField('emergencyContact.phone', e.target.value)}
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm"
placeholder="Phone number"
/>
</div>
<div>
<label className="text-xs font-medium text-slate-600 mb-1 block">Relationship *</label>
<select
value={formData.emergencyContact.relation}
onChange={(e) => updateField('emergencyContact.relation', e.target.value)}
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm bg-white"
>
<option value="">Select</option>
<option value="Spouse">Spouse</option>
<option value="Father">Father</option>
<option value="Mother">Mother</option>
<option value="Brother">Brother</option>
<option value="Sister">Sister</option>
<option value="Friend">Friend</option>
<option value="Other">Other</option>
</select>
</div>
<div>
<label className="text-xs font-medium text-slate-600 mb-1 block">Email</label>
<input
type="email"
value={formData.emergencyContact.email}
onChange={(e) => updateField('emergencyContact.email', e.target.value)}
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm"
placeholder="email@example.com"
/>
</div>
<div className="sm:col-span-2 lg:col-span-2">
<label className="text-xs font-medium text-slate-600 mb-1 block">Address *</label>
<input
type="text"
value={formData.emergencyContact.address}
onChange={(e) => updateField('emergencyContact.address', e.target.value)}
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm"
placeholder="Address"
/>
</div>
</div>
</div>
</div>
)}
{step === 4 && formData.type === 'biker' && (
<div className="space-y-5">
<div className="bg-amber-50/80 p-4 rounded-xl border border-amber-100">
<h4 className="font-semibold text-amber-900 mb-3 flex items-center gap-2 text-sm">
<Calendar className="w-4 h-4" /> Plan Selection
</h4>
<div className="grid grid-cols-1 sm:grid-cols-3 gap-3 mb-4">
{[
{ v: 'single_rent', l: 'Single Rent', d: 'Single person rental plan', icon: Bike },
{ v: 'rent_to_own', l: 'Rent to Own', d: 'Own after X months', icon: Key },
{ v: 'share_ev', l: 'Share EV', d: 'Shared bike', icon: Users },
].map(plan => (
<button
key={plan.v}
onClick={() => updateField('riderPlan', plan.v)}
className={`p-4 rounded-lg border text-left transition-all ${formData.riderPlan === plan.v
? 'border-accent bg-accent/10 ring-1 ring-accent'
: 'border-slate-200 bg-white hover:border-accent'
}`}
>
<plan.icon className={`w-5 h-5 mb-2 ${formData.riderPlan === plan.v ? 'text-accent' : 'text-slate-400'}`} />
<p className="text-sm font-semibold text-slate-800">{plan.l}</p>
<p className="text-xs text-slate-500">{plan.d}</p>
</button>
))}
</div>
<div className="grid grid-cols-1 sm:grid-cols-3 gap-3">
<div>
<label className="text-xs font-medium text-slate-600 mb-1 block">Requested EV Model</label>
<select
value={formData.evModel}
onChange={(e) => updateField('evModel', e.target.value)}
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm bg-white"
>
<option value="">Select Model</option>
<option value="AIMA Lightning">AIMA Lightning</option>
<option value="Yadea DT3">Yadea DT3</option>
<option value="Etron ET50">Etron ET50</option>
<option value="AIMA i3">AIMA i3</option>
<option value="TVS iQube">TVS iQube</option>
<option value="Benling Aura">Benling Aura</option>
<option value="Okinawa Ridge">Okinawa Ridge</option>
<option value="Hero Optima">Hero Optima</option>
</select>
</div>
<div>
<label className="text-xs font-medium text-slate-600 mb-1 block">EV Condition</label>
<select
value={formData.evCondition}
onChange={(e) => updateField('evCondition', e.target.value)}
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm bg-white"
>
<option value="new">New</option>
<option value="old">Old</option>
</select>
</div>
<div>
<label className="text-xs font-medium text-slate-600 mb-1 block">Schedule Date</label>
<input
type="date"
value={formData.scheduleDate}
onChange={(e) => updateField('scheduleDate', e.target.value)}
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm"
/>
</div>
</div>
</div>
</div>
)}
{step === 4 && formData.type === 'investor' && (
<div className="space-y-5">
<div className="bg-amber-50/80 p-4 rounded-xl border border-amber-100">
<h4 className="font-semibold text-amber-900 mb-3 flex items-center gap-2 text-sm">
<Wallet className="w-4 h-4" /> Investment Plan
</h4>
<div className="grid grid-cols-1 sm:grid-cols-3 gap-3 mb-4">
{[
{ v: '1', l: '1 Bike', d: 'Invest in 1 bike', icon: Bike },
{ v: '5', l: '5 Bikes', d: 'Invest in 5 bikes', icon: Bike },
{ v: '10', l: '10 Bikes', d: 'Invest in 10 bikes', icon: Bike },
].map(plan => (
<button
key={plan.v}
onClick={() => updateField('investmentPlan.bikes', Number(plan.v))}
className={`p-4 rounded-lg border text-left transition-all ${formData.investmentPlan.bikes === Number(plan.v)
? 'border-accent bg-accent/10 ring-1 ring-accent'
: 'border-slate-200 bg-white hover:border-accent'
}`}
>
<plan.icon className={`w-5 h-5 mb-2 ${formData.investmentPlan.bikes === Number(plan.v) ? 'text-accent' : 'text-slate-400'}`} />
<p className="text-sm font-semibold text-slate-800">{plan.l}</p>
<p className="text-xs text-slate-500">{plan.d}</p>
</button>
))}
</div>
<div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
<div>
<label className="text-xs font-medium text-slate-600 mb-1 block">Plan Name</label>
<input
type="text"
value={formData.investmentPlan.planName}
onChange={(e) => updateField('investmentPlan.planName', e.target.value)}
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm"
placeholder="Plan name"
/>
</div>
<div>
<label className="text-xs font-medium text-slate-600 mb-1 block">Plan Type</label>
<select
value={formData.investmentPlan.planType}
onChange={(e) => updateField('investmentPlan.planType', e.target.value)}
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm bg-white"
>
<option value="">Select Type</option>
<option value="Bronze">Bronze</option>
<option value="Silver">Silver</option>
<option value="Gold">Gold</option>
<option value="Platinum">Platinum</option>
</select>
</div>
<div>
<label className="text-xs font-medium text-slate-600 mb-1 block">Investment Amount (Tk)</label>
<input
type="number"
value={formData.investmentPlan.amount}
onChange={(e) => updateField('investmentPlan.amount', Number(e.target.value))}
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm"
placeholder="0"
/>
</div>
<div>
<label className="text-xs font-medium text-slate-600 mb-1 block">Expected Monthly Return (%)</label>
<input
type="number"
value={formData.investmentPlan.monthlyReturn}
onChange={(e) => updateField('investmentPlan.monthlyReturn', Number(e.target.value))}
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm"
placeholder="0"
/>
</div>
<div className="sm:col-span-2">
<label className="text-xs font-medium text-slate-600 mb-1 block">Expected ROI (%)</label>
<input
type="number"
value={formData.investmentPlan.expectedROI}
onChange={(e) => updateField('investmentPlan.expectedROI', Number(e.target.value))}
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm"
placeholder="0"
/>
</div>
</div>
</div>
</div>
)}
{step === 4 && formData.type === 'swapstation' && (
<div className="space-y-5">
<div className="bg-amber-50/80 p-4 rounded-xl border border-amber-100">
<h4 className="font-semibold text-amber-900 mb-3 flex items-center gap-2 text-sm">
<BatteryCharging className="w-4 h-4" /> Swap Station Plan
</h4>
<div className="grid grid-cols-1 sm:grid-cols-3 gap-3 mb-4">
{[
{ v: 8, l: '8 Cabinets', d: '8 battery swap capacity' },
{ v: 12, l: '12 Cabinets', d: '12 battery swap capacity' },
{ v: 20, l: '20 Cabinets', d: '20 battery swap capacity' },
].map(plan => (
<button
key={plan.v}
onClick={() => updateField('swapStationPlan.cabinets', plan.v)}
className={`p-4 rounded-lg border text-left transition-all ${formData.swapStationPlan.cabinets === plan.v
? 'border-accent bg-accent/10 ring-1 ring-accent'
: 'border-slate-200 bg-white hover:border-accent'
}`}
>
<BatteryCharging className={`w-5 h-5 mb-2 ${formData.swapStationPlan.cabinets === plan.v ? 'text-accent' : 'text-slate-400'}`} />
<p className="text-sm font-semibold text-slate-800">{plan.l}</p>
<p className="text-xs text-slate-500">{plan.d}</p>
</button>
))}
</div>
<div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
<div>
<label className="text-xs font-medium text-slate-600 mb-1 block">Plan Type</label>
<select
value={formData.swapStationPlan.planType}
onChange={(e) => updateField('swapStationPlan.planType', e.target.value)}
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm bg-white"
>
<option value="">Select Type</option>
<option value="Basic">Basic</option>
<option value="Standard">Standard</option>
<option value="Premium">Premium</option>
</select>
</div>
<div>
<label className="text-xs font-medium text-slate-600 mb-1 block">Number of Batteries</label>
<input
type="number"
value={formData.swapStationPlan.batteries}
onChange={(e) => updateField('swapStationPlan.batteries', Number(e.target.value))}
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm"
placeholder="0"
/>
</div>
<div>
<label className="text-xs font-medium text-slate-600 mb-1 block">Investment Amount (Tk)</label>
<input
type="number"
value={formData.swapStationPlan.amount}
onChange={(e) => updateField('swapStationPlan.amount', Number(e.target.value))}
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm"
placeholder="0"
/>
</div>
<div>
<label className="text-xs font-medium text-slate-600 mb-1 block">Expected Monthly Rent (Tk)</label>
<input
type="number"
value={formData.swapStationPlan.monthlyRent}
onChange={(e) => updateField('swapStationPlan.monthlyRent', Number(e.target.value))}
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm"
placeholder="0"
/>
</div>
</div>
</div>
</div>
)}
{step === 4 && formData.type === 'merchant' && (
<div className="space-y-5">
<div className="bg-amber-50/80 p-4 rounded-xl border border-amber-100">
<h4 className="font-semibold text-amber-900 mb-3 flex items-center gap-2 text-sm">
<Users className="w-4 h-4" /> Rider Request Plan
</h4>
<div className="grid grid-cols-1 sm:grid-cols-3 gap-3 mb-4">
{[
{ v: 5, l: '5 Riders', d: 'Request for 5 bikers' },
{ v: 10, l: '10 Riders', d: 'Request for 10 bikers' },
{ v: 20, l: '20 Riders', d: 'Request for 20 bikers' },
{ v: 50, l: '50 Riders', d: 'Request for 50 bikers' },
{ v: 100, l: '100 Riders', d: 'Request for 100 bikers' },
].map(plan => (
<button
key={plan.v}
onClick={() => updateField('merchantPlan.bikersRequested', plan.v)}
className={`p-4 rounded-lg border text-left transition-all ${formData.merchantPlan.bikersRequested === plan.v
? 'border-accent bg-accent/10 ring-1 ring-accent'
: 'border-slate-200 bg-white hover:border-accent'
}`}
>
<Users className={`w-5 h-5 mb-2 ${formData.merchantPlan.bikersRequested === plan.v ? 'text-accent' : 'text-slate-400'}`} />
<p className="text-sm font-semibold text-slate-800">{plan.l}</p>
<p className="text-xs text-slate-500">{plan.d}</p>
</button>
))}
</div>
<div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
<div>
<label className="text-xs font-medium text-slate-600 mb-1 block">Company Category</label>
<select
value={formData.merchantPlan.companyCategory}
onChange={(e) => updateField('merchantPlan.companyCategory', e.target.value)}
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm bg-white"
>
<option value="">Select Category</option>
<option value="Food Delivery">Food Delivery</option>
<option value="Parcel Delivery">Parcel Delivery</option>
<option value="E-commerce">E-commerce</option>
<option value="Logistics">Logistics</option>
<option value="Quick Commerce">Quick Commerce</option>
<option value="Others">Others</option>
</select>
</div>
<div>
<label className="text-xs font-medium text-slate-600 mb-1 block">Required Area/Zone</label>
<input
type="text"
value={formData.merchantPlan.requiredArea}
onChange={(e) => updateField('merchantPlan.requiredArea', e.target.value)}
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm"
placeholder="e.g., Dhaka, Chattogram"
/>
</div>
<div>
<label className="text-xs font-medium text-slate-600 mb-1 block">Investment Amount (Tk)</label>
<input
type="number"
value={formData.merchantPlan.amount}
onChange={(e) => updateField('merchantPlan.amount', Number(e.target.value))}
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm"
placeholder="0"
/>
</div>
<div>
<label className="text-xs font-medium text-slate-600 mb-1 block">Monthly Budget (Tk)</label>
<input
type="number"
value={formData.merchantPlan.monthlyBudget}
onChange={(e) => updateField('merchantPlan.monthlyBudget', Number(e.target.value))}
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm"
placeholder="0"
/>
</div>
</div>
</div>
</div>
)}
{step === 5 && (
<div className="space-y-5">
<div className="bg-green-50/80 p-4 rounded-xl border border-green-100">
<h4 className="font-semibold text-green-900 mb-3 flex items-center gap-2 text-sm">
<FileText className="w-4 h-4" /> Required Documents ({formData.type})
</h4>
<p className="text-xs text-slate-600 mb-4">Documents required for {formData.type} KYC application</p>
<div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
{formData.requiredDocuments.map((doc) => (
<div key={doc.id} className="flex items-center justify-between p-3 bg-white rounded-lg border border-green-100">
<div className="flex items-center gap-2">
{doc.status === 'pending' ? (
<Upload className="w-4 h-4 text-amber-400" />
) : doc.status === 'uploaded' ? (
<FileText className="w-4 h-4 text-blue-400" />
) : doc.status === 'approved' ? (
<CheckCircle className="w-4 h-4 text-green-500" />
) : (
<XCircle className="w-4 h-4 text-red-500" />
)}
<span className="text-sm text-slate-700">{doc.name}</span>
</div>
<span className="text-xs text-slate-500 flex items-center gap-1">
{doc.status === 'pending' ? (
<span className="text-amber-600">Pending</span>
) : doc.status === 'uploaded' ? (
<span className="text-blue-600">Uploaded</span>
) : doc.status === 'approved' ? (
<span className="text-green-600">Approved</span>
) : (
<span className="text-red-600">Rejected</span>
)}
</span>
</div>
))}
</div>
</div>
</div>
)}
</div>
<div className="p-4 border-t border-slate-100 flex justify-between flex-shrink-0 bg-slate-50">
<button
onClick={() => setStep(Math.max(1, step - 1))}
className={`px-4 py-2 border border-slate-200 text-slate-600 rounded-lg text-sm hover:bg-slate-100 flex items-center gap-2 ${step === 1 ? 'invisible' : ''}`}
>
<ChevronDown className="w-4 h-4 rotate-90" /> Previous
</button>
<div className="flex gap-2">
<button onClick={onClose} className="px-4 py-2 border border-slate-200 text-slate-600 rounded-lg text-sm hover:bg-slate-100">
Cancel
</button>
{step < 5 ? (
<button onClick={() => setStep(step + 1)} className="px-4 py-2 bg-accent text-white rounded-lg text-sm hover:bg-accent-dark flex items-center gap-2">
Next <ChevronDown className="w-4 h-4 -rotate-90" />
</button>
) : (
<button
onClick={handleSave}
className="px-4 py-2 bg-green-600 text-white rounded-lg text-sm hover:bg-green-700 flex items-center gap-2"
>
<Check className="w-4 h-4" /> Create Application
</button>
)}
</div>
</div>
</div>
</div>
);
}