Files
Filamenteka/src/components/ColorSwatch.tsx
DaX 808ca077fa Major frontend and admin improvements
Frontend changes:
- Removed brand filter and column from table
- Removed inventory summary grid
- Removed stanje (state) and težina (weight) columns
- Reorganized filters: Material → Finish → Color
- Updated EnhancedFilters component with new filter structure
- Removed legend section for storage conditions

Admin dashboard changes:
- Removed sidebar navigation (Boje option)
- Made dashboard full screen
- Removed brand column from table
- Removed brand field from add/edit form
- Updated all boolean columns to use checkmark/X icons
- Made color tiles 40% bigger
- Added sortable columns functionality
- Auto-fill price: 3499 for refill, 3999 for regular

Other improvements:
- Added BackToTop button component on all pages
- Fixed Next.js dialog backdrop CSS error
- Updated tests to match new UI structure
- Removed obsolete FilamentTable.tsx component
- Ensured proper synchronization between admin and frontend

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-06-23 22:27:43 +02:00

79 lines
2.2 KiB
TypeScript

import React from 'react';
interface ColorSwatchProps {
name: string;
hex?: string;
size?: 'sm' | 'md' | 'lg';
showLabel?: boolean;
className?: string;
}
export const ColorSwatch: React.FC<ColorSwatchProps> = ({
name,
hex,
size = 'md',
showLabel = true,
className = ''
}) => {
const sizeClasses = {
sm: 'w-7 h-7',
md: 'w-8 h-8',
lg: 'w-10 h-10'
};
// Default color mappings if hex is not provided
const defaultColors: Record<string, string> = {
'Black': '#000000',
'White': '#FFFFFF',
'Gray': '#808080',
'Red': '#FF0000',
'Blue': '#0000FF',
'Green': '#00FF00',
'Yellow': '#FFFF00',
'Transparent': 'rgba(255, 255, 255, 0.1)'
};
const getColorFromName = (colorName: string): string => {
// Check exact match first
if (defaultColors[colorName]) return defaultColors[colorName];
// Check if color name contains a known color
const lowerName = colorName.toLowerCase();
for (const [key, value] of Object.entries(defaultColors)) {
if (lowerName.includes(key.toLowerCase())) {
return value;
}
}
// Generate a color from the name hash
let hash = 0;
for (let i = 0; i < colorName.length; i++) {
hash = colorName.charCodeAt(i) + ((hash << 5) - hash);
}
const hue = hash % 360;
return `hsl(${hue}, 70%, 50%)`;
};
const backgroundColor = hex || getColorFromName(name);
const isLight = backgroundColor.startsWith('#') &&
parseInt(backgroundColor.slice(1, 3), 16) > 200 &&
parseInt(backgroundColor.slice(3, 5), 16) > 200 &&
parseInt(backgroundColor.slice(5, 7), 16) > 200;
return (
<div className={`flex items-center gap-2 ${className}`}>
<div
className={`${sizeClasses[size]} rounded border border-gray-300 dark:border-gray-600`}
style={{ backgroundColor }}
title={name}
>
{name.toLowerCase().includes('transparent') && (
<div className="w-full h-full rounded bg-gradient-to-br from-gray-200 to-gray-300 opacity-50" />
)}
</div>
{showLabel && (
<span className="text-sm text-gray-700 dark:text-gray-300">{name}</span>
)}
</div>
);
};