// ─────────────────────────────────────────────────────────── // Huio Control Panel — Disputes & Reports View (cp-disputes-view.jsx) // ─────────────────────────────────────────────────────────── if (!window.CP_STYLES) throw new Error('[cp-disputes-view] window.CP_STYLES not loaded'); const isPending = status => status === 'pending_review' || status === 'under_investigation' || status === 'pending'; const isResolved = status => status === 'resolved' || status === 'dismissed'; // Static O(1) dictionary for badge CSS classes const STATUS_BADGES = { under_investigation: 'hu-chip hu-chip-teal hu-pulse', resolved: 'hu-chip hu-chip-coral', dismissed: 'hu-chip hu-chip-gray', pending_review: 'hu-chip hu-chip-ochre', pending: 'hu-chip hu-chip-ochre', }; // Safe date formatter to prevent runtime exceptions on malformed ISO timestamps const formatResolvedAt = (isoStr) => { if (!isoStr) return ''; try { const dt = new Date(isoStr); return isNaN(dt.getTime()) ? String(isoStr) : dt.toLocaleString(); } catch { return String(isoStr); } }; function renderDisputes({ lang, t: rawT, appStyles: rawAppStyles, disputes: rawDisputes = [], disputesFilter = 'pending', setDisputesFilter, resolvingReportId = null, handleResolve, setZoomImg, }) { const appStyles = rawAppStyles || window.CP_STYLES || {}; const t = typeof rawT === 'function' ? rawT : (k) => k; const disputes = Array.isArray(rawDisputes) ? rawDisputes : []; // Senior High-Load Optimization: Single-pass zero-allocation aggregation let pendingCount = 0; let resolvedCount = 0; const isPendingFilter = disputesFilter === 'pending'; for (let i = 0; i < disputes.length; i++) { const d = disputes[i]; if (!d) continue; if (isPending(d.status)) pendingCount++; else if (isResolved(d.status)) resolvedCount++; } // Single-pass defensive filter with hoisted loop invariant const filteredDisputes = disputes.filter(d => { if (!d) return false; return isPendingFilter ? isPending(d.status) : isResolved(d.status); }); return (

{t('disputes.title')}

{t('disputes.sub')}

{filteredDisputes.length === 0 ? (

{t('disputes.empty')}

) : (
{filteredDisputes.map((req, idx) => { if (!req) return null; const isProcessing = resolvingReportId === req.id; const rawGroupId = req.group_id; const groupIdStr = rawGroupId != null ? String(rawGroupId) : ''; const groupName = req.hui_groups?.name || (groupIdStr ? `${groupIdStr.slice(0, 8)}...` : null); const statusBadgeClass = STATUS_BADGES[req.status] || 'hu-chip hu-chip-ochre'; const reportTypeKey = req.report_type ? `disputes.type.${req.report_type}` : 'disputes.type.other'; return (

{t(reportTypeKey) || req.report_type || t('disputes.type.other')}

{t(`disputes.status.${req.status}`) || req.status || t('disputes.status.pending_review')}
{t('disputes.reporter')}: {req.reporter?.name || t('common.unknown')} {req.reporter?.phone ? `(${req.reporter.phone})` : ''}
{t('disputes.reported')}: {req.reported?.name || t('common.unknown')} {req.reported?.phone ? `(${req.reported.phone})` : ''}
{groupName && (
{t('disputes.group')}: {groupName}
)} {req.description && (
{t('disputes.description')}: {req.description}
)} {/* Evidence Images */} {Array.isArray(req.evidence_urls) && req.evidence_urls.length > 0 && (
{t('disputes.evidence')}:
{req.evidence_urls.map((url, i) => ( Evidence typeof setZoomImg === 'function' && setZoomImg(url)} /> ))}
)} {/* Resolved Details Box */} {isResolved(req.status) && (
{t('disputes.resolution_info')}: {req.resolution === 'in_favor_reporter' ? t('disputes.status.resolved') : (req.resolution === 'dismissed' ? t('disputes.status.dismissed') : (req.resolution || t('disputes.status.resolved')))}
{req.resolution_note && (
{t('disputes.resolution_note')}: {req.resolution_note}
)} {req.resolved_at && (
{formatResolvedAt(req.resolved_at)}
)}
)} {/* Resolution Actions */} {isPending(req.status) && (
{req.status !== 'under_investigation' && ( )}
)}
); })}
)}
); } window.CpDisputesView = { renderDisputes, };