mirror of
https://github.com/christianvidalwolf-prog/CrazeAnalytix.git
synced 2026-08-03 13:05:24 +02:00
Add custom icons to stock and coverage filters for better visibility
This commit is contained in:
@@ -6,6 +6,7 @@ import { StockBadge } from './StockBadge';
|
||||
import { Top50Badge } from './Top50Badge';
|
||||
import { VendorStockBadge } from './VendorStockBadge';
|
||||
import { InColumnStockFilter } from './InColumnStockFilter';
|
||||
import { WarehouseIcon, AmazonSmileIcon, CoverageIcon } from './Icons';
|
||||
|
||||
interface AdsPerformanceProps {
|
||||
data: CombinedKPIs[];
|
||||
@@ -427,11 +428,13 @@ const AdsPerformance: React.FC<AdsPerformanceProps> = ({
|
||||
currentFilters={stockFilter}
|
||||
onFilterChange={onStockFilterChange}
|
||||
title="Warehouse Stock"
|
||||
icon={<WarehouseIcon className="w-3.5 h-3.5 text-fuchsia-400" />}
|
||||
/>
|
||||
<InColumnStockFilter
|
||||
currentFilters={vendorStockFilter}
|
||||
onFilterChange={onVendorStockFilterChange}
|
||||
title="Vendor Stock"
|
||||
icon={<AmazonSmileIcon className="w-5 h-5 text-amber-500" />}
|
||||
options={[
|
||||
'Out of Stock (0)',
|
||||
'In Stock (>0)',
|
||||
@@ -443,6 +446,7 @@ const AdsPerformance: React.FC<AdsPerformanceProps> = ({
|
||||
currentFilters={wocFilter}
|
||||
onFilterChange={onWocFilterChange}
|
||||
title="Week Coverage"
|
||||
icon={<CoverageIcon className="w-3.5 h-3.5 text-emerald-400" />}
|
||||
options={[
|
||||
'< 4 Weeks',
|
||||
'> 4 Weeks',
|
||||
|
||||
@@ -3,6 +3,7 @@ import * as XLSX from 'xlsx';
|
||||
import { ProductForecastData, FilterState, CombinedKPIs } from '../types';
|
||||
import { DownloadIcon, FunnelIcon, TrendingIcon, ChartIcon } from './Icons';
|
||||
import { StockBadge } from './StockBadge';
|
||||
import { WarehouseIcon, AmazonSmileIcon, CoverageIcon } from './Icons';
|
||||
import { Top50Badge } from './Top50Badge';
|
||||
import { VendorStockBadge } from './VendorStockBadge';
|
||||
import { InColumnStockFilter } from './InColumnStockFilter';
|
||||
@@ -436,10 +437,29 @@ const ForecastView: React.FC<ForecastViewProps> = ({
|
||||
className="bg-slate-950 border border-white/10 rounded-xl px-4 py-2 text-sm text-white focus:outline-none w-64"
|
||||
/>
|
||||
<button onClick={handleExportExcel} className="p-2 bg-slate-800 hover:bg-slate-700 text-white rounded-xl border border-white/5 transition-all"><DownloadIcon /></button>
|
||||
<InColumnStockFilter
|
||||
currentFilters={stockFilter}
|
||||
onFilterChange={onStockFilterChange}
|
||||
title="Warehouse Stock"
|
||||
icon={<WarehouseIcon className="w-3.5 h-3.5 text-fuchsia-400" />}
|
||||
/>
|
||||
<InColumnStockFilter
|
||||
currentFilters={vendorStockFilter}
|
||||
onFilterChange={onVendorStockFilterChange}
|
||||
title="Vendor Stock"
|
||||
icon={<AmazonSmileIcon className="w-5 h-5 text-amber-500" />}
|
||||
options={[
|
||||
'Out of Stock (0)',
|
||||
'In Stock (>0)',
|
||||
'In Stock (>20)',
|
||||
'Low Stock (<10)',
|
||||
]}
|
||||
/>
|
||||
<InColumnStockFilter
|
||||
currentFilters={wocFilter}
|
||||
onFilterChange={onWocFilterChange}
|
||||
title="Week Coverage"
|
||||
icon={<CoverageIcon className="w-3.5 h-3.5 text-emerald-400" />}
|
||||
options={[
|
||||
'< 4 Weeks',
|
||||
'> 4 Weeks',
|
||||
|
||||
+30
-9
@@ -27,15 +27,15 @@ export const SendIcon = () => (
|
||||
);
|
||||
|
||||
export const ChartIcon = () => (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" className="w-5 h-5">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" d="M3.75 3v11.25A2.25 2.25 0 0 0 6 16.5h2.25M3.75 3h-1.5m1.5 0h16.5m0 0h1.5m-1.5 0v11.25A2.25 2.25 0 0 1 18 16.5h-2.25m-7.5 0h7.5m-7.5 0-1 3m8.5-3 1 3m0 0 .5 1.5m-.5-1.5h-9.5m0 0-.5 1.5M9 11.25v1.5M12 9v3.75m3-6v6" />
|
||||
</svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" className="w-5 h-5">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" d="M3.75 3v11.25A2.25 2.25 0 0 0 6 16.5h2.25M3.75 3h-1.5m1.5 0h16.5m0 0h1.5m-1.5 0v11.25A2.25 2.25 0 0 1 18 16.5h-2.25m-7.5 0h7.5m-7.5 0-1 3m8.5-3 1 3m0 0 .5 1.5m-.5-1.5h-9.5m0 0-.5 1.5M9 11.25v1.5M12 9v3.75m3-6v6" />
|
||||
</svg>
|
||||
);
|
||||
|
||||
export const TableIcon = () => (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" className="w-5 h-5">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" d="M3.375 19.5h17.25m-17.25 0a1.125 1.125 0 0 1-1.125-1.125M3.375 19.5h7.5c.621 0 1.125-.504 1.125-1.125m-9.75 0V5.625m0 12.75v-1.5c0-.621.504-1.125 1.125-1.125m18.375 2.625V5.625m0 12.75c0 .621-.504 1.125-1.125 1.125m1.125-1.125v-1.5c0-.621-.504-1.125-1.125-1.125m0 3h-7.5c-.621 0-1.125-.504-1.125-1.125m16.875-12.75a1.125 1.125 0 0 0-1.125-1.125H3.375a1.125 1.125 0 0 0-1.125 1.125m19.5 0v1.5c0 .621-.504 1.125-1.125 1.125M2.25 5.625v1.5c0 .621.504 1.125 1.125 1.125m0 0h17.25m-17.25 0h7.5c.621 0 1.125.504 1.125 1.125M3.375 8.25v1.5c0 .621.504 1.125 1.125 1.125m17.25-2.625v1.5c0 .621-.504 1.125-1.125 1.125m-17.25 0h7.5m-7.5 0h17.25" />
|
||||
</svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" className="w-5 h-5">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" d="M3.375 19.5h17.25m-17.25 0a1.125 1.125 0 0 1-1.125-1.125M3.375 19.5h7.5c.621 0 1.125-.504 1.125-1.125m-9.75 0V5.625m0 12.75v-1.5c0-.621.504-1.125 1.125-1.125m18.375 2.625V5.625m0 12.75c0 .621-.504 1.125-1.125 1.125m1.125-1.125v-1.5c0-.621-.504-1.125-1.125-1.125m0 3h-7.5c-.621 0-1.125-.504-1.125-1.125m16.875-12.75a1.125 1.125 0 0 0-1.125-1.125H3.375a1.125 1.125 0 0 0-1.125 1.125m19.5 0v1.5c0 .621-.504 1.125-1.125 1.125M2.25 5.625v1.5c0 .621.504 1.125 1.125 1.125m0 0h17.25m-17.25 0h7.5c.621 0 1.125.504 1.125 1.125M3.375 8.25v1.5c0 .621.504 1.125 1.125 1.125m17.25-2.625v1.5c0 .621-.504 1.125-1.125 1.125m-17.25 0h7.5m-7.5 0h17.25" />
|
||||
</svg>
|
||||
);
|
||||
|
||||
export const SearchIcon = () => (
|
||||
@@ -51,9 +51,9 @@ export const DownloadIcon = () => (
|
||||
);
|
||||
|
||||
export const FunnelIcon = () => (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" className="w-5 h-5">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" d="M12 3c2.755 0 5.455.232 8.083.678.533.09.917.556.917 1.096v1.044a2.25 2.25 0 0 1-.659 1.591l-5.432 5.432a2.25 2.25 0 0 0-.659 1.591v2.927a2.25 2.25 0 0 1-1.244 2.013L9.75 21v-6.568a2.25 2.25 0 0 0-.659-1.591L3.659 7.409A2.25 2.25 0 0 1 3 5.818V4.774c0-.54.384-1.006.917-1.096A48.32 48.32 0 0 1 12 3Z" />
|
||||
</svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" className="w-5 h-5">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" d="M12 3c2.755 0 5.455.232 8.083.678.533.09.917.556.917 1.096v1.044a2.25 2.25 0 0 1-.659 1.591l-5.432 5.432a2.25 2.25 0 0 0-.659 1.591v2.927a2.25 2.25 0 0 1-1.244 2.013L9.75 21v-6.568a2.25 2.25 0 0 0-.659-1.591L3.659 7.409A2.25 2.25 0 0 1 3 5.818V4.774c0-.54.384-1.006.917-1.096A48.32 48.32 0 0 1 12 3Z" />
|
||||
</svg>
|
||||
);
|
||||
|
||||
export const TrendingIcon = () => (
|
||||
@@ -67,3 +67,24 @@ export const MegaphoneIcon = () => (
|
||||
<path strokeLinecap="round" strokeLinejoin="round" d="M10.34 15.84c-.688-.06-1.386-.09-2.09-.09H7.5a4.5 4.5 0 1 1 0-9h.75c.704 0 1.402-.03 2.09-.09m0 9.18c.253.962.584 1.892.985 2.783.247.55.06 1.21-.463 1.511l-.657.38c-.551.318-1.26.117-1.527-.461a20.845 20.845 0 0 1-1.44-4.282m3.102.069a18.03 18.03 0 0 1-.59-4.59c0-1.586.205-3.124.59-4.59m0 9.18a23.848 23.848 0 0 1 8.835 2.535M10.34 6.66a23.847 23.847 0 0 0 8.835-2.535m0 0A23.74 23.74 0 0 0 18.795 3m.38 1.125a23.91 23.91 0 0 1 1.014 5.795 23.91 23.91 0 0 1-1.014 5.795m0-11.589a23.917 23.917 0 0 1 6.391 5.34" />
|
||||
</svg>
|
||||
);
|
||||
|
||||
export const WarehouseIcon = ({ className = "w-4 h-4" }) => (
|
||||
<svg className={className} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
||||
<path d="M21 8L12 3L3 8V16L12 21L21 16V8Z" />
|
||||
<path d="M3 8L12 13L21 8" />
|
||||
<path d="M12 13V21" />
|
||||
</svg>
|
||||
);
|
||||
|
||||
export const AmazonSmileIcon = ({ className = "w-4 h-4" }) => (
|
||||
<svg className={className} viewBox="0 0 24 24" fill="currentColor">
|
||||
<path d="M18.66 15.65c-2.31 1.76-6.22 2.45-9.14 1.35-1-.38-2.22-1.05-2.02-2.12.15-.81 1.12-.72 1.83-.58 2.57.51 6.27.32 8.35-.67.4-.19 1-.53 1.33-.14.33.39-.12 1.25-.35 2.16zM19.78 12.78c-.32-.43-2.31-.15-3.32-.01-.36.05-.76.12-.86-.24-.13-.49.71-.9 1.12-1.06 1.11-.42 2.66-.78 3.3.01.53.64.08 1.8-.24 1.3z" />
|
||||
</svg>
|
||||
);
|
||||
|
||||
export const CoverageIcon = ({ className = "w-4 h-4" }) => (
|
||||
<svg className={className} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
||||
<circle cx="12" cy="12" r="10" />
|
||||
<polyline points="12 6 12 12 16 14" />
|
||||
</svg>
|
||||
);
|
||||
|
||||
@@ -5,6 +5,7 @@ interface InColumnStockFilterProps {
|
||||
onFilterChange: (newFilters: string[]) => void;
|
||||
title?: string;
|
||||
options?: string[];
|
||||
icon?: React.ReactNode;
|
||||
}
|
||||
|
||||
const DEFAULT_STOCK_OPTIONS = [
|
||||
@@ -17,7 +18,8 @@ export const InColumnStockFilter: React.FC<InColumnStockFilterProps> = ({
|
||||
currentFilters,
|
||||
onFilterChange,
|
||||
title = "Stock Filter",
|
||||
options = DEFAULT_STOCK_OPTIONS
|
||||
options = DEFAULT_STOCK_OPTIONS,
|
||||
icon
|
||||
}) => {
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
@@ -55,12 +57,18 @@ export const InColumnStockFilter: React.FC<InColumnStockFilterProps> = ({
|
||||
e.stopPropagation();
|
||||
setIsOpen(!isOpen);
|
||||
}}
|
||||
className={`p-1 rounded hover:bg-white/10 transition-colors ${currentFilters.length > 0 ? 'text-indigo-400 bg-indigo-500/10' : 'text-slate-500'}`}
|
||||
title="Filter by Stock"
|
||||
className={`flex flex-col items-center gap-0.5 p-1 rounded hover:bg-white/10 transition-all ${currentFilters.length > 0 ? 'text-indigo-400 bg-indigo-500/10' : 'text-slate-500'}`}
|
||||
title={`Filter by ${title}`}
|
||||
>
|
||||
<svg className="w-3 h-3" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={3} d="M3 4a1 1 0 011-1h16a1 1 0 011 1v2.586a1 1 0 01-.293.707l-6.414 6.414a1 1 0 00-.293.707V17l-4 4v-6.586a1 1 0 00-.293-.707L3.293 7.293A1 1 0 013 6.586V4z" />
|
||||
</svg>
|
||||
{icon ? (
|
||||
<div className="transition-transform group-hover:scale-110">
|
||||
{icon}
|
||||
</div>
|
||||
) : (
|
||||
<svg className="w-3 h-3" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={3} d="M3 4a1 1 0 011-1h16a1 1 0 011 1v2.586a1 1 0 01-.293.707l-6.414 6.414a1 1 0 00-.293.707V17l-4 4v-6.586a1 1 0 00-.293-.707L3.293 7.293A1 1 0 013 6.586V4z" />
|
||||
</svg>
|
||||
)}
|
||||
</button>
|
||||
|
||||
{isOpen && (
|
||||
|
||||
@@ -6,6 +6,7 @@ import { StockBadge } from './StockBadge';
|
||||
import { InColumnStockFilter } from './InColumnStockFilter';
|
||||
import { Top50Badge } from './Top50Badge';
|
||||
import { VendorStockBadge } from './VendorStockBadge';
|
||||
import { WarehouseIcon, AmazonSmileIcon, CoverageIcon } from './Icons';
|
||||
|
||||
interface WeeklyGridProps {
|
||||
data: CombinedKPIs[];
|
||||
@@ -518,11 +519,13 @@ const WeeklyGrid: React.FC<WeeklyGridProps & { top50Mode: 'eu' | 'uk' }> = ({
|
||||
currentFilters={stockFilter}
|
||||
onFilterChange={onStockFilterChange}
|
||||
title="Warehouse Stock"
|
||||
icon={<WarehouseIcon className="w-3.5 h-3.5 text-fuchsia-400" />}
|
||||
/>
|
||||
<InColumnStockFilter
|
||||
currentFilters={vendorStockFilter}
|
||||
onFilterChange={onVendorStockFilterChange}
|
||||
title="Vendor Stock"
|
||||
icon={<AmazonSmileIcon className="w-5 h-5 text-amber-500" />}
|
||||
options={[
|
||||
'Out of Stock (0)',
|
||||
'In Stock (>0)',
|
||||
@@ -534,6 +537,7 @@ const WeeklyGrid: React.FC<WeeklyGridProps & { top50Mode: 'eu' | 'uk' }> = ({
|
||||
currentFilters={wocFilter}
|
||||
onFilterChange={onWocFilterChange}
|
||||
title="Week Coverage"
|
||||
icon={<CoverageIcon className="w-3.5 h-3.5 text-emerald-400" />}
|
||||
options={[
|
||||
'< 4 Weeks',
|
||||
'> 4 Weeks',
|
||||
|
||||
Reference in New Issue
Block a user