import React, { useState } from 'react'; import { CornerUpRight, X, Loader, AlertCircle } from 'lucide-react'; const API_BASE = process.env.REACT_APP_API_BASE || 'http://localhost:3001/api'; const WORKFLOW_OPTIONS = [ { key: 'FP', label: 'FP', col: '#F59E0B', rgb: '245,158,11' }, { key: 'Archer', label: 'Archer', col: '#0EA5E9', rgb: '14,165,233' }, { key: 'CARD', label: 'CARD', col: '#10B981', rgb: '16,185,129' }, { key: 'GRANITE', label: 'GRANITE', col: '#A1887F', rgb: '161,136,127' }, ]; export default function RedirectModal({ item, onClose, onRedirect }) { const [workflowType, setWorkflowType] = useState('FP'); const [vendor, setVendor] = useState(''); const [loading, setLoading] = useState(false); const [error, setError] = useState(''); const needsVendor = workflowType === 'FP' || workflowType === 'Archer'; const canSubmit = !loading && (!needsVendor || vendor.trim().length > 0); const handleSubmit = async () => { if (!canSubmit) return; setLoading(true); setError(''); try { const body = { workflow_type: workflowType }; if (needsVendor) body.vendor = vendor.trim(); const res = await fetch(`${API_BASE}/ivanti/todo-queue/${item.id}/redirect`, { method: 'POST', credentials: 'include', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body), }); const data = await res.json(); if (!res.ok) { setError(data.error || 'Redirect failed.'); setLoading(false); return; } onRedirect(data); onClose(); } catch (err) { setError(err.message || 'Network error.'); setLoading(false); } }; return (
e.stopPropagation()} style={{ width: '100%', maxWidth: '460px', background: 'linear-gradient(135deg, rgba(30, 41, 59, 0.98), rgba(51, 65, 85, 0.95))', border: '2px solid rgba(14, 165, 233, 0.4)', borderRadius: '0.75rem', boxShadow: '0 20px 60px rgba(0, 0, 0, 0.7), 0 0 28px rgba(14, 165, 233, 0.12)', display: 'flex', flexDirection: 'column', overflow: 'hidden', }} > {/* Top accent line */}
{/* Header */}
Redirect Queue Item
{/* Body */}
{/* Read-only context */}
Finding Title
{item.finding_title || '—'}
Finding ID
{item.finding_id || '—'}
Current Type
{(() => { const opt = WORKFLOW_OPTIONS.find((o) => o.key === item.workflow_type) || WORKFLOW_OPTIONS[0]; return ( {item.workflow_type} ); })()}
{/* Workflow type selector */}
{WORKFLOW_OPTIONS.map(({ key, label, col, rgb }) => { const active = workflowType === key; return ( ); })}
{/* Vendor input — conditional */} {needsVendor && (
setVendor(e.target.value)} placeholder="e.g. Cisco, Juniper, ADTRAN…" maxLength={200} style={{ width: '100%', boxSizing: 'border-box', background: 'rgba(30, 41, 59, 0.6)', border: '1px solid rgba(14, 165, 233, 0.25)', borderRadius: '0.375rem', padding: '0.5rem 0.75rem', fontFamily: "'JetBrains Mono', monospace", fontSize: '0.8rem', color: '#E2E8F0', outline: 'none', transition: 'border-color 0.2s', }} onFocus={(e) => { e.target.style.borderColor = '#0EA5E9'; }} onBlur={(e) => { e.target.style.borderColor = 'rgba(14, 165, 233, 0.25)'; }} />
)} {/* Error message */} {error && (
{error}
)}
{/* Footer */}
); }