From 37f86c23631250ba7c53a7158b54da7bdaa76af1 Mon Sep 17 00:00:00 2001 From: sazzadulalambd Date: Tue, 5 May 2026 02:32:51 +0600 Subject: [PATCH] feat: expand KYC types with swapstation support and implement SMS history tracking with templating system --- src/app/admin/kyc/[id]/page.tsx | 157 +++++++++++++++++++++++++------- src/app/admin/kyc/page.tsx | 24 ++--- 2 files changed, 131 insertions(+), 50 deletions(-) diff --git a/src/app/admin/kyc/[id]/page.tsx b/src/app/admin/kyc/[id]/page.tsx index 5360975..2d81cad 100644 --- a/src/app/admin/kyc/[id]/page.tsx +++ b/src/app/admin/kyc/[id]/page.tsx @@ -11,7 +11,7 @@ import { } from 'lucide-react'; type ApplicationSource = 'app' | 'web' | 'walkin' | 'referral'; -type KYCType = 'biker' | 'investor' | 'shop' | 'merchant' | 'general'; +type KYCType = 'biker' | 'investor' | 'swapstation' | 'merchant' | 'general'; type RiderPlan = 'daily_rent' | 'weekly_rent' | 'monthly_rent' | 'rent_to_own' | 'share_ev'; type VerificationStage = 'application' | 'document_collection' | 'risk_check' | 'plan_selection' | 'payment' | 'agreement' | 'allocated' | 'active'; @@ -24,6 +24,38 @@ interface Document { uploadedAt?: string; } +interface InvestmentPlan { + planName: string; + planType: string; + bikes: number; + amount: number; + monthlyReturn: number; + expectedROI: number; +} + +interface SwapStationPlan { + planType: string; + cabinets: number; + amount: number; + batteries: number; + monthlyRent: number; +} + +interface MerchantPlan { + companyCategory: string; + bikersRequested: number; + amount: number; + monthlyBudget: number; + requiredArea: string; +} + +interface SmsHistory { + id: string; + message: string; + sentAt: string; + sentBy: string; +} + interface Request { id: string; applicationSource: ApplicationSource; @@ -42,6 +74,9 @@ interface Request { riderPlan?: RiderPlan; nomineeDetails?: { name: string; phone: string; relationship: string; nid: string }; employmentInfo?: { company: string; dailyEarning: number; whyEV: string; experience: string }; + investmentPlan?: InvestmentPlan; + swapStationPlan?: SwapStationPlan; + merchantPlan?: MerchantPlan; riskCheck?: { nidVerified: boolean; nomineeNidVerified: boolean; deliveryPlatformStatus: string; paymentReliability: string; notes: string }; agreement?: { dailyRentObligation: number; latePenalty: number; signedAt?: string }; evAllocation?: { evId: string; bikeModel: string; batteryId: string; hubLocation: string; gpsActivated: boolean }; @@ -51,7 +86,7 @@ interface Request { bikeRequested?: string; scheduleDate?: string; notes: string[]; - messageHistory: { date: string; message: string; from: 'admin' | 'user' }[]; + smsHistory?: SmsHistory[]; } const mockRequests: Request[] = [ @@ -80,13 +115,14 @@ const mockRequests: Request[] = [ advancePayment: 500, bikeRequested: 'AIMA Lightning', notes: ['Downloaded app and applied through mobile'], - messageHistory: [], + smsHistory: [ + { id: 'sms1', message: 'Your KYC application is under review', sentAt: '2024-03-21', sentBy: 'admin' }, + ], }, { id: 'REQ002', applicationSource: 'walkin', - sourceDetails: 'Gulshan Hub', - hubId: 'hub1', + hubId: 'hub2', name: 'Karim Hasan', phone: '01712345679', email: 'karim@email.com', @@ -102,7 +138,58 @@ const mockRequests: Request[] = [ { id: 'd7', name: 'Bank Statement', status: 'pending' }, ], notes: ['Walked in at Gulshan office - referred by current biker'], - messageHistory: [], + smsHistory: [], + investmentPlan: { planName: 'Gold Plan', planType: 'Gold', bikes: 5, amount: 2500000, monthlyReturn: 8, expectedROI: 96 }, + nomineeDetails: { name: 'John Doe', phone: '01712345690', relationship: 'Brother', nid: '1234567890124' }, + }, + { + id: 'REQ003', + applicationSource: 'web', + hubId: 'hub1', + name: 'Dhaka Swap Station', + phone: '01712345680', + email: 'dhakaswap@email.com', + type: 'swapstation', + status: 'under_review', + verificationStage: 'document_collection', + submittedAt: '2024-03-18', + location: 'Gulshan, Dhaka', + address: 'Plot 45, Road 11, Gulshan 1', + requiredDocuments: [ + { id: 'd8', name: 'Trade License', status: 'uploaded', uploadedAt: '2024-03-18' }, + { id: 'd9', name: 'Owner NID', status: 'uploaded', uploadedAt: '2024-03-18' }, + { id: 'd10', name: 'Station Photos', status: 'pending' }, + { id: 'd11', name: 'Electricity Bill', status: 'pending' }, + ], + employmentInfo: { company: 'Dhaka Swap Station', dailyEarning: 0, whyEV: 'https://maps.google.com/...', experience: 'Battery swap station' }, + swapStationPlan: { planType: 'Premium', cabinets: 12, amount: 1800000, batteries: 24, monthlyRent: 45000 }, + nomineeDetails: { name: 'Mahbub', phone: '01712345691', relationship: 'Brother', nid: '1234567890125' }, + notes: ['Located in commercial area'], + smsHistory: [], + }, + { + id: 'REQ004', + applicationSource: 'app', + hubId: 'hub3', + name: 'Foodpanda Bangladesh', + phone: '01712345681', + email: 'bd@foodpanda.com', + type: 'merchant', + status: 'pending', + verificationStage: 'application', + submittedAt: '2024-03-21', + location: 'Dhaka', + address: 'House 12, Gulshan Avenue', + requiredDocuments: [ + { id: 'd12', name: 'Trade License', status: 'pending' }, + { id: 'd13', name: 'Company NID', status: 'pending' }, + { id: 'd14', name: 'Company Documents', status: 'pending' }, + ], + employmentInfo: { company: 'Foodpanda Bangladesh', dailyEarning: 5000000, whyEV: 'Food Delivery', experience: 'Leading food delivery platform' }, + merchantPlan: { companyCategory: 'Food Delivery', bikersRequested: 100, amount: 5000000, monthlyBudget: 10000000, requiredArea: 'Dhaka' }, + nomineeDetails: { name: 'Admin User', phone: '01712345692', relationship: 'Office', nid: '1234567890126' }, + notes: ['Request for 100 riders'], + smsHistory: [], }, ]; @@ -152,7 +239,7 @@ const planLabels: Record = { const typeIcons: Record = { biker: Bike, investor: DollarSign, - shop: Store, + swapstation: Store, merchant: User, }; @@ -214,10 +301,16 @@ export default function KYCDetailPage() { if (!request || !newMessageText.trim()) return; setRequest(prev => prev ? { ...prev, - messageHistory: [...prev.messageHistory, { date: new Date().toISOString().split('T')[0], message: newMessageText, from: 'admin' as const }] + status: 'documents_needed' as const, + smsHistory: [ + ...(prev.smsHistory || []), + { id: `sms-${Date.now()}`, message: newMessageText, sentAt: new Date().toISOString(), sentBy: 'admin' } + ], + notes: [...prev.notes, newMessageText] } : null); setNewMessageText(''); setShowMessageModal(false); + alert(`Message sent to ${request.phone}`); }; const handleAddDocument = () => { @@ -240,7 +333,7 @@ export default function KYCDetailPage() { } : null); }; -const handleRejectDocument = (docId: string) => { + const handleRejectDocument = (docId: string) => { const reason = prompt('Enter rejection reason:'); if (reason) { setRequest(prev => prev ? { @@ -272,6 +365,12 @@ const handleRejectDocument = (docId: string) => { const TypeIcon = typeIcons[request.type]; + const smsTemplates = [ + { id: 'docs', label: 'Documents Required', message: 'Please upload your required documents to proceed with your KYC application.' }, + { id: 'review', label: 'Under Review', message: 'Your KYC application is now under review. We will notify you once the process is completed.' }, + { id: 'approval', label: 'Pending Approval', message: 'Your application is pending final approval. You will be notified once approved.' }, + ]; + return (
)} {request.type === 'investor' && request.status !== 'approved' && ( - )} - {request.type === 'shop' && request.status !== 'approved' && ( - )} {request.type === 'merchant' && request.status !== 'approved' && ( -
- -
-

- Messages ({request.messageHistory.length}) -

- {request.messageHistory.length > 0 ? ( -
- {request.messageHistory.map((msg, idx) => ( -
- {msg.from === 'admin' ? 'Admin' : 'User'}: {msg.message} - {msg.date} -
- ))} -
- ) : ( -

No messages yet

- )} -
@@ -624,6 +705,18 @@ const handleRejectDocument = (docId: string) => {
+ +
+ {smsTemplates.map(tmpl => ( + + ))} +