Files
Filamenteka/src/components/InventoryBadge.tsx
DaX 18110ab159 Major restructure: Remove Confluence, add V2 data structure, organize for dev/prod
- Import real data from PDF (35 Bambu Lab filaments)
- Remove all Confluence integration and dependencies
- Implement new V2 data structure with proper inventory tracking
- Add backwards compatibility for existing data
- Create enhanced UI components (ColorSwatch, InventoryBadge, MaterialBadge)
- Add advanced filtering with quick filters and multi-criteria search
- Organize codebase for dev/prod environments
- Update Lambda functions to support both V1/V2 formats
- Add inventory summary dashboard
- Clean up project structure and documentation

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-06-20 01:12:50 +02:00

89 lines
3.3 KiB
TypeScript

import React from 'react';
interface InventoryBadgeProps {
type: 'vacuum' | 'opened' | 'printer' | 'total' | 'available';
count: number;
className?: string;
}
export const InventoryBadge: React.FC<InventoryBadgeProps> = ({ type, count, className = '' }) => {
if (count === 0) return null;
const getIcon = () => {
switch (type) {
case 'vacuum':
return (
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2}
d="M20 7l-8-4-8 4m16 0l-8 4m8-4v10l-8 4m0-10L4 7m8 4v10M4 7v10l8 4" />
</svg>
);
case 'opened':
return (
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2}
d="M20 13V6a2 2 0 00-2-2H6a2 2 0 00-2 2v7m16 0v5a2 2 0 01-2 2H6a2 2 0 01-2-2v-5m16 0h-2.586a1 1 0 00-.707.293l-2.414 2.414a1 1 0 01-.707.293h-3.172a1 1 0 01-.707-.293l-2.414-2.414A1 1 0 006.586 13H4" />
</svg>
);
case 'printer':
return (
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2}
d="M17 17h2a2 2 0 002-2v-4a2 2 0 00-2-2H5a2 2 0 00-2 2v4a2 2 0 002 2h2m2 4h6a2 2 0 002-2v-4a2 2 0 00-2-2H9a2 2 0 00-2 2v4a2 2 0 002 2zm8-12V5a2 2 0 00-2-2H9a2 2 0 00-2 2v4h10z" />
</svg>
);
case 'total':
return (
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2}
d="M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10" />
</svg>
);
case 'available':
return (
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2}
d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
);
}
};
const getColor = () => {
switch (type) {
case 'vacuum':
return 'bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-200';
case 'opened':
return 'bg-yellow-100 text-yellow-800 dark:bg-yellow-900 dark:text-yellow-200';
case 'printer':
return 'bg-purple-100 text-purple-800 dark:bg-purple-900 dark:text-purple-200';
case 'total':
return 'bg-gray-100 text-gray-800 dark:bg-gray-700 dark:text-gray-200';
case 'available':
return 'bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200';
}
};
const getLabel = () => {
switch (type) {
case 'vacuum':
return 'Vakuum';
case 'opened':
return 'Otvoreno';
case 'printer':
return 'U printeru';
case 'total':
return 'Ukupno';
case 'available':
return 'Dostupno';
}
};
return (
<span className={`inline-flex items-center gap-1 px-2 py-1 rounded-full text-xs font-medium ${getColor()} ${className}`}>
{getIcon()}
<span>{count}</span>
<span className="sr-only">{getLabel()}</span>
</span>
);
};