E-Commerce
Stock Levels Card - Real-time Inventory
Monitor real-time stock levels and inventory availability. Track inventory quantities by location.
Stock Levels Card
The Stock Levels Card Monitor real-time inventory levels across products.
Preview
Installation
ash npx shadcn@latest add https://vectormotion.vercel.app/registry/stock-levels-card.json
Stock Levels Card
'use client';import React from "react";import { Package, AlertCircle, TrendingDown } from "lucide-react";import { motion } from "motion/react";import { clsx, type ClassValue } from "clsx";import { twMerge } from "tailwind-merge";function cn(...inputs: ClassValue[]) { return twMerge(clsx(inputs));}interface Product { name: string; stock: number; status: "good" | "low" | "critical"; max: number; [key: string]: any;}interface StockLevelsCardProps { className?: string; title?: string; description?: string; totalUnits?: string; lowStockItems?: number; products?: Product[];}const DEFAULT_TITLE = "Stock Levels";const DEFAULT_DESCRIPTION = "Real-time inventory tracking";const DEFAULT_TOTAL_UNITS = "824 units";const DEFAULT_LOW_STOCK_ITEMS = 2;const DEFAULT_PRODUCTS: Product[] = [ { name: "Wireless Earbuds", stock: 245, status: "good", max: 500 }, { name: "Smart Watch", stock: 89, status: "low", max: 200 }, { name: "Phone Case", stock: 456, status: "good", max: 600 }, { name: "USB-C Cable", stock: 34, status: "critical", max: 150 },];export const StockLevelsCard: React.FC<StockLevelsCardProps> = ({ className = "", title = DEFAULT_TITLE, description = DEFAULT_DESCRIPTION, totalUnits = DEFAULT_TOTAL_UNITS, lowStockItems = DEFAULT_LOW_STOCK_ITEMS, products = DEFAULT_PRODUCTS,}) => { const isInteractive = true; const index = 11; const getStatusColor = (status: string) => { if (status === "good") return "bg-emerald-500"; if (status === "low") return "bg-amber-500"; return "bg-red-500"; }; return ( <motion.div layoutId={isInteractive ? `card-${index}-${title}` : undefined} transition={{ duration: 0.4, ease: "easeOut" }} className={cn( "relative overflow-hidden rounded-xl border border-border bg-card text-card-foreground p-6 shadow-sm transition-all flex flex-col group", isInteractive ? "cursor-pointer hover:border-zinc-300 dark:hover:border-zinc-700" : "", className, )} > <div className="mb-4 flex items-start justify-between relative z-10"> <div> <h3 className="font-semibold text-lg tracking-tight text-foreground"> {title} </h3> {description && ( <p className="text-sm text-muted-foreground mt-1">{description}</p> )} </div> <div className="rounded-full bg-zinc-100 dark:bg-zinc-800 p-2 text-foreground flex items-center justify-center"> <Package className="h-5 w-5 text-blue-500" /> </div> </div> <div className="relative z-10 flex-1"> <div className="flex items-center gap-2 mb-4"> <div className="text-2xl font-bold text-foreground">{totalUnits}</div> <div className="flex items-center gap-1 text-sm"> <TrendingDown className="h-4 w-4 text-amber-500" /> <span className="text-amber-500">{lowStockItems} low stock</span> </div> </div> <div className="space-y-3"> {products.map((product, idx) => ( <div key={idx}> <div className="flex justify-between items-center mb-1"> <div className="flex items-center gap-2"> <span className="text-sm text-foreground"> {product.name} </span> {product.status === "critical" && ( <AlertCircle className="h-3 w-3 text-red-500" /> )} </div> <span className="text-sm font-bold text-foreground"> {product.stock} </span> </div> <div className="flex items-center gap-2"> <div className="flex-1 bg-zinc-100 dark:bg-zinc-800 rounded-full h-2 overflow-hidden"> <motion.div initial={{ width: 0 }} animate={{ width: `${(product.stock / product.max) * 100}%`, }} transition={{ duration: 1, delay: idx * 0.1 }} className={`h-full ${getStatusColor(product.status)} rounded-full`} /> </div> <span className="text-xs text-muted-foreground w-12 text-right"> {Math.round((product.stock / product.max) * 100)}% </span> </div> </div> ))} </div> </div> </motion.div> );};Usage
This component is a data-rich dashboard card displaying e-commerce metrics with animated visualizations and dark mode support. Perfect for dashboards, landing pages, and analytics interfaces.
Prop
Type