import { useParams, useNavigate } from "react-router-dom"; import { useEffect, useState } from "react"; import { ArrowLeft, Download } from "lucide-react"; import { Button } from "@/components/ui/button"; import { Card } from "@/components/ui/card"; import { dealerService } from "@/api/services/dealer.service"; import { useToast } from "@/components/ui/use-toast"; import { useAuth } from "@/hooks/useAuth"; import { LoadingSpinner } from "@/components/common/LoadingSpinner"; interface ProductScore { month: string; month_key: string; score: number; } interface ProductTrend { product: string; scores: ProductScore[]; } interface DealerData { dealer_id: string; dealer_name: string; mfms_id: string; location: string; overall_credit_score: number; period: string; products: ProductTrend[]; } const ScoreCard = () => { const { id } = useParams(); const navigate = useNavigate(); const { toast } = useToast(); const { user, userRole, loading } = useAuth(); const [dealerData, setDealerData] = useState(null); const [fetchingData, setFetchingData] = useState(true); const [error, setError] = useState(null); // Fetch data from API useEffect(() => { const fetchData = async () => { if (!id) { setFetchingData(false); return; } setFetchingData(true); setError(null); try { const response = await dealerService.getProductWiseScoreTrends(id); if (response.success && response.data) { setDealerData(response.data); } else { setError('Failed to fetch dealer score trends'); } } catch (err) { console.error('Error fetching score trends:', err); setError('Failed to load dealer data'); } finally { setFetchingData(false); } }; fetchData(); }, [id]); useEffect(() => { if (!loading && !user) { navigate('/login'); } // Redirect bank customers away from scorecard if (!loading && userRole === 'bank_customer') { navigate(`/dealer/${id}`); toast({ title: "Access Denied", description: "Score card is not available for your role", variant: "destructive", }); } }, [user, userRole, loading, navigate, id, toast]); const handleDownload = () => { toast({ title: "Download Started", description: "Exporting score card as Excel...", }); }; const getScoreColor = (score: number) => { if (score >= 750) return "text-[#16A34A] bg-[#E8F5E9]"; if (score >= 500) return "text-[#F59E0B] bg-[#FEF3C7]"; return "text-[#EF4444] bg-[#FEE2E2]"; }; const getScoreColorText = (score: number) => { if (score >= 750) return "text-[#16A34A]"; if (score >= 500) return "text-[#F59E0B]"; return "text-[#EF4444]"; }; // Loading state if (loading || fetchingData) { return (
); } // Error or not found state if (error || !dealerData) { return (

{error || 'Dealer Not Found'}

); } // Get months from first product's scores const months = dealerData.products[0]?.scores?.map(s => s.month) || []; return (
{/* Header */}

Dealer Score Card

Product-wise Performance Trends

{/* Card 1: Dealer Info Header */}

{dealerData.dealer_name}

MFMS ID: {dealerData.mfms_id} Location: {dealerData.location}

Overall Credit Score

{dealerData.overall_credit_score}

{/* Card 2: Table with Header */}

Month-on-Month Product-wise Score Trends

Scores are calculated based on various performance metrics. Total weightage per product per month: 1000 points

{months.map((month: string, idx: number) => ( ))} {dealerData.products.map((product: ProductTrend, idx: number) => ( {product.scores.map((scoreData: ProductScore, scoreIdx: number) => ( ))} ))}
Product {month}
{product.product} {scoreData.score}
{/* Card 3: Legend */}
Excellent (750-1000)
Good (500-749)
Needs Attention (<500)
No Data
{/* Card 4: Footer Note */}

Note: This score card provides a detailed view of product-wise performance trends over the last 6 months. Scores are calculated based on sales velocity, purchase consistency, stock management, and payment timeliness for each product category.

); }; export default ScoreCard;