mirror of
https://github.com/SamyRai/turash.git
synced 2025-12-26 23:01:33 +00:00
- Remove nested git repository from bugulma/frontend/.git - Add all frontend files to main repository tracking - Convert from separate frontend/backend repos to unified monorepo - Preserve all frontend code and development history as tracked files - Eliminate nested repository complexity for simpler development workflow This creates a proper monorepo structure with frontend and backend coexisting in the same repository for easier development and deployment.
195 lines
6.4 KiB
TypeScript
195 lines
6.4 KiB
TypeScript
import { motion } from 'framer-motion';
|
|
import React from 'react';
|
|
|
|
type BadgeVariant =
|
|
| 'default'
|
|
| 'material'
|
|
| 'outline'
|
|
| 'secondary'
|
|
| 'destructive'
|
|
| 'success'
|
|
| 'construction'
|
|
| 'production'
|
|
| 'recreation'
|
|
| 'logistics'
|
|
| 'protected'
|
|
| 'cultural-heritage'
|
|
| 'historical';
|
|
|
|
interface BadgeProps {
|
|
children: React.ReactNode;
|
|
variant?: BadgeVariant;
|
|
showDot?: boolean;
|
|
dotColor?: 'primary' | 'accent';
|
|
textColor?: 'primary' | 'accent' | 'foreground';
|
|
size?: 'sm' | 'md' | 'lg';
|
|
className?: string;
|
|
animate?: boolean;
|
|
}
|
|
|
|
const Badge: React.FC<BadgeProps> = ({
|
|
children,
|
|
variant = 'default',
|
|
showDot = false,
|
|
dotColor = 'primary',
|
|
textColor,
|
|
size = 'md',
|
|
className = '',
|
|
animate = false,
|
|
}) => {
|
|
const sizeClasses = {
|
|
sm: 'px-3 py-1 text-xs',
|
|
md: 'px-4 py-1.5 lg:px-6 lg:py-2.5 text-sm lg:text-base',
|
|
lg: 'px-5 py-2 lg:px-7 lg:py-3 text-base lg:text-lg',
|
|
};
|
|
|
|
const textColorClasses = {
|
|
primary: 'text-primary',
|
|
accent: 'text-accent',
|
|
foreground: 'text-foreground',
|
|
};
|
|
|
|
const dotColorClasses = {
|
|
primary: 'bg-primary',
|
|
accent: 'bg-accent',
|
|
};
|
|
|
|
const isHeritageVariant = variant === 'protected' || variant === 'cultural-heritage' || variant === 'historical';
|
|
|
|
const baseClasses = variant === 'material'
|
|
? `relative inline-flex items-center gap-2.5 rounded-full font-medium overflow-hidden border-2 ${sizeClasses[size]} ${className}`
|
|
: `relative inline-flex items-center gap-2 rounded-full font-medium ${isHeritageVariant ? '' : 'border'} ${sizeClasses[size]} ${className}`;
|
|
|
|
if (variant === 'material') {
|
|
const finalTextColor = textColor || 'accent';
|
|
const finalDotColor = dotColor;
|
|
|
|
const BadgeContent = (
|
|
<>
|
|
{/* Subtle texture overlay */}
|
|
<div
|
|
className="absolute inset-0 opacity-[0.04] pointer-events-none rounded-full"
|
|
style={{
|
|
backgroundImage: `radial-gradient(circle at 1px 1px, var(--foreground) 1px, transparent 0)`,
|
|
backgroundSize: '8px 8px',
|
|
}}
|
|
/>
|
|
|
|
{showDot && (
|
|
<motion.span
|
|
className={`relative z-10 h-2.5 w-2.5 rounded-full shrink-0 ${dotColorClasses[finalDotColor]}`}
|
|
style={{
|
|
background: `radial-gradient(circle at 30% 30%, var(--${finalDotColor}), var(--${finalDotColor}))`,
|
|
boxShadow: `
|
|
0 2px 4px rgba(0, 0, 0, 0.2),
|
|
inset 0 1px 2px rgba(255, 255, 255, 0.4),
|
|
inset 0 -1px 1px rgba(0, 0, 0, 0.2)
|
|
`,
|
|
}}
|
|
animate={animate ? { scale: [1, 1.2, 1], opacity: [1, 0.9, 1] } : {}}
|
|
transition={{ duration: 2, repeat: Infinity, ease: 'easeInOut' }}
|
|
/>
|
|
)}
|
|
<span className={`relative z-10 ${textColorClasses[finalTextColor]} font-semibold drop-shadow-sm`}>
|
|
{children}
|
|
</span>
|
|
</>
|
|
);
|
|
|
|
if (animate) {
|
|
return (
|
|
<motion.div
|
|
className={`${baseClasses} bg-muted`}
|
|
initial={{ opacity: 0, y: -10 }}
|
|
animate={{ opacity: 1, y: 0 }}
|
|
transition={{ duration: 0.6, delay: 0.3 }}
|
|
whileHover={{ scale: 1.03, y: -2 }}
|
|
style={{
|
|
background: 'linear-gradient(135deg, var(--muted) 0%, var(--card) 50%, var(--muted) 100%)',
|
|
borderColor: 'var(--border)',
|
|
boxShadow: `
|
|
0 2px 4px rgba(0, 0, 0, 0.1),
|
|
0 4px 8px rgba(0, 0, 0, 0.08),
|
|
0 8px 16px rgba(0, 0, 0, 0.06),
|
|
0 0 0 1px rgba(0, 0, 0, 0.05),
|
|
inset 0 -2px 4px rgba(0, 0, 0, 0.1)
|
|
`,
|
|
}}
|
|
>
|
|
{BadgeContent}
|
|
</motion.div>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<div
|
|
className={`${baseClasses} bg-muted`}
|
|
style={{
|
|
background: 'linear-gradient(135deg, var(--muted) 0%, var(--card) 50%, var(--muted) 100%)',
|
|
borderColor: 'var(--border)',
|
|
boxShadow: `
|
|
0 2px 4px rgba(0, 0, 0, 0.1),
|
|
0 4px 8px rgba(0, 0, 0, 0.08),
|
|
0 8px 16px rgba(0, 0, 0, 0.06),
|
|
0 0 0 1px rgba(0, 0, 0, 0.05),
|
|
inset 0 -2px 4px rgba(0, 0, 0, 0.1)
|
|
`,
|
|
}}
|
|
>
|
|
{BadgeContent}
|
|
</div>
|
|
);
|
|
}
|
|
|
|
// Variant classes for simple badges
|
|
const variantClasses: Record<string, string> = {
|
|
default: 'bg-primary border-transparent text-primary-foreground',
|
|
outline: 'bg-transparent border-border text-foreground',
|
|
secondary: 'bg-secondary border-transparent text-secondary-foreground',
|
|
destructive: 'bg-destructive border-transparent text-destructive-foreground',
|
|
success: 'bg-success border-success/30 text-success-foreground',
|
|
// Sector variants
|
|
construction: 'bg-sector-construction/10 border-sector-construction/20 text-sector-construction',
|
|
production: 'bg-sector-production/10 border-sector-production/20 text-sector-production',
|
|
recreation: 'bg-sector-recreation/10 border-sector-recreation/20 text-sector-recreation',
|
|
logistics: 'bg-sector-logistics/10 border-sector-logistics/20 text-sector-logistics',
|
|
};
|
|
|
|
// Heritage status variants need inline styles for proper CSS variable usage
|
|
// Using CSS color-mix for proper theme-aware colors with opacity
|
|
const heritageStyles: Record<string, React.CSSProperties> = {
|
|
protected: {
|
|
backgroundColor: 'color-mix(in srgb, var(--primary) 10%, transparent)',
|
|
borderColor: 'color-mix(in srgb, var(--primary) 40%, transparent)',
|
|
color: 'var(--primary)',
|
|
},
|
|
'cultural-heritage': {
|
|
backgroundColor: 'color-mix(in srgb, var(--accent) 10%, transparent)',
|
|
borderColor: 'color-mix(in srgb, var(--accent) 40%, transparent)',
|
|
color: 'var(--accent)',
|
|
},
|
|
historical: {
|
|
backgroundColor: 'color-mix(in srgb, var(--warning) 10%, transparent)',
|
|
borderColor: 'color-mix(in srgb, var(--warning) 40%, transparent)',
|
|
color: 'var(--warning)',
|
|
},
|
|
};
|
|
|
|
// For heritage variants, apply inline styles directly
|
|
const heritageStyle = isHeritageVariant ? heritageStyles[variant] : undefined;
|
|
|
|
return (
|
|
<span
|
|
className={`${baseClasses} ${!isHeritageVariant ? (variantClasses[variant] || variantClasses.default) : ''} ${className}`}
|
|
style={heritageStyle ? { ...heritageStyle, borderWidth: '1px', borderStyle: 'solid' } : undefined}
|
|
>
|
|
{showDot && (
|
|
<span className={`h-2 w-2 rounded-full shrink-0 ${dotColorClasses[dotColor]}`} />
|
|
)}
|
|
{children}
|
|
</span>
|
|
);
|
|
};
|
|
|
|
export default Badge;
|