This commit is contained in:
Kirill
2026-05-24 13:59:14 +05:00
parent 2fe426b70a
commit c2c4099fd7
10 changed files with 853 additions and 189 deletions
+138 -14
View File
@@ -1,34 +1,158 @@
import type { ReactElement } from 'react'
import Chip from '@mui/material/Chip'
import { type ReactNode, useState } from 'react'
import Box from '@mui/material/Box'
import Tooltip from '@mui/material/Tooltip'
import { Banknote, CheckCircle, Package, PackageCheck, PackageSearch, Store, XCircle } from 'lucide-react'
import Typography from '@mui/material/Typography'
import { getOrderStatusData, type StatusIconName } from '@/shared/lib/order-status-data'
const iconMap: Record<StatusIconName, ReactElement> = {
banknote: <Banknote size={18} />,
'check-circle': <CheckCircle size={18} />,
'package-search': <PackageSearch size={18} />,
package: <Package size={18} />,
'package-check': <PackageCheck size={18} />,
store: <Store size={18} />,
'x-circle': <XCircle size={18} />,
const iconMap: Record<StatusIconName, ReactNode> = {
banknote: (
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
<rect x="2" y="6" width="20" height="12" rx="2" />
<circle cx="12" cy="12" r="3" />
<path d="M6 12h.01M18 12h.01" />
</svg>
),
'check-circle': (
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
<path d="M22 11.08V12a10 10 0 1 1-5.93-9.14" />
<polyline points="22 4 12 14.01 9 11.01" />
</svg>
),
'package-search': (
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
<path d="M16 16a4 4 0 1 0 0-8 4 4 0 0 0 0 8z" />
<path d="M19 19l-3-3" />
<path d="M21 10V7a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 7v3" />
<path d="M3 10l9 5 9-5" />
</svg>
),
package: (
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
<path d="M16.5 9.4l-9-5.19M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z" />
<polyline points="3.27 6.96 12 12.01 20.73 6.96" />
<line x1="12" y1="22.08" x2="12" y2="12" />
</svg>
),
'package-check': (
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
<path d="M16.5 9.4l-9-5.19M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z" />
<polyline points="3.27 6.96 12 12.01 20.73 6.96" />
<line x1="12" y1="22.08" x2="12" y2="12" />
<polyline points="9 13 11 15 15 11" />
</svg>
),
store: (
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
<path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z" />
<polyline points="9 22 9 12 15 12 15 22" />
</svg>
),
'x-circle': (
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
<circle cx="12" cy="12" r="10" />
<path d="M15 9l-6 6M9 9l6 6" />
</svg>
),
}
const colorMap: Record<string, { bg: string; border: string; text: string; dot: string }> = {
warning: {
bg: 'rgba(245, 124, 0, 0.06)',
border: 'rgba(245, 124, 0, 0.25)',
text: '#c27a00',
dot: '#F57C00',
},
success: {
bg: 'rgba(46, 139, 87, 0.06)',
border: 'rgba(46, 139, 87, 0.25)',
text: '#1e6e42',
dot: '#2E8B57',
},
info: {
bg: 'rgba(84, 110, 122, 0.06)',
border: 'rgba(84, 110, 122, 0.25)',
text: '#3d5a68',
dot: '#546E7A',
},
error: {
bg: 'rgba(211, 47, 47, 0.06)',
border: 'rgba(211, 47, 47, 0.25)',
text: '#a83232',
dot: '#D32F2F',
},
}
interface OrderStatusChipProps {
status: string
tooltipOverride?: string
size?: 'sm' | 'md'
}
export function OrderStatusChip({ status, tooltipOverride }: OrderStatusChipProps) {
export function OrderStatusChip({ status, tooltipOverride, size = 'md' }: OrderStatusChipProps) {
const data = getOrderStatusData(status)
const label = data?.label ?? status
const color = data?.color ?? 'default'
const colorKey = data?.color ?? 'default'
const icon = data ? iconMap[data.iconName] : undefined
const tooltip = tooltipOverride ?? data?.description ?? ''
const colors = colorMap[colorKey] ?? colorMap.info
const [hovered, setHovered] = useState(false)
const padding = size === 'sm' ? '3px 10px' : '5px 14px'
const fontSize = size === 'sm' ? '0.7rem' : '0.75rem'
const iconSize = size === 'sm' ? 14 : 16
return (
<Tooltip title={tooltip} arrow placement="top">
<Chip icon={icon} label={label} color={color as 'default'} size="small" variant="outlined" />
<Box
onMouseEnter={() => setHovered(true)}
onMouseLeave={() => setHovered(false)}
sx={{
display: 'inline-flex',
alignItems: 'center',
gap: '6px',
padding: padding,
borderRadius: '999px',
border: `1px solid ${colors.border}`,
backgroundColor: hovered ? colors.bg : 'transparent',
transition: 'all 0.2s cubic-bezier(0.16, 1, 0.3, 1)',
cursor: 'default',
'&:active': {
transform: 'scale(0.97)',
},
}}
>
<Box
sx={{
width: '6px',
height: '6px',
borderRadius: '50%',
backgroundColor: colors.dot,
flexShrink: 0,
}}
/>
<Box
sx={{
color: colors.text,
display: 'flex',
alignItems: 'center',
width: iconSize,
height: iconSize,
}}
>
{icon}
</Box>
<Typography
sx={{
fontSize,
fontWeight: 600,
color: colors.text,
lineHeight: 1.2,
letterSpacing: '-0.01em',
}}
>
{label}
</Typography>
</Box>
</Tooltip>
)
}