Add At Risk to products views

This commit is contained in:
2025-01-15 14:35:19 -05:00
parent 5747ce3ded
commit f3a39e39ba
4 changed files with 46 additions and 27 deletions

View File

@@ -49,11 +49,12 @@ const FILTER_OPTIONS: FilterOption[] = [
label: 'Stock Status', label: 'Stock Status',
type: 'select', type: 'select',
options: [ options: [
{ label: 'Critical', value: 'Critical' }, { label: 'Critical', value: 'critical' },
{ label: 'Reorder', value: 'Reorder' }, { label: 'At Risk', value: 'at-risk' },
{ label: 'Healthy', value: 'Healthy' }, { label: 'Reorder', value: 'reorder' },
{ label: 'Overstocked', value: 'Overstocked' }, { label: 'Healthy', value: 'healthy' },
{ label: 'New', value: 'New' } { label: 'Overstocked', value: 'overstocked' },
{ label: 'New', value: 'new' }
], ],
group: 'Inventory' group: 'Inventory'
}, },

View File

@@ -85,7 +85,8 @@ function SortableHeader({ column, columnDef, onSort, sortColumn, sortDirection }
style={style} style={style}
className={cn( className={cn(
"cursor-pointer select-none", "cursor-pointer select-none",
columnDef?.width columnDef?.width,
sortColumn === column && "bg-accent/50"
)} )}
{...attributes} {...attributes}
{...listeners} {...listeners}
@@ -95,8 +96,8 @@ function SortableHeader({ column, columnDef, onSort, sortColumn, sortDirection }
{columnDef?.label ?? column} {columnDef?.label ?? column}
{sortColumn === column && ( {sortColumn === column && (
sortDirection === 'desc' sortDirection === 'desc'
? <SortDesc className="h-4 w-4" /> ? <SortDesc className="h-4 w-4 min-w-4" />
: <SortAsc className="h-4 w-4" /> : <SortAsc className="h-4 w-4 min-w-4" />
)} )}
</div> </div>
</TableHead> </TableHead>
@@ -154,21 +155,22 @@ export function ProductTable({
const getStockStatus = (status: string | undefined) => { const getStockStatus = (status: string | undefined) => {
if (!status) return null; if (!status) return null;
switch (status.toLowerCase()) { const normalizedStatus = status.toLowerCase().replace(/-/g, ' ');
switch (normalizedStatus) {
case 'critical': case 'critical':
return <Badge variant="destructive">Critical</Badge>; return <Badge variant="destructive">Critical</Badge>;
case 'reorder': case 'reorder':
return <Badge variant="warning">Reorder</Badge>; return <Badge variant="secondary">Reorder</Badge>;
case 'healthy': case 'healthy':
return <Badge variant="success">Healthy</Badge>; return <Badge variant="default">Healthy</Badge>;
case 'overstocked': case 'overstocked':
return <Badge variant="secondary">Overstocked</Badge>; return <Badge variant="secondary">Overstocked</Badge>;
case 'new': case 'new':
return <Badge variant="default">New</Badge>; return <Badge variant="default">New</Badge>;
case 'out of stock': case 'out of stock':
return <Badge variant="destructive">Out of Stock</Badge>; return <Badge variant="destructive">Out of Stock</Badge>;
case 'at-risk': case 'at risk':
return <Badge variant="warning">At Risk</Badge>; return <Badge variant="secondary">At Risk</Badge>;
default: default:
return <Badge variant="outline">{status}</Badge>; return <Badge variant="outline">{status}</Badge>;
} }

View File

@@ -1,6 +1,15 @@
import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs" import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs"
import { Product } from "@/types/products" import { Product } from "@/types/products"
import { AlertCircle, AlertTriangle, CheckCircle2, PackageSearch, Sparkles } from "lucide-react" import {
AlertTriangle,
AlertCircle,
CheckCircle2,
PackageSearch,
Sparkles,
Timer,
PackagePlus,
PackageX
} from "lucide-react"
export type ProductView = { export type ProductView = {
id: string id: string
@@ -19,35 +28,42 @@ export const PRODUCT_VIEWS: ProductView[] = [
columns: ["image", "title", "SKU", "stock_quantity", "price", "stock_status"] columns: ["image", "title", "SKU", "stock_quantity", "price", "stock_status"]
}, },
{ {
id: "Critical", id: "critical",
label: "Critical Stock", label: "Critical Stock",
icon: AlertTriangle, icon: AlertTriangle,
iconClassName: "", iconClassName: "",
columns: ["image", "title", "SKU", "stock_quantity", "daily_sales_avg", "reorder_qty", "replenishable", "last_purchase_date", "lead_time_status"] columns: ["image", "title", "SKU", "stock_quantity", "daily_sales_avg", "reorder_qty", "last_purchase_date", "lead_time_status"]
}, },
{ {
id: "Reorder", id: "reorder",
label: "Reorder Soon", label: "Reorder Soon",
icon: AlertCircle, icon: PackagePlus,
iconClassName: "", iconClassName: "",
columns: ["image", "title", "SKU", "stock_quantity", "daily_sales_avg", "reorder_qty", "replenishable", "last_purchase_date", "lead_time_status"] columns: ["image", "title", "SKU", "stock_quantity", "daily_sales_avg", "reorder_qty", "last_purchase_date", "lead_time_status"]
}, },
{ {
id: "Healthy", id: "healthy",
label: "Healthy Stock", label: "Healthy Stock",
icon: CheckCircle2, icon: CheckCircle2,
iconClassName: "", iconClassName: "",
columns: ["image", "title", "stock_quantity", "daily_sales_avg", "stock_status", "abc_class"] columns: ["image", "title", "stock_quantity", "daily_sales_avg", "stock_status", "abc_class"]
}, },
{ {
id: "Overstocked", id: "at-risk",
label: "Overstock", label: "At Risk",
icon: PackageSearch, icon: Timer,
iconClassName: "", iconClassName: "",
columns: ["image", "title", "stock_quantity", "daily_sales_avg", "overstocked_amt", "replenishable", "last_sale_date", "abc_class"] columns: ["image", "title", "stock_quantity", "daily_sales_avg", "weekly_sales_avg", "days_of_inventory", "last_sale_date"]
}, },
{ {
id: "New", id: "overstocked",
label: "Overstock",
icon: PackageX,
iconClassName: "",
columns: ["image", "title", "stock_quantity", "daily_sales_avg", "overstocked_amt", "days_of_inventory", "last_sale_date"]
},
{
id: "new",
label: "New Products", label: "New Products",
icon: Sparkles, icon: Sparkles,
iconClassName: "", iconClassName: "",

View File

@@ -127,8 +127,8 @@ const VIEW_COLUMNS: Record<string, ColumnKey[]> = {
'stock_quantity', 'stock_quantity',
'daily_sales_avg', 'daily_sales_avg',
'weekly_sales_avg', 'weekly_sales_avg',
'monthly_sales_avg',
'days_of_inventory', 'days_of_inventory',
'last_sale_date',
], ],
new: [ new: [
'image', 'image',
@@ -241,7 +241,7 @@ export function Products() {
// Add view filter // Add view filter
if (activeView !== 'all') { if (activeView !== 'all') {
params.append('stockStatus', activeView); params.append('stockStatus', activeView === 'at-risk' ? 'At Risk' : activeView);
} }
// Add showNonReplenishable param // Add showNonReplenishable param