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 / SidebarNavigation.js

SidebarNavigation.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/SidebarNavigation.js

134 lines 4.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /**
2 * Sidebar Navigation Component for Essential SEO
3 *
4 * Left sidebar navigation that replaces nested tabs with a hierarchical structure
5 *
6 * @package ThinkRank
7 * @since 1.0.0
8 */
9
10 import { useState, memo, useCallback } from '@wordpress/element';
11 import { __ } from '@wordpress/i18n';
12 import {
13 Panel,
14 PanelBody,
15 PanelRow,
16 Button
17 } from '@wordpress/components';
18
19 /**
20 * Navigation structure configuration
21 */
22 const navigationStructure = [
23 {
24 id: 'site-identity',
25 title: __('Site Identity', 'thinkrank'),
26 items: [
27 { id: 'basic-info', title: __('Basic Info', 'thinkrank') },
28 { id: 'title-formats', title: __('Title Formats', 'thinkrank') },
29 { id: 'breadcrumbs', title: __('Breadcrumbs', 'thinkrank') },
30 { id: 'hero-section', title: __('Hero & Branding', 'thinkrank') },
31 { id: 'local-seo', title: __('Business Info', 'thinkrank') }
32 ]
33 },
34 {
35 id: 'integrations',
36 title: __('Integrations', 'thinkrank'),
37 items: [
38 { id: 'google-services', title: __('Google Services', 'thinkrank') },
39 { id: 'social-platforms', title: __('Social Platforms', 'thinkrank') }
40 ]
41 },
42 {
43 id: 'analytics',
44 title: __('Analytics', 'thinkrank'),
45 items: [
46 { id: 'setup', title: __('Setup & Integration', 'thinkrank') },
47 { id: 'dashboard', title: __('Dashboard', 'thinkrank') },
48 { id: 'opportunities', title: __('Opportunities', 'thinkrank') },
49 { id: 'insights', title: __('Insights', 'thinkrank') }
50 ]
51 },
52 {
53 id: 'performance',
54 title: __('Performance', 'thinkrank'),
55 items: [
56 { id: 'core-web-vitals', title: __('Core Web Vitals', 'thinkrank') },
57 { id: 'seo-performance', title: __('Opportunities', 'thinkrank') },
58 { id: 'monitoring', title: __('Historical Data', 'thinkrank') },
59 { id: 'recommendations', title: __('Diagnostics', 'thinkrank') }
60 ]
61 },
62
63 {
64 id: 'schema',
65 title: __('Schema Manager', 'thinkrank'),
66 items: [
67 { id: 'schema-settings', title: __('Schema Settings', 'thinkrank') },
68 { id: 'schema-types', title: __('Schema Types', 'thinkrank') },
69 { id: 'organization', title: __('Organization', 'thinkrank') },
70 { id: 'local-business', title: __('LocalBusiness', 'thinkrank') },
71 { id: 'person', title: __('Person', 'thinkrank') },
72 { id: 'website', title: __('Website', 'thinkrank') },
73 { id: 'deployment', title: __('Deployment', 'thinkrank') }
74 ]
75 },
76 {
77 id: 'social-media',
78 title: __('Social Media', 'thinkrank'),
79 items: [
80 { id: 'open-graph', title: __('Open Graph', 'thinkrank') },
81 { id: 'twitter-cards', title: __('Twitter Cards', 'thinkrank') },
82 { id: 'preview', title: __('Preview', 'thinkrank') }
83 ]
84 },
85 {
86 id: 'crawling-ai-indexing',
87 title: __('Crawling & AI Indexing', 'thinkrank'),
88 items: [
89 { id: 'robots-management', title: __('Robots.txt', 'thinkrank') },
90 { id: 'xml-sitemap', title: __('XML Sitemap', 'thinkrank') },
91 { id: 'llms-ai-indexing', title: __('LLMs.txt for AI', 'thinkrank') }
92 ]
93 }
94 ];
95
96 // No need for custom NavigationSection - using WordPress Panel components
97
98 /**
99 * Main Sidebar Navigation Component using WordPress Panel - Optimized with React.memo
100 */
101 const SidebarNavigation = memo(({ activeSection, activeItem, onNavigate }) => {
102 // Memoize the click handler to prevent unnecessary re-renders
103 const handleItemSelect = useCallback((sectionId, itemId) => {
104 onNavigate(sectionId, itemId);
105 }, [onNavigate]);
106
107 return (
108 <Panel>
109 {navigationStructure.map((section) => (
110 <PanelBody
111 key={section.id}
112 title={section.title}
113 initialOpen={activeSection === section.id}
114 >
115 {section.items.map((item) => (
116 <PanelRow key={item.id}>
117 <Button
118 variant={activeSection === section.id && activeItem === item.id ? 'primary' : 'secondary'}
119 onClick={() => handleItemSelect(section.id, item.id)}
120 style={{ width: '100%', justifyContent: 'flex-start' }}
121 >
122 {item.title}
123 </Button>
124 </PanelRow>
125 ))}
126 </PanelBody>
127 ))}
128 </Panel>
129 );
130 });
131
132 export default SidebarNavigation;
133 export { navigationStructure };
134