Create React Admin Page
Generate a new React page component for the Saman SEO admin interface.
Arguments
- •
$ARGUMENTSshould contain: page name (e.g., "KeywordPlanner") and description
Steps
- •
Analyze the request to determine:
- •Page name (PascalCase for React component)
- •Page purpose and main features
- •Required API endpoints
- •UI components needed
- •
Create the React page at
src-v2/pages/{PageName}.js - •
Follow this template:
jsx
/**
* {PageName} page component.
*
* {Description}
*
* @package Saman SEO
*/
import { useState, useEffect, useCallback } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import apiFetch from '@wordpress/api-fetch';
import Header from '../components/Header';
/**
* {PageName} component.
*
* @return {JSX.Element} The rendered component.
*/
const {PageName} = () => {
// State
const [isLoading, setIsLoading] = useState(true);
const [isSaving, setIsSaving] = useState(false);
const [data, setData] = useState(null);
const [error, setError] = useState(null);
// Fetch data on mount
useEffect(() => {
fetchData();
}, []);
/**
* Fetch data from API.
*/
const fetchData = useCallback(async () => {
setIsLoading(true);
setError(null);
try {
const response = await apiFetch({
path: '/saman-seo/v1/{endpoint}',
});
setData(response);
} catch (err) {
setError(err.message || __('Failed to load data.', 'saman-seo'));
console.error('Error fetching data:', err);
} finally {
setIsLoading(false);
}
}, []);
/**
* Save data to API.
*/
const handleSave = useCallback(async () => {
setIsSaving(true);
setError(null);
try {
await apiFetch({
path: '/saman-seo/v1/{endpoint}',
method: 'POST',
data: data,
});
// Show success notice
} catch (err) {
setError(err.message || __('Failed to save.', 'saman-seo'));
console.error('Error saving:', err);
} finally {
setIsSaving(false);
}
}, [data]);
// Loading state
if (isLoading) {
return (
<div className="samanseo-admin-page">
<Header
title={__('{Page Title}', 'saman-seo')}
description={__('{Page description}', 'saman-seo')}
/>
<div className="samanseo-loading">
<span className="spinner is-active"></span>
{__('Loading...', 'saman-seo')}
</div>
</div>
);
}
// Error state
if (error) {
return (
<div className="samanseo-admin-page">
<Header
title={__('{Page Title}', 'saman-seo')}
description={__('{Page description}', 'saman-seo')}
/>
<div className="notice notice-error">
<p>{error}</p>
</div>
</div>
);
}
return (
<div className="samanseo-admin-page">
<Header
title={__('{Page Title}', 'saman-seo')}
description={__('{Page description}', 'saman-seo')}
/>
<div className="samanseo-content">
{/* Page content here */}
</div>
<div className="samanseo-footer">
<button
type="button"
className="button button-primary"
onClick={handleSave}
disabled={isSaving}
>
{isSaving
? __('Saving...', 'saman-seo')
: __('Save Changes', 'saman-seo')
}
</button>
</div>
</div>
);
};
export default {PageName};
- •Register the page in App.js:
jsx
// Add lazy import at the top
const {PageName} = lazy(() => import('./pages/{PageName}'));
// Add route in the pages array
{ path: '{page-slug}', component: {PageName} },
- •
Add menu item in
includes/class-saman-seo-admin-v2.php:- •Add to
get_menu_items()method - •Add URL routing in
get_page_routes()
- •Add to
- •
Create styles if needed in
src-v2/less/pages/{page-name}.less
Patterns to Follow
- •Imports: Use
@wordpress/element,@wordpress/i18n,@wordpress/api-fetch - •State: Use React hooks (
useState,useEffect,useCallback) - •API: Use
apiFetch()for REST API calls - •i18n: Wrap all strings in
__()or_n()for translation - •Loading: Always handle loading and error states
- •Styling: Use BEM naming with
samanseo-prefix
Common Components Available
- •
Header- Page header with title and description - •
SearchPreview- SERP preview component - •
TemplateInput- Input with template variable support - •
VariablePicker- Template variable selector - •
AiGenerateModal- AI content generation modal
Example Usage
code
/react-page KeywordPlanner Plan and manage target keywords for content