feat: highlight overdue orders in kanban and calendar
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -45,13 +45,16 @@ function isSameDay(a, b) {
|
||||
|
||||
function OrderChip({ order, onClick }) {
|
||||
const color = getStatusColor(order.status);
|
||||
const isOverdue = order.scheduled_at &&
|
||||
new Date(order.scheduled_at) < new Date() &&
|
||||
order.status !== 'закрыт';
|
||||
return (
|
||||
<div
|
||||
onClick={(e) => { e.stopPropagation(); onClick(order); }}
|
||||
title={`${order.name} — ${order.status}`}
|
||||
title={isOverdue ? `Просрочено: ${order.name}` : `${order.name} — ${order.status}`}
|
||||
style={{
|
||||
background: color + '1A',
|
||||
color,
|
||||
background: isOverdue ? '#fef2f2' : color + '1A',
|
||||
color: isOverdue ? '#ef4444' : color,
|
||||
fontSize: '0.68rem',
|
||||
fontWeight: 600,
|
||||
padding: '2px 6px',
|
||||
@@ -303,6 +306,9 @@ function DayDetail({ date, orders, onOrderClick, onAdd, onAssign }) {
|
||||
{dayOrders.map((o) => {
|
||||
const color = getStatusColor(o.status);
|
||||
const time = new Date(o.scheduled_at).toLocaleTimeString('ru-RU', { hour: '2-digit', minute: '2-digit' });
|
||||
const isOverdue = o.scheduled_at &&
|
||||
new Date(o.scheduled_at) < new Date() &&
|
||||
o.status !== 'закрыт';
|
||||
return (
|
||||
<div
|
||||
key={o.id}
|
||||
@@ -310,7 +316,8 @@ function DayDetail({ date, orders, onOrderClick, onAdd, onAssign }) {
|
||||
className="glass-panel"
|
||||
style={{
|
||||
padding: '12px 16px',
|
||||
borderLeft: `3px solid ${color}`,
|
||||
borderLeft: `3px solid ${isOverdue ? '#ef4444' : color}`,
|
||||
background: isOverdue ? '#fffafa' : undefined,
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
@@ -344,7 +351,9 @@ function DayDetail({ date, orders, onOrderClick, onAdd, onAssign }) {
|
||||
>
|
||||
{o.status}
|
||||
</span>
|
||||
<span style={{ fontSize: '0.75rem', color: 'var(--text-muted, #8C9097)' }}>{time}</span>
|
||||
<span style={{ fontSize: '0.75rem', color: isOverdue ? '#ef4444' : 'var(--text-muted, #8C9097)', fontWeight: isOverdue ? 700 : undefined }}>
|
||||
{isOverdue ? `⚠ Просрочено` : time}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -15,6 +15,10 @@ const OrderCard = ({ order, onClick }) => {
|
||||
id: order.id,
|
||||
});
|
||||
|
||||
const isOverdue = order.scheduled_at &&
|
||||
new Date(order.scheduled_at) < new Date() &&
|
||||
order.status !== 'закрыт';
|
||||
|
||||
return (
|
||||
<div
|
||||
ref={setNodeRef}
|
||||
@@ -22,8 +26,8 @@ const OrderCard = ({ order, onClick }) => {
|
||||
transform: CSS.Transform.toString(transform),
|
||||
transition,
|
||||
opacity: isDragging ? 0.45 : 1,
|
||||
background: '#fff',
|
||||
border: '1px solid var(--border-light)',
|
||||
background: isOverdue ? '#fffafa' : '#fff',
|
||||
border: isOverdue ? '1.5px solid #fca5a5' : '1px solid var(--border-light)',
|
||||
borderRadius: '10px',
|
||||
padding: '13px',
|
||||
cursor: 'pointer',
|
||||
@@ -43,6 +47,17 @@ const OrderCard = ({ order, onClick }) => {
|
||||
<GripVertical size={15} />
|
||||
</div>
|
||||
<div style={{ flex: 1, minWidth: 0 }}>
|
||||
{isOverdue && (
|
||||
<div style={{
|
||||
display: 'inline-flex', alignItems: 'center', gap: '4px',
|
||||
background: '#fef2f2', color: '#ef4444',
|
||||
fontSize: '0.68rem', fontWeight: 700,
|
||||
padding: '2px 6px', borderRadius: '4px',
|
||||
marginBottom: '4px',
|
||||
}}>
|
||||
⚠ Просрочено
|
||||
</div>
|
||||
)}
|
||||
<p style={{
|
||||
fontWeight: 700, fontFamily: 'var(--font-heading)',
|
||||
fontSize: '0.9rem', marginBottom: '6px',
|
||||
|
||||
Reference in New Issue
Block a user