Dealer_Onboard_Frontend/src/features/onboarding/components/ApplicationCard.tsx

149 lines
6.1 KiB
TypeScript

import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import { Progress } from '@/components/ui/progress';
import { Application } from '@/lib/mock-data';
import { MapPin, Phone, Mail, Award, Calendar, Building } from 'lucide-react';
import { formatDateTime } from '@/components/ui/utils';
interface ApplicationCardProps {
application: Application;
onViewDetails: (id: string) => void;
}
export function ApplicationCard({ application, onViewDetails }: ApplicationCardProps) {
const getStatusColor = (status: string) => {
const statusColors: Record<string, string> = {
'Submitted': 'bg-slate-500',
'Questionnaire Pending': 'bg-orange-500',
'Questionnaire Completed': 'bg-blue-500',
'Shortlisted': 'bg-cyan-500',
'Level 1 Pending': 'bg-amber-500',
'Level 1 Approved': 'bg-green-500',
'Level 2 Pending': 'bg-purple-500',
'Level 2 Approved': 'bg-green-600',
'Level 2 Recommended': 'bg-teal-500',
'Level 3 Pending': 'bg-indigo-500',
'FDD Verification': 'bg-violet-500',
'Payment Pending': 'bg-yellow-500',
'LOI Issued': 'bg-lime-500',
'Dealer Code Generation': 'bg-fuchsia-500',
'Architecture Team Assigned': 'bg-blue-500',
'Architecture Document Upload': 'bg-blue-500',
'Architecture Team Completion': 'bg-blue-500',
'Statutory GST': 'bg-emerald-500',
'Statutory PAN': 'bg-emerald-500',
'Statutory Nodal': 'bg-emerald-500',
'Statutory Check': 'bg-emerald-500',
'Statutory Partnership': 'bg-emerald-500',
'Statutory Firm Reg': 'bg-emerald-500',
'Statutory Virtual Code': 'bg-emerald-500',
'Statutory Domain': 'bg-emerald-500',
'Statutory MSD': 'bg-emerald-500',
'Statutory LOI Ack': 'bg-emerald-500',
'EOR In Progress': 'bg-sky-500',
'LOA Pending': 'bg-emerald-500',
'Approved': 'bg-green-700',
'Rejected': 'bg-red-500',
'Disqualified': 'bg-red-700'
};
return statusColors[status] || 'bg-slate-500';
};
return (
<div
className="bg-white rounded-lg border border-slate-200 p-6 hover:shadow-lg transition-shadow"
data-testid={`onboarding-application-card-${application.id}`}
>
<div className="flex items-start justify-between mb-4">
<div>
<div className="flex items-center gap-2 mb-1">
<h3 className="text-slate-900" data-testid="onboarding-application-card-name">{application.name}</h3>
{application.tags?.map((tag) => (
<Badge
key={tag}
variant="outline"
className={tag === 'Approved' ? 'border-green-500 text-green-700' : 'border-teal-500 text-teal-700'}
data-testid={`onboarding-application-card-tag-${tag}`}
>
{tag}
</Badge>
))}
</div>
<p className="text-slate-600" data-testid="onboarding-application-card-registration">{application.registrationNumber}</p>
</div>
<Badge
className={getStatusColor(application.status)}
data-testid="onboarding-application-card-status"
>
{application.status}
</Badge>
</div>
<div className="space-y-3 mb-4">
<div className="flex items-center gap-2 text-slate-600">
<MapPin className="w-4 h-4" />
<span data-testid="onboarding-application-card-location">{application.preferredLocation}</span>
{application.rank && application.totalApplicantsAtLocation && (
<Badge variant="outline" data-testid="onboarding-application-card-rank">
Rank {application.rank}/{application.totalApplicantsAtLocation}
</Badge>
)}
</div>
<div className="flex items-start gap-2 text-slate-600">
<Building className="w-4 h-4 mt-0.5" />
<span className="text-sm" data-testid="onboarding-application-card-address">{application.businessAddress}</span>
</div>
<div className="flex items-center gap-2 text-slate-600">
<Mail className="w-4 h-4" />
<span data-testid="onboarding-application-card-email">{application.email}</span>
</div>
<div className="flex items-center gap-2 text-slate-600">
<Phone className="w-4 h-4" />
<span data-testid="onboarding-application-card-phone">{application.phone}</span>
</div>
{application.questionnaireMarks !== undefined && (
<div className="flex items-center gap-2 text-slate-600">
<Award className="w-4 h-4" />
<span data-testid="onboarding-application-card-score">Score: {application.questionnaireMarks}/100</span>
</div>
)}
<div className="flex items-center gap-2 text-slate-600">
<Calendar className="w-4 h-4" />
<span data-testid="onboarding-application-card-submission-date">Submitted: {formatDateTime(application.submissionDate)}</span>
</div>
</div>
{/* Progress Bar */}
<div className="mb-4">
<div className="flex items-center justify-between mb-2">
<span className="text-slate-600">Progress</span>
<span className="text-slate-900" data-testid="onboarding-application-card-progress-text">{application.progress}%</span>
</div>
<Progress value={application.progress} className="h-2" data-testid="onboarding-application-card-progress-bar" />
</div>
{/* Deadline Warning */}
{application.deadline && application.status === 'Questionnaire Pending' && (
<div className="mb-4 p-3 bg-orange-50 border border-orange-200 rounded-md" data-testid="onboarding-application-card-deadline-warning">
<p className="text-orange-800">
Deadline: {formatDateTime(application.deadline)}
</p>
</div>
)}
<Button
onClick={() => onViewDetails(application.id)}
className="w-full bg-amber-600 hover:bg-amber-700"
data-testid="onboarding-application-card-view-button"
>
View Details
</Button>
</div>
);
}