PluginProbe
ThinkRank AI SEO – AI SEO Plugin for WordPress: Schema, XML Sitemaps, Meta Tags, Search Console & Local SEO / 1.0.0
ThinkRank AI SEO – AI SEO Plugin for WordPress: Schema, XML Sitemaps, Meta Tags, Search Console & Local SEO v1.0.0
2.7.0 2.6.0 2.5.0 2.4.0 2.3.0 2.2.0 2.1.1 2.1.0 2.0.2 2.0.1 2.0.0 1.32.0 1.31.0 1.30.0 1.29.0 1.28.0 1.27.0 1.26.0 1.25.0 trunk 1.0.0 1.0.1 1.0.2 1.1.0 1.10.0 All 48 releases
thinkrank / src / metabox / components / AnalysisResults.js

AnalysisResults.js in ThinkRank AI SEO – AI SEO Plugin for WordPress: Schema, XML Sitemaps, Meta Tags, Search Console & Local SEO 1.0.0, at src/metabox/components/AnalysisResults.js

211 lines 9.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /**
2 * Analysis Results Component
3 *
4 * Displays SEO analysis results including score breakdown and suggestions
5 *
6 * @package ThinkRank
7 * @since 1.0.0
8 */
9
10 import { __ } from '@wordpress/i18n';
11
12 /**
13 * Analysis Results Component
14 */
15 const AnalysisResults = ({ analysisData, showScoreBreakdown }) => {
16 if (!analysisData) {
17 return null;
18 }
19
20 /**
21 * Get score class based on score value
22 */
23 const getScoreClass = (score) => {
24 if (score >= 80) return 'score-high';
25 if (score >= 60) return 'score-medium';
26 return 'score-low';
27 };
28
29 /**
30 * Get grade from score
31 */
32 const getGrade = (score) => {
33 if (score >= 90) return 'A';
34 if (score >= 80) return 'B';
35 if (score >= 70) return 'C';
36 if (score >= 60) return 'D';
37 return 'F';
38 };
39
40 /**
41 * Render score factor item
42 */
43 const renderScoreFactor = (factorKey, factorData) => {
44 const percentage = factorData.percentage || 0;
45 const score = factorData.score || 0;
46 const maxScore = factorData.max_score || 0;
47 const fillWidth = maxScore > 0 ? (score / maxScore) * 100 : 0;
48
49 const factorLabels = {
50 'satisfying_content': __('Satisfying Content', 'thinkrank'),
51 'title_optimization': __('Title Optimization', 'thinkrank'),
52 'niche_expertise': __('Niche Expertise', 'thinkrank'),
53 'searcher_engagement': __('Searcher Engagement', 'thinkrank'),
54 'backlink_authority': __('Backlink Authority', 'thinkrank'),
55 'content_freshness': __('Content Freshness', 'thinkrank'),
56 'mobile_experience': __('Mobile Experience', 'thinkrank'),
57 'trustworthiness': __('Trustworthiness', 'thinkrank'),
58 'link_diversity': __('Link Diversity', 'thinkrank'),
59 'core_web_vitals': __('Core Web Vitals', 'thinkrank'),
60 'site_security': __('Site Security', 'thinkrank'),
61 'internal_linking': __('Internal Linking', 'thinkrank'),
62 'technical_factors': __('Technical Factors', 'thinkrank')
63 };
64
65 const factorIcons = {
66 'satisfying_content': '🎯',
67 'title_optimization': '📝',
68 'niche_expertise': '🧠',
69 'searcher_engagement': '👥',
70 'backlink_authority': '🔗',
71 'content_freshness': '🔄',
72 'mobile_experience': '📱',
73 'trustworthiness': '🛡️',
74 'link_diversity': '🌐',
75 'core_web_vitals': '',
76 'site_security': '🔒',
77 'internal_linking': '🔗',
78 'technical_factors': '⚙️'
79 };
80
81 return (
82 <div key={factorKey} id={`score-${factorKey.replace('_', '-')}`} className="score-factor-item">
83 <div className="factor-header">
84 <span className="factor-icon">{factorIcons[factorKey] || '📊'}</span>
85 <span className="factor-label">{factorLabels[factorKey] || factorKey}</span>
86 <div className="factor-score">
87 <span className="score-value">{score}/{maxScore}</span>
88 <div className="score-bar">
89 <div className="score-bar-fill" style={{ width: `${fillWidth}%` }}></div>
90 </div>
91 </div>
92 </div>
93 </div>
94 );
95 };
96
97 return (
98 <div className="thinkrank-analysis-results" id="thinkrank-analysis-results">
99 {/* SEO Score Section */}
100 <div className="analysis-section score-section">
101 <div className={`score-circle ${getScoreClass(analysisData.overall_score || 0)}`}>
102 <span className="score-number" id="analysis-score">{analysisData.overall_score || 0}</span>
103 <span className="score-grade" id="seo-grade">{getGrade(analysisData.overall_score || 0)}</span>
104 <span className="score-label">{__('SEO Score', 'thinkrank')}</span>
105 </div>
106 <div className="score-breakdown">
107 <div className="score-item">
108 <span className="score-label">{__('Content Quality', 'thinkrank')}</span>
109 <span className="score-value" id="content-quality">
110 {analysisData.content_quality || '-'}
111 </span>
112 </div>
113 <div className="score-item">
114 <span className="score-label">{__('Keyword Optimization', 'thinkrank')}</span>
115 <span className="score-value" id="keyword-optimization">
116 {analysisData.keyword_optimization || '-'}
117 </span>
118 </div>
119 <div className="score-item">
120 <span className="score-label">{__('Readability', 'thinkrank')}</span>
121 <span className="score-value" id="readability-score">
122 {analysisData.readability_score || '-'}
123 </span>
124 </div>
125 </div>
126 </div>
127
128 {/* Comprehensive Score Breakdown Section */}
129 {showScoreBreakdown && analysisData.score_breakdown && (
130 <div id="seo-score-breakdown" className="analysis-section comprehensive-score-section">
131 <h5>{__('2025 SEO Analysis (Google Q1 Algorithm)', 'thinkrank')}</h5>
132 {Object.entries(analysisData.score_breakdown).map(([factorKey, factorData]) =>
133 renderScoreFactor(factorKey, factorData)
134 )}
135 </div>
136 )}
137
138 {/* Content Analysis Section */}
139 <div className="analysis-section content-analysis">
140 <h4>{__('Content Analysis', 'thinkrank')}</h4>
141 <div className="analysis-grid">
142 <div className="analysis-item">
143 <span className="analysis-label">{__('Word Count', 'thinkrank')}</span>
144 <span className="analysis-value" id="word-count">
145 {analysisData.word_count || '-'}
146 </span>
147 </div>
148 <div className="analysis-item">
149 <span className="analysis-label">{__('Structure', 'thinkrank')}</span>
150 <span className="analysis-value" id="content-structure">
151 {analysisData.content_structure || '-'}
152 </span>
153 </div>
154 <div className="analysis-item">
155 <span className="analysis-label">{__('Keyword Density', 'thinkrank')}</span>
156 <span className="analysis-value" id="keyword-density">
157 {analysisData.keyword_density || '-'}
158 </span>
159 </div>
160 </div>
161 </div>
162
163 {/* Suggestions Section */}
164 {analysisData.suggestions && analysisData.suggestions.length > 0 && (
165 <div className="analysis-section suggestions-section">
166 <h4>{__('Improvement Suggestions', 'thinkrank')}</h4>
167 <ul className="suggestions-list" id="improvement-suggestions">
168 {analysisData.suggestions.map((suggestion, index) => (
169 <li key={index}>
170 {typeof suggestion === 'string' ? suggestion : suggestion.text || suggestion.message || JSON.stringify(suggestion)}
171 </li>
172 ))}
173 </ul>
174 </div>
175 )}
176
177 {/* Strengths & Weaknesses */}
178 {(analysisData.strengths || analysisData.weaknesses) && (
179 <div className="analysis-section strengths-weaknesses">
180 {analysisData.strengths && analysisData.strengths.length > 0 && (
181 <div className="strengths-column">
182 <h5>{__('Strengths', 'thinkrank')}</h5>
183 <ul className="strengths-list" id="content-strengths">
184 {analysisData.strengths.map((strength, index) => (
185 <li key={index}>
186 {typeof strength === 'string' ? strength : strength.text || strength.message || JSON.stringify(strength)}
187 </li>
188 ))}
189 </ul>
190 </div>
191 )}
192 {analysisData.weaknesses && analysisData.weaknesses.length > 0 && (
193 <div className="weaknesses-column">
194 <h5>{__('Areas for Improvement', 'thinkrank')}</h5>
195 <ul className="weaknesses-list" id="content-weaknesses">
196 {analysisData.weaknesses.map((weakness, index) => (
197 <li key={index}>
198 {typeof weakness === 'string' ? weakness : weakness.text || weakness.message || JSON.stringify(weakness)}
199 </li>
200 ))}
201 </ul>
202 </div>
203 )}
204 </div>
205 )}
206 </div>
207 );
208 };
209
210 export default AnalysisResults;
211