Spaces:
Sleeping
Sleeping
| import React, { useState } from 'react'; | |
| const ACTIONS = [ | |
| { | |
| type: 'reply', | |
| icon: '↩', | |
| label: 'Reply', | |
| desc: 'Personally respond and handle', | |
| color: '#3b82f6', | |
| bg: 'rgba(59,130,246,0.15)', | |
| hoverBg: 'rgba(59,130,246,0.25)', | |
| }, | |
| { | |
| type: 'schedule', | |
| icon: '📅', | |
| label: 'Schedule', | |
| desc: 'Book a meeting slot', | |
| color: '#8b5cf6', | |
| bg: 'rgba(139,92,246,0.15)', | |
| hoverBg: 'rgba(139,92,246,0.25)', | |
| }, | |
| { | |
| type: 'delegate', | |
| icon: '→', | |
| label: 'Delegate', | |
| desc: 'Assign to team member', | |
| color: '#f97316', | |
| bg: 'rgba(249,115,22,0.15)', | |
| hoverBg: 'rgba(249,115,22,0.25)', | |
| }, | |
| { | |
| type: 'ignore', | |
| icon: '✕', | |
| label: 'Ignore', | |
| desc: 'Skip this item', | |
| color: '#64748b', | |
| bg: 'rgba(100,116,139,0.15)', | |
| hoverBg: 'rgba(100,116,139,0.25)', | |
| }, | |
| ]; | |
| export default function ActionPanel({ selectedEmail, onAction, done, loading }) { | |
| const [hoveredAction, setHoveredAction] = useState(null); | |
| const [lastAction, setLastAction] = useState(null); | |
| const handleAction = (actionType) => { | |
| if (!selectedEmail || done || loading) return; | |
| setLastAction(actionType); | |
| onAction({ type: actionType, email_id: selectedEmail.id }); | |
| setTimeout(() => setLastAction(null), 600); | |
| }; | |
| const isDisabled = !selectedEmail || done || loading; | |
| return ( | |
| <div className="panel action-panel"> | |
| <div className="panel-header"> | |
| <span className="panel-title">⚡ Actions</span> | |
| </div> | |
| {selectedEmail ? ( | |
| <div className="selected-email-preview"> | |
| <div className="selected-label">SELECTED</div> | |
| <div className="selected-subject">{selectedEmail.subject}</div> | |
| <div className="selected-sender">{selectedEmail.sender.split('<')[0].trim()}</div> | |
| </div> | |
| ) : ( | |
| <div className="no-selection"> | |
| <span className="no-selection-icon">👆</span> | |
| <span>Select an email<br />from the inbox</span> | |
| </div> | |
| )} | |
| <div className="action-buttons"> | |
| {ACTIONS.map(action => { | |
| const isActive = lastAction === action.type; | |
| const isHovered = hoveredAction === action.type; | |
| return ( | |
| <button | |
| key={action.type} | |
| className={`action-btn ${isActive ? 'active' : ''}`} | |
| style={{ | |
| borderColor: isDisabled ? 'rgba(148,163,184,0.15)' : action.color, | |
| background: isDisabled | |
| ? 'rgba(148,163,184,0.05)' | |
| : isActive | |
| ? action.color | |
| : isHovered | |
| ? action.hoverBg | |
| : action.bg, | |
| color: isDisabled ? '#475569' : isActive ? '#fff' : action.color, | |
| transform: isActive ? 'scale(0.96)' : 'scale(1)', | |
| cursor: isDisabled ? 'not-allowed' : 'pointer', | |
| }} | |
| disabled={isDisabled} | |
| onClick={() => handleAction(action.type)} | |
| onMouseEnter={() => setHoveredAction(action.type)} | |
| onMouseLeave={() => setHoveredAction(null)} | |
| > | |
| <span className="action-btn-icon">{action.icon}</span> | |
| <div className="action-btn-text"> | |
| <span className="action-btn-label">{action.label}</span> | |
| <span className="action-btn-desc">{action.desc}</span> | |
| </div> | |
| </button> | |
| ); | |
| })} | |
| </div> | |
| {done && ( | |
| <div className="done-overlay"> | |
| <span className="done-icon">✓</span> | |
| <span className="done-text">Simulation Complete</span> | |
| </div> | |
| )} | |
| </div> | |
| ); | |
| } | |