From 5ea92e25aff29c4d1978b4d10f5b862a98d3745f Mon Sep 17 00:00:00 2001 From: Kelly Date: Sat, 13 Dec 2025 16:31:06 -0700 Subject: [PATCH] fix(dashboard): Restore preflight display with gold shield + geo MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Show gold shield icon with city/state for qualified workers - Restore IP address, fingerprint, and antidetect status rows - Keep geo session fields in worker interface 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- cannaiq/src/pages/WorkersDashboard.tsx | 82 ++++++++++++++++++-------- 1 file changed, 56 insertions(+), 26 deletions(-) diff --git a/cannaiq/src/pages/WorkersDashboard.tsx b/cannaiq/src/pages/WorkersDashboard.tsx index 9d100147..f198c5d8 100644 --- a/cannaiq/src/pages/WorkersDashboard.tsx +++ b/cannaiq/src/pages/WorkersDashboard.tsx @@ -334,67 +334,97 @@ function ResourceBadge({ worker }: { worker: Worker }) { ); } -// Preflight Summary - shows qualification status with geo region +// Preflight Summary - shows IP, fingerprint, antidetect status, and qualification function PreflightSummary({ worker }: { worker: Worker }) { const httpStatus = worker.preflight_http_status || 'pending'; const isQualified = worker.is_qualified || httpStatus === 'passed'; const httpIp = worker.http_ip; + const fingerprint = worker.fingerprint_data; const httpError = worker.preflight_http_error; + const httpMs = worker.preflight_http_ms; const geoState = worker.current_state; const geoCity = worker.current_city; - // Build tooltip + // Build detailed tooltip const tooltipLines: string[] = []; tooltipLines.push(`HTTP Preflight: ${httpStatus.toUpperCase()}`); if (httpIp) tooltipLines.push(`IP: ${httpIp}`); + if (httpMs) tooltipLines.push(`Response: ${httpMs}ms`); + if (fingerprint?.browser) tooltipLines.push(`Browser: ${fingerprint.browser}`); + if (fingerprint?.timezone) tooltipLines.push(`Timezone: ${fingerprint.timezone}`); + if (fingerprint?.productsReturned !== undefined) tooltipLines.push(`Products returned: ${fingerprint.productsReturned}`); + if (fingerprint?.botDetection) { + const bd = fingerprint.botDetection; + tooltipLines.push(`Bot detection - webdriver: ${bd.webdriver ? 'detected' : 'hidden'}`); + } if (geoState) tooltipLines.push(`Geo: ${geoCity ? `${geoCity}, ` : ''}${geoState}`); if (worker.session_task_count !== undefined) { tooltipLines.push(`Session: ${worker.session_task_count}/${worker.session_max_tasks || 7} tasks`); } if (httpError) tooltipLines.push(`Error: ${httpError}`); - // Qualified - show icon + geo + // Qualification styling - gold shield + geo for qualified if (isQualified) { return ( -
-
- +
+ {/* Gold shield + city/state */} +
+ + + {geoCity && geoState ? `${geoCity}, ${geoState}` : + geoState ? geoState : + 'No geo assigned'} +
- {geoState ? ( -
- - - {geoCity ? `${geoCity}, ` : ''}{geoState} - + {/* IP address */} + {httpIp && ( +
+ + {httpIp}
- ) : ( - No geo assigned )} + {/* Fingerprint summary */} + {fingerprint?.browser && ( +
+ + {fingerprint.browser} +
+ )} + {/* Antidetect status */} +
+ + Antidetect OK + {httpMs && ({httpMs}ms)} +
); } - // Failed + // Not qualified - show failure state if (httpStatus === 'failed') { return ( -
-
- +
+
+ + NOT QUALIFIED +
+
+ {httpError || 'Preflight failed'}
- - {httpError || 'Failed'} -
); } - // Pending + // Pending state return ( -
-
- +
+
+ + QUALIFYING... +
+
+ Running preflight check
- Qualifying...
); }