D360-Frontend/src/components/dealer/DealerSnapshot.tsx

130 lines
6.1 KiB
TypeScript

import { memo } from 'react';
import { User } from 'lucide-react';
import { Card } from '@/components/ui/card';
import type { Dealer } from '@/lib/mockData';
interface DealerSnapshotProps {
dealer: Dealer;
title?: string;
}
export const DealerSnapshot = memo(({ dealer, title = "Dealer Snapshot" }: DealerSnapshotProps) => {
const snapshotItems = [
{ label: "Type", value: dealer.dealerType },
{ label: "Total Companies Associated", value: dealer.noOfCompanies },
{ label: "Active Products", value: dealer.noOfProducts },
{ label: "Total Sales (6M Rolling)", value: `${dealer.totalSales6M} MT` },
{ label: "Total Purchase (6M Rolling)", value: `${dealer.totalPurchase6M} MT` },
{ label: "Avg. Liquidity Cycle (3M Weighted)", value: `${dealer.avgLiquidityCycle > 0 ? dealer.avgLiquidityCycle.toFixed(1) : 0} Days` },
{ label: "Avg. Acknowledgment Cycle (3M Weighted)", value: `${dealer.avgAcknowledgmentCycle > 0 ? dealer.avgAcknowledgmentCycle.toFixed(1) : 0} Days` },
{ label: "Avg. Stock Age", value: `${dealer.stockAge} Days` },
{ label: "Aged Stock (>90 Days)", value: `${dealer.agedStock} MT` },
{ label: "Current Stock Quantity", value: `${dealer.currentStock} MT` },
];
return (
<Card className="p-4 sm:p-6">
<div className="flex items-center gap-2 mb-4">
<User className="h-5 w-5 text-primary" />
<h2 className="text-xl font-semibold text-foreground">{title}</h2>
</div>
<div className="space-y-3">
{snapshotItems.map((item, idx) => (
<div key={idx} className="flex flex-col min-[450px]:flex-row justify-between py-2 border-b border-border last:border-0 gap-1 min-[450px]:gap-4">
<span className="text-xs sm:text-sm text-muted-foreground">{item.label}</span>
<span className="text-sm font-medium text-foreground">{item.value}</span>
</div>
))}
</div>
</Card>
);
});
DealerSnapshot.displayName = 'DealerSnapshot';
// Compare My Dealer Business variant for manufacturers
interface ManufacturerData {
type: string;
totalCompanies?: number;
total_companies_associated?: number;
activeProducts?: number;
active_products?: number;
totalSales?: number;
total_sales_6m_rolling?: number | { value: number; unit: string };
totalPurchase?: number;
total_purchase_6m_rolling?: number | { value: number; unit: string };
avgLiquidityCycle?: number;
avg_liquidity_cycle_3m_weighted?: number | { value: number; unit: string };
avgAcknowledgmentCycle?: number;
avg_acknowledgment_cycle_3m_weighted?: number | { value: number; unit: string };
avgStockAge?: number;
avg_stock_age?: number | { value: number; unit: string };
agedStock?: number;
aged_stock_over_90_days?: number | { value: number; unit: string };
currentStock?: number;
current_stock_quantity?: number | { value: number; unit: string };
}
interface CompareBusinessSnapshotProps {
data: ManufacturerData;
}
export const CompareBusinessSnapshot = memo(({ data }: CompareBusinessSnapshotProps) => {
// Helper function to extract value from API response (handles both formats)
const getValue = (value: number | { value: number; unit: string } | undefined, defaultVal: number = 0): number => {
if (value === undefined) return defaultVal;
if (typeof value === 'number') return value;
return value.value || defaultVal;
};
// Helper function to get unit from API response
const getUnit = (value: number | { value: number; unit: string } | undefined, defaultUnit: string = ''): string => {
if (value === undefined || typeof value === 'number') return defaultUnit;
return value.unit || defaultUnit;
};
// Extract values from API response format or fallback to direct values
const type = data.type || 'N/A';
const totalCompanies = data.total_companies_associated ?? data.totalCompanies ?? 0;
const activeProducts = data.active_products ?? data.activeProducts ?? 0;
const totalSales = getValue(data.total_sales_6m_rolling ?? data.totalSales, 0);
const totalPurchase = getValue(data.total_purchase_6m_rolling ?? data.totalPurchase, 0);
const avgLiquidityCycle = getValue(data.avg_liquidity_cycle_3m_weighted ?? data.avgLiquidityCycle, 0);
const avgAcknowledgmentCycle = getValue(data.avg_acknowledgment_cycle_3m_weighted ?? data.avgAcknowledgmentCycle, 0);
const avgStockAge = getValue(data.avg_stock_age ?? data.avgStockAge, 0);
const agedStock = getValue(data.aged_stock_over_90_days ?? data.agedStock, 0);
const currentStock = getValue(data.current_stock_quantity ?? data.currentStock, 0);
const snapshotItems = [
{ label: "Type", value: type },
{ label: "Total Companies Associated", value: totalCompanies },
{ label: "Active Products", value: activeProducts },
{ label: "Total Sales (6M Rolling)", value: `${totalSales} MT` },
{ label: "Total Purchase (6M Rolling)", value: `${totalPurchase} MT` },
{ label: "Avg. Liquidity Cycle (3M Weighted)", value: `${avgLiquidityCycle > 0 ? avgLiquidityCycle.toFixed(1) : 0} Days` },
{ label: "Avg. Acknowledgment Cycle (3M Weighted)", value: `${avgAcknowledgmentCycle > 0 ? avgAcknowledgmentCycle.toFixed(1) : 0} Days` },
{ label: "Avg. Stock Age", value: `${avgStockAge} Days` },
{ label: "Aged Stock (>90 Days)", value: `${agedStock} MT` },
{ label: "Current Stock Quantity", value: `${currentStock} MT` },
];
return (
<Card className="p-4 sm:p-6">
<div className="flex items-center gap-2 mb-4">
<User className="h-5 w-5 text-primary" />
<h2 className="text-xl font-semibold text-foreground">Compare My Dealer Business</h2>
</div>
<div className="space-y-3">
{snapshotItems.map((item, idx) => (
<div key={idx} className="flex flex-col min-[400px]:flex-row justify-between py-2 border-b border-border last:border-0 gap-1 min-[400px]:gap-4">
<span className="text-xs sm:text-sm text-muted-foreground">{item.label}</span>
<span className="text-sm font-medium text-foreground">{item.value}</span>
</div>
))}
</div>
</Card>
);
});
CompareBusinessSnapshot.displayName = 'CompareBusinessSnapshot';