Spaces:
Sleeping
Sleeping
| import React from 'react'; | |
| const PRIORITY_CONFIG = { | |
| 5: { color: '#ef4444', bg: 'rgba(239,68,68,0.12)', label: 'CRITICAL', textColor: '#fca5a5' }, | |
| 4: { color: '#f59e0b', bg: 'rgba(245,158,11,0.12)', label: 'HIGH', textColor: '#fcd34d' }, | |
| 3: { color: '#eab308', bg: 'rgba(234,179,8,0.10)', label: 'MEDIUM', textColor: '#fde047' }, | |
| 2: { color: '#22c55e', bg: 'rgba(34,197,94,0.10)', label: 'LOW', textColor: '#86efac' }, | |
| 1: { color: '#94a3b8', bg: 'rgba(148,163,184,0.08)', label: 'MINIMAL', textColor: '#cbd5e1' }, | |
| }; | |
| const ACTION_ICONS = { | |
| reply: '↩', | |
| schedule: '📅', | |
| delegate: '→', | |
| ignore: '✕', | |
| }; | |
| function UrgencyRing({ urgency, priority }) { | |
| const pct = Math.max(0, Math.min(1, urgency)); | |
| const size = 36; | |
| const stroke = 3; | |
| const r = (size - stroke * 2) / 2; | |
| const circ = 2 * Math.PI * r; | |
| const dash = circ * pct; | |
| const color = PRIORITY_CONFIG[priority]?.color || '#94a3b8'; | |
| return ( | |
| <div className="urgency-ring-wrapper" title={`Urgency: ${(urgency * 100).toFixed(0)}%`}> | |
| <svg width={size} height={size} style={{ transform: 'rotate(-90deg)' }}> | |
| <circle cx={size / 2} cy={size / 2} r={r} fill="none" stroke="rgba(255,255,255,0.08)" strokeWidth={stroke} /> | |
| <circle | |
| cx={size / 2} cy={size / 2} r={r} | |
| fill="none" | |
| stroke={color} | |
| strokeWidth={stroke} | |
| strokeDasharray={`${dash} ${circ}`} | |
| strokeLinecap="round" | |
| style={{ transition: 'stroke-dasharray 0.6s ease, stroke 0.3s' }} | |
| opacity={0.3 + pct * 0.7} | |
| /> | |
| </svg> | |
| <span className="urgency-pct" style={{ color }}>{(urgency * 100).toFixed(0)}</span> | |
| </div> | |
| ); | |
| } | |
| export default function InboxPanel({ emails, selectedEmailId, onSelect, isAutoRunning }) { | |
| const sorted = [...emails].sort((a, b) => { | |
| if (a.handled !== b.handled) return a.handled ? 1 : -1; | |
| if (b.priority !== a.priority) return b.priority - a.priority; | |
| return b.urgency - a.urgency; | |
| }); | |
| return ( | |
| <div className="panel inbox-panel"> | |
| <div className="panel-header"> | |
| <span className="panel-title">📥 Inbox</span> | |
| <span className="panel-badge">{emails.filter(e => !e.handled).length} unhandled</span> | |
| </div> | |
| <div className="email-list"> | |
| {sorted.map(email => { | |
| const cfg = PRIORITY_CONFIG[email.priority] || PRIORITY_CONFIG[1]; | |
| const isSelected = email.id === selectedEmailId; | |
| const isHandled = email.handled; | |
| const isAiFocus = isSelected && isAutoRunning; | |
| return ( | |
| <div | |
| key={email.id} | |
| className={`email-card ${isSelected ? 'selected' : ''} ${isHandled ? 'handled' : ''} ${isAiFocus ? 'ai-focus' : ''}`} | |
| style={{ | |
| borderLeft: `3px solid ${isHandled ? 'rgba(148,163,184,0.3)' : cfg.color}`, | |
| background: isSelected ? `${cfg.bg}` : isHandled ? 'rgba(15,23,42,0.4)' : cfg.bg, | |
| cursor: isHandled || isAutoRunning ? 'default' : 'pointer', | |
| }} | |
| onClick={() => !isHandled && !isAutoRunning && onSelect && onSelect(email)} | |
| > | |
| <div className="email-header"> | |
| <div className="email-meta"> | |
| <span | |
| className="priority-badge" | |
| style={{ background: isHandled ? 'rgba(148,163,184,0.15)' : cfg.color, color: isHandled ? '#64748b' : '#fff' }} | |
| > | |
| P{email.priority} {cfg.label} | |
| </span> | |
| {isHandled && ( | |
| <span className="action-taken-badge"> | |
| {ACTION_ICONS[email.action_taken]} {email.action_taken} | |
| </span> | |
| )} | |
| </div> | |
| {!isHandled && <UrgencyRing urgency={email.urgency} priority={email.priority} />} | |
| {isHandled && <span className="handled-check">✓</span>} | |
| </div> | |
| <div className="email-sender" style={{ color: isHandled ? '#475569' : cfg.textColor }}> | |
| {email.sender.split('<')[0].trim()} | |
| </div> | |
| <div className="email-subject" style={{ color: isHandled ? '#475569' : '#f1f5f9' }}> | |
| {email.subject} | |
| </div> | |
| {isSelected && !isHandled && ( | |
| <div className="email-body">{email.body}</div> | |
| )} | |
| </div> | |
| ); | |
| })} | |
| </div> | |
| </div> | |
| ); | |
| } | |