Keyword-research-analysis/src/components/ComprehensiveMetrics.jsx
2025-11-04 17:40:16 +05:30

262 lines
10 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import React, { useState } from 'react'
import './ComprehensiveMetrics.css'
function ComprehensiveMetrics({ metricsData, hookpilotStatus }) {
const [expandedDomain, setExpandedDomain] = useState(null)
if (!metricsData || metricsData.length === 0) {
return null
}
const toggleDomainDetails = (domain) => {
setExpandedDomain(expandedDomain === domain ? null : domain)
}
const getStageColor = (stage) => {
switch (stage) {
case 'NEW': return '#ff6b6b'
case 'GROWING': return '#ffa726'
case 'ESTABLISHED': return '#66bb6a'
case 'ERROR': return '#9e9e9e'
default: return '#9e9e9e'
}
}
const getStageIcon = (stage) => {
switch (stage) {
case 'NEW': return '🌱'
case 'GROWING': return '📈'
case 'ESTABLISHED': return '🏆'
case 'ERROR': return '❌'
default: return '❓'
}
}
const renderTopKeywords = (keywords) => {
if (!keywords || keywords.length === 0) {
return <span className="no-data">No keywords data</span>
}
return (
<div className="keywords-list">
{keywords.slice(0, 5).map((keyword, index) => (
<div key={index} className="keyword-item">
<span className="keyword-phrase">{keyword.phrase}</span>
<span className="keyword-metrics">
SV: {keyword.searchVolume?.toLocaleString() || 'N/A'} |
KD: {keyword.keywordDifficulty || 'N/A'} |
Pos: {keyword.position || 'N/A'}
</span>
</div>
))}
{keywords.length > 5 && (
<div className="more-keywords">+{keywords.length - 5} more keywords</div>
)}
</div>
)
}
const renderTopCategories = (categories) => {
if (!categories || categories.length === 0) {
return <span className="no-data">No categories data</span>
}
return (
<div className="categories-list">
{categories.map((category, index) => (
<div key={index} className="category-item">
<span className="category-url">{category.url}</span>
<span className="category-traffic">{category.traffic?.toLocaleString() || 0} visits</span>
</div>
))}
</div>
)
}
const renderDetailedView = (domainData) => {
if (!domainData || domainData.error) return null
return (
<div className="detailed-view">
<div className="detailed-sections">
<div className="section">
<h4>📊 Complete Metrics</h4>
<div className="metrics-grid">
<div className="metric-item">
<span className="metric-label">Authority Score:</span>
<span className="metric-value">{domainData.authorityScore}</span>
</div>
<div className="metric-item">
<span className="metric-label">Organic Traffic:</span>
<span className="metric-value">{domainData.organicTraffic?.toLocaleString()}</span>
</div>
<div className="metric-item">
<span className="metric-label">Organic Keywords:</span>
<span className="metric-value">{domainData.organicKeywords?.toLocaleString()}</span>
</div>
<div className="metric-item">
<span className="metric-label">Paid Traffic:</span>
<span className="metric-value">{domainData.paidTraffic?.toLocaleString()}</span>
</div>
<div className="metric-item">
<span className="metric-label">Paid Keywords:</span>
<span className="metric-value">{domainData.paidKeywords?.toLocaleString()}</span>
</div>
<div className="metric-item">
<span className="metric-label">Total Backlinks:</span>
<span className="metric-value">{domainData.totalBacklinks?.toLocaleString()}</span>
</div>
</div>
</div>
<div className="section">
<h4>🔍 Top 10 Keywords</h4>
<div className="keywords-detailed">
{domainData.top10Keywords?.map((keyword, index) => (
<div key={index} className="keyword-detailed">
<div className="keyword-main">
<span className="keyword-rank">#{index + 1}</span>
<span className="keyword-text">{keyword.phrase}</span>
</div>
<div className="keyword-stats">
<span>SV: {keyword.searchVolume?.toLocaleString() || 'N/A'}</span>
<span>KD: {keyword.keywordDifficulty || 'N/A'}</span>
<span>Pos: {keyword.position || 'N/A'}</span>
<span>CPC: ${keyword.cpc?.toFixed(2) || 'N/A'}</span>
</div>
</div>
))}
</div>
</div>
<div className="section">
<h4>📄 Top Categories/Pages</h4>
<div className="categories-detailed">
{domainData.topCategories?.map((category, index) => (
<div key={index} className="category-detailed">
<div className="category-url">{category.url}</div>
<div className="category-stats">
<span>Traffic: {category.traffic?.toLocaleString() || 0}</span>
<span>Keywords: {category.positionCount || 1}</span>
</div>
</div>
))}
</div>
</div>
</div>
</div>
)
}
return (
<div className="comprehensive-metrics">
<div className="metrics-header">
<div className="header-content">
<h2>📊 Comprehensive Domain Metrics</h2>
<p>Complete SEO analysis with all required metrics for SEO maturity assessment</p>
</div>
{hookpilotStatus && (
<div className={`hookpilot-status ${hookpilotStatus.success ? 'success' : 'error'}`}>
{hookpilotStatus.success ? '✅ Sent to Hookpilot' : '❌ Hookpilot Error'}
</div>
)}
</div>
<div className="metrics-table-container">
<table className="metrics-table">
<thead>
<tr>
<th>Actions</th>
<th>Domain</th>
<th>Authority Score</th>
<th>Organic Keywords</th>
<th>Top 10 Keywords</th>
<th>Referring Domains</th>
<th>Monthly Traffic</th>
<th>Top Categories</th>
<th>Stage</th>
</tr>
</thead>
<tbody>
{metricsData.map((domainData, index) => (
<React.Fragment key={index}>
<tr className={domainData.error ? 'error-row' : ''}>
<td className="actions-cell">
{!domainData.error && (
<button
className="expand-button"
onClick={() => toggleDomainDetails(domainData.domain)}
title="View detailed metrics"
>
{expandedDomain === domainData.domain ? '▼' : '▶'}
</button>
)}
</td>
<td className="domain-cell">
<strong>{domainData.domain}</strong>
{index === 0 && <span className="client-badge">Client</span>}
</td>
<td className="metric-cell">
{domainData.error ? 'Error' : domainData.authorityScore?.toLocaleString()}
</td>
<td className="metric-cell">
{domainData.error ? 'Error' : domainData.organicKeywords?.toLocaleString()}
</td>
<td className="keywords-cell">
{domainData.error ? 'Error' : renderTopKeywords(domainData.top10Keywords)}
</td>
<td className="metric-cell">
{domainData.error ? 'Error' : domainData.referringDomains?.toLocaleString()}
</td>
<td className="metric-cell">
{domainData.error ? 'Error' : domainData.monthlyTraffic?.toLocaleString()}
</td>
<td className="categories-cell">
{domainData.error ? 'Error' : renderTopCategories(domainData.topCategories)}
</td>
<td className="stage-cell">
<span
className="stage-badge"
style={{ backgroundColor: getStageColor(domainData.stage) }}
>
{getStageIcon(domainData.stage)} {domainData.stage}
</span>
</td>
</tr>
{expandedDomain === domainData.domain && !domainData.error && (
<tr className="expanded-row">
<td colSpan="9">
{renderDetailedView(domainData)}
</td>
</tr>
)}
</React.Fragment>
))}
</tbody>
</table>
</div>
{/* Classification Legend */}
<div className="classification-legend">
<h4>📋 SEO Maturity Classification Criteria</h4>
<div className="legend-items">
<div className="legend-item">
<span className="legend-color" style={{ backgroundColor: '#ff6b6b' }}></span>
<strong>NEW:</strong> AS &lt; 20 OR Organic KW &lt; 500 OR &lt; 10 Ref Domains
</div>
<div className="legend-item">
<span className="legend-color" style={{ backgroundColor: '#ffa726' }}></span>
<strong>GROWING:</strong> AS 2040 OR Organic KW 5003000
</div>
<div className="legend-item">
<span className="legend-color" style={{ backgroundColor: '#66bb6a' }}></span>
<strong>ESTABLISHED:</strong> AS &gt; 40 OR Organic KW &gt; 3000 OR &gt; 100 Ref Domains
</div>
</div>
</div>
</div>
)
}
export default ComprehensiveMetrics