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>
This commit is contained in:
89
src/components/InventoryBadge.tsx
Normal file
89
src/components/InventoryBadge.tsx
Normal file
@@ -0,0 +1,89 @@
|
||||
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>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user