// CallbackTab.jsx — Callback Request Management UI // Exported as window.CallbackTab (function () { const { useState, useEffect, useCallback, useRef } = React; const STATUS_LABELS = { pending: 'Bekleyen', calling: 'Arıyor', done: 'Tamamlandı', failed: 'Başarısız', cancelled: 'İptal', }; const STATUS_COLORS = { pending: { bg: '#92400e20', border: '#f59e0b', text: '#fbbf24' }, calling: { bg: '#1e3a8a20', border: '#3b82f6', text: '#60a5fa' }, done: { bg: '#064e3b20', border: '#10b981', text: '#34d399' }, failed: { bg: '#7f1d1d20', border: '#ef4444', text: '#f87171' }, cancelled: { bg: '#1f2937', border: '#6b7280', text: '#9ca3af' }, }; const FILTER_TABS = [ { key: 'all', label: 'Tümü' }, { key: 'pending', label: 'Bekleyen' }, { key: 'calling', label: 'Arıyor' }, { key: 'done', label: 'Tamamlandı' }, { key: 'failed', label: 'Başarısız' }, { key: 'cancelled', label: 'İptal' }, ]; function StatusBadge({ status }) { const s = STATUS_COLORS[status] || STATUS_COLORS.cancelled; return ( {STATUS_LABELS[status] || status} ); } function formatTR(iso) { if (!iso) return '--'; // Backend naive UTC döndürebilir → parseUTC ile yerel saate çevir. return fmtDateTime(iso, { day: '2-digit', month: '2-digit', year: 'numeric', hour: '2-digit', minute: '2-digit', }); } // ── Stat card ─────────────────────────────────────────────────────────────── function StatCard({ label, value, color }) { return (
{value ?? '—'}
{label}
); } // ── New / Edit modal ───────────────────────────────────────────────────────── function CallbackModal({ mode, initial, queues, onClose, onSaved, toast }) { const isEdit = mode === 'edit'; const [form, setForm] = useState( isEdit ? { notes: initial.notes || '', scheduled_at: initial.scheduled_at ? initial.scheduled_at.slice(0, 16) : '', status: initial.status || 'pending', } : { phone: '', caller_name: '', queue_id: '', scheduled_at: '', notes: '', } ); const [saving, setSaving] = useState(false); const set = (key, val) =>setForm(f => ({ ...f, [key]: val })); const handleSubmit = async (e) => { e.preventDefault(); setSaving(true); try { let res; if (isEdit) { res = await authFetch(`/api/callbacks/${initial.id}/status`, { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ status: form.status, notes: form.notes, scheduled_at: form.scheduled_at || null, }), }); } else { const q = queues.find(q =>String(q.id) === String(form.queue_id)); res = await authFetch('/api/callbacks', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ phone: form.phone, caller_name: form.caller_name, queue_id: form.queue_id || null, queue_name: q ? q.name : '', scheduled_at: form.scheduled_at || null, notes: form.notes, }), }); } if (!res.ok) throw new Error('İstek başarısız'); toast(isEdit ? 'Callback güncellendi' : 'Callback oluşturuldu', 'success'); onSaved(); } catch (err) { toast(err.message || 'Hata oluştu', 'error'); } finally { setSaving(false); } }; const inputStyle = { width: '100%', padding: '8px 12px', borderRadius: 8, border: '1px solid var(--border)', background: 'var(--bg-card)', color: 'inherit', fontSize: 14, boxSizing: 'border-box', }; return (
e.target === e.currentTarget && onClose()}>

{isEdit ? ' Callback Düzenle' : ' Yeni Callback'}

{!isEdit && ( <>
set('phone', e.target.value)} />
set('caller_name', e.target.value)} />
)} {isEdit && (
)}
set('scheduled_at', e.target.value)} />