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 / admin / components / essential-seo / schema / SchemaPreview.js

SchemaPreview.js in ThinkRank AI SEO – AI SEO Plugin for WordPress: Schema, XML Sitemaps, Meta Tags, Search Console & Local SEO 1.0.0, at src/admin/components/essential-seo/schema/SchemaPreview.js

259 lines 13.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /**
2 * Schema Preview Component
3 *
4 * Extracted from SchemaTab.js - handles schema markup preview and rich snippets display
5 *
6 * @package ThinkRank
7 * @since 1.0.0
8 */
9
10 import { __ } from '@wordpress/i18n';
11 import {
12 Card,
13 CardBody,
14 CardHeader,
15 Button,
16 Flex,
17 FlexItem
18 } from '@wordpress/components';
19
20 /**
21 * Schema Preview Component
22 */
23 const SchemaPreview = ({
24 generatedSchemas,
25 schemaPreview,
26 onGeneratePreview
27 }) => {
28 if (!generatedSchemas) {
29 return null;
30 }
31
32 return (
33 <>
34 {/* Generated Schema Results */}
35 <Card size="small" className="thinkrank-mt-lg">
36 <CardHeader>
37 <Flex justify="space-between" align="center">
38 <FlexItem>
39 <h3>{__('Generated Schema Markup', 'thinkrank')}</h3>
40 </FlexItem>
41 <FlexItem>
42 <Button
43 variant="secondary"
44 size="small"
45 onClick={onGeneratePreview}
46 >
47 {__('Generate Preview', 'thinkrank')}
48 </Button>
49 </FlexItem>
50 </Flex>
51 </CardHeader>
52 <CardBody>
53 {generatedSchemas.generated_schemas && Object.keys(generatedSchemas.generated_schemas).length > 0 && (
54 <div className="thinkrank-mb-md">
55 <h4>{__('Schema Types Generated:', 'thinkrank')}</h4>
56 <div className="thinkrank-mb-sm" style={{ display: 'flex', flexWrap: 'wrap', gap: '8px' }}>
57 {Object.keys(generatedSchemas.generated_schemas).map((schemaType) => (
58 <span key={schemaType} style={{
59 padding: '4px 8px',
60 backgroundColor: '#e7f3ff',
61 border: '1px solid #b3d9ff',
62 borderRadius: '4px',
63 fontSize: '12px',
64 fontWeight: '500'
65 }}>
66 {schemaType}
67 </span>
68 ))}
69 </div>
70 </div>
71 )}
72
73 {generatedSchemas.deployment_ready && (
74 <div style={{
75 padding: '12px',
76 backgroundColor: '#d4edda',
77 border: '1px solid #c3e6cb',
78 borderRadius: '4px',
79 marginBottom: '16px'
80 }}>
81 <strong style={{ color: '#155724' }}>
82 {__('✓ Schema is ready for deployment!', 'thinkrank')}
83 </strong>
84 </div>
85 )}
86
87 {generatedSchemas.optimization_recommendations && generatedSchemas.optimization_recommendations.length > 0 && (
88 <div className="thinkrank-mb-md">
89 <h4>{__('Optimization Recommendations:', 'thinkrank')}</h4>
90 <ul>
91 {generatedSchemas.optimization_recommendations.map((rec, index) => (
92 <li key={index}>
93 {typeof rec === 'string' ? rec : rec.message || JSON.stringify(rec)}
94 </li>
95 ))}
96 </ul>
97 </div>
98 )}
99
100 {/* Schema Code Preview */}
101 {generatedSchemas.generated_schemas && (
102 <div>
103 <h4>{__('Schema Code Preview:', 'thinkrank')}</h4>
104 {Object.entries(generatedSchemas.generated_schemas).map(([schemaType, schemaData]) => (
105 <div key={schemaType} className="thinkrank-mb-md">
106 <h5 className="thinkrank-mb-xs" style={{ fontSize: '14px' }}>{schemaType} Schema:</h5>
107 <pre style={{
108 backgroundColor: '#f8f9fa',
109 border: '1px solid #dee2e6',
110 borderRadius: '4px',
111 padding: '12px',
112 fontSize: '12px',
113 overflow: 'auto',
114 overflowWrap: 'break-word',
115 wordWrap: 'break-word',
116 whiteSpace: 'pre-wrap',
117 maxHeight: '200px',
118 maxWidth: '100%'
119 }}>
120 {JSON.stringify(schemaData, null, 2)}
121 </pre>
122 </div>
123 ))}
124 </div>
125 )}
126 </CardBody>
127 </Card>
128
129 {/* Schema Preview */}
130 {schemaPreview && (
131 <Card size="small" className="thinkrank-mt-lg">
132 <CardHeader>
133 <h3>{__('Rich Snippets Preview', 'thinkrank')}</h3>
134 </CardHeader>
135 <CardBody>
136 <p className="thinkrank-mb-md" style={{ color: '#666' }}>
137 {__('Preview of how your content might appear in search results with schema markup:', 'thinkrank')}
138 </p>
139
140 {schemaPreview.rich_snippets && Object.keys(schemaPreview.rich_snippets).length > 0 && (
141 <div>
142 {Object.entries(schemaPreview.rich_snippets).map(([schemaType, preview]) => {
143 // Handle different preview data structures
144 let previewData = preview;
145
146 // If preview is an object with nested structure, extract the actual preview data
147 if (preview && typeof preview === 'object' && !preview.title && !preview.url && !preview.description) {
148 // Look for nested preview data
149 const nestedKeys = Object.keys(preview);
150 if (nestedKeys.length > 0) {
151 previewData = preview[nestedKeys[0]];
152 }
153 }
154
155 // Ensure we have valid preview data
156 if (!previewData || typeof previewData !== 'object') {
157 return (
158 <div key={schemaType} className="thinkrank-mb-lg">
159 <h4 className="thinkrank-mb-sm" style={{ fontSize: '14px' }}>{schemaType} Rich Snippet:</h4>
160 <div style={{
161 padding: '16px',
162 backgroundColor: '#f8f9fa',
163 border: '1px solid #dee2e6',
164 borderRadius: '4px',
165 textAlign: 'center',
166 color: '#666'
167 }}>
168 {__('Preview data not available for this schema type.', 'thinkrank')}
169 </div>
170 </div>
171 );
172 }
173
174 return (
175 <div key={schemaType} className="thinkrank-mb-lg">
176 <h4 className="thinkrank-mb-sm" style={{ fontSize: '14px' }}>{schemaType} Rich Snippet:</h4>
177 <div style={{
178 padding: '16px',
179 backgroundColor: '#f8f9fa',
180 border: '1px solid #dee2e6',
181 borderRadius: '4px',
182 fontFamily: 'Arial, sans-serif'
183 }}>
184 {previewData.title && (
185 <div style={{
186 color: '#1a0dab',
187 fontSize: '18px',
188 fontWeight: 'normal',
189 marginBottom: '4px',
190 textDecoration: 'underline',
191 cursor: 'pointer'
192 }}>
193 {typeof previewData.title === 'string' ? previewData.title : JSON.stringify(previewData.title)}
194 </div>
195 )}
196 {previewData.url && (
197 <div style={{
198 color: '#006621',
199 fontSize: '14px',
200 marginBottom: '4px'
201 }}>
202 {typeof previewData.url === 'string' ? previewData.url : JSON.stringify(previewData.url)}
203 </div>
204 )}
205 {previewData.description && (
206 <div style={{
207 color: '#545454',
208 fontSize: '13px',
209 lineHeight: '1.4'
210 }}>
211 {typeof previewData.description === 'string' ? previewData.description : JSON.stringify(previewData.description)}
212 </div>
213 )}
214 {previewData.additional_info && (
215 <div style={{
216 marginTop: '8px',
217 fontSize: '12px',
218 color: '#666'
219 }}>
220 {typeof previewData.additional_info === 'object' ? (
221 Object.entries(previewData.additional_info).map(([key, value]) => (
222 <div key={key}>
223 <strong>{key}:</strong> {typeof value === 'string' ? value : JSON.stringify(value)}
224 </div>
225 ))
226 ) : (
227 <div>{typeof previewData.additional_info === 'string' ? previewData.additional_info : JSON.stringify(previewData.additional_info)}</div>
228 )}
229 </div>
230 )}
231 </div>
232 </div>
233 );
234 })}
235 </div>
236 )}
237
238 {(!schemaPreview.rich_snippets || Object.keys(schemaPreview.rich_snippets).length === 0) && (
239 <div style={{
240 padding: '20px',
241 textAlign: 'center',
242 backgroundColor: '#f8f9fa',
243 border: '1px solid #dee2e6',
244 borderRadius: '4px'
245 }}>
246 <p style={{ margin: 0, color: '#666' }}>
247 {__('No rich snippets preview available. Generate schema markup first.', 'thinkrank')}
248 </p>
249 </div>
250 )}
251 </CardBody>
252 </Card>
253 )}
254 </>
255 );
256 };
257
258 export default SchemaPreview;
259