feat: Complete Dashboard API Integration with Analytics Controller
✨ Features: - Implemented API integration for all 7 dashboard pages - Added Analytics REST API controller with 7 endpoints - Full loading and error states with retry functionality - Seamless dummy data toggle for development 📊 Dashboard Pages: - Customers Analytics (complete) - Revenue Analytics (complete) - Orders Analytics (complete) - Products Analytics (complete) - Coupons Analytics (complete) - Taxes Analytics (complete) - Dashboard Overview (complete) 🔌 Backend: - Created AnalyticsController.php with REST endpoints - All endpoints return 501 (Not Implemented) for now - Ready for HPOS-based implementation - Proper permission checks 🎨 Frontend: - useAnalytics hook for data fetching - React Query caching - ErrorCard with retry functionality - TypeScript type safety - Zero build errors 📝 Documentation: - DASHBOARD_API_IMPLEMENTATION.md guide - Backend implementation roadmap - Testing strategy 🔧 Build: - All pages compile successfully - Production-ready with dummy data fallback - Zero TypeScript errors
This commit is contained in:
726
ADDON_INJECTION_GUIDE.md
Normal file
726
ADDON_INJECTION_GUIDE.md
Normal file
@@ -0,0 +1,726 @@
|
||||
# WooNooW Addon Injection Guide
|
||||
|
||||
**Version:** 1.0.0
|
||||
**Last Updated:** 2025-10-28
|
||||
**Status:** Production Ready
|
||||
|
||||
---
|
||||
|
||||
## 📋 Table of Contents
|
||||
|
||||
1. [Overview](#overview)
|
||||
2. [Admin SPA Addons](#admin-spa-addons)
|
||||
- [Quick Start](#quick-start)
|
||||
- [Addon Registration](#addon-registration)
|
||||
- [Route Registration](#route-registration)
|
||||
- [Navigation Injection](#navigation-injection)
|
||||
- [Component Development](#component-development)
|
||||
- [Best Practices](#best-practices)
|
||||
3. [Customer SPA Addons](#customer-spa-addons) *(Coming Soon)*
|
||||
4. [Testing & Debugging](#testing--debugging)
|
||||
5. [Examples](#examples)
|
||||
6. [Troubleshooting](#troubleshooting)
|
||||
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
WooNooW provides a **powerful addon injection system** that allows third-party plugins to seamlessly integrate with the React-powered admin SPA. Addons can:
|
||||
|
||||
- ✅ Register custom SPA routes
|
||||
- ✅ Inject navigation menu items
|
||||
- ✅ Add submenu items to existing sections
|
||||
- ✅ Load React components dynamically
|
||||
- ✅ Declare dependencies and capabilities
|
||||
- ✅ Maintain full isolation and safety
|
||||
|
||||
**No iframes, no hacks, just clean React integration!**
|
||||
|
||||
---
|
||||
|
||||
## Admin SPA Addons
|
||||
|
||||
### Quick Start
|
||||
|
||||
**5-Minute Integration:**
|
||||
|
||||
```php
|
||||
<?php
|
||||
/**
|
||||
* Plugin Name: My WooNooW Addon
|
||||
* Description: Adds custom functionality to WooNooW
|
||||
* Version: 1.0.0
|
||||
*/
|
||||
|
||||
// 1. Register your addon
|
||||
add_filter('woonoow/addon_registry', function($addons) {
|
||||
$addons['my-addon'] = [
|
||||
'id' => 'my-addon',
|
||||
'name' => 'My Addon',
|
||||
'version' => '1.0.0',
|
||||
'author' => 'Your Name',
|
||||
'description' => 'My awesome addon',
|
||||
'spa_bundle' => plugin_dir_url(__FILE__) . 'dist/addon.js',
|
||||
'dependencies' => ['woocommerce' => '8.0'],
|
||||
];
|
||||
return $addons;
|
||||
});
|
||||
|
||||
// 2. Register your routes
|
||||
add_filter('woonoow/spa_routes', function($routes) {
|
||||
$routes[] = [
|
||||
'path' => '/my-addon',
|
||||
'component_url' => plugin_dir_url(__FILE__) . 'dist/MyAddonPage.js',
|
||||
'capability' => 'manage_woocommerce',
|
||||
'title' => 'My Addon',
|
||||
];
|
||||
return $routes;
|
||||
});
|
||||
|
||||
// 3. Add navigation item
|
||||
add_filter('woonoow/nav_tree', function($tree) {
|
||||
$tree[] = [
|
||||
'key' => 'my-addon',
|
||||
'label' => 'My Addon',
|
||||
'path' => '/my-addon',
|
||||
'icon' => 'puzzle', // lucide icon name
|
||||
'children' => [],
|
||||
];
|
||||
return $tree;
|
||||
});
|
||||
```
|
||||
|
||||
**That's it!** Your addon is now integrated into WooNooW.
|
||||
|
||||
---
|
||||
|
||||
### Addon Registration
|
||||
|
||||
**Filter:** `woonoow/addon_registry`
|
||||
**Priority:** 20 (runs on `plugins_loaded`)
|
||||
**File:** `includes/Compat/AddonRegistry.php`
|
||||
|
||||
#### Configuration Schema
|
||||
|
||||
```php
|
||||
add_filter('woonoow/addon_registry', function($addons) {
|
||||
$addons['addon-id'] = [
|
||||
// Required
|
||||
'id' => 'addon-id', // Unique identifier
|
||||
'name' => 'Addon Name', // Display name
|
||||
'version' => '1.0.0', // Semantic version
|
||||
|
||||
// Optional
|
||||
'author' => 'Author Name', // Author name
|
||||
'description' => 'Description', // Short description
|
||||
'spa_bundle' => 'https://...', // Main JS bundle URL
|
||||
|
||||
// Dependencies (optional)
|
||||
'dependencies' => [
|
||||
'woocommerce' => '8.0', // Min WooCommerce version
|
||||
'wordpress' => '6.0', // Min WordPress version
|
||||
],
|
||||
|
||||
// Advanced (optional)
|
||||
'routes' => [], // Route definitions
|
||||
'nav_items' => [], // Nav item definitions
|
||||
'widgets' => [], // Widget definitions
|
||||
];
|
||||
return $addons;
|
||||
});
|
||||
```
|
||||
|
||||
#### Dependency Validation
|
||||
|
||||
WooNooW automatically validates dependencies:
|
||||
|
||||
```php
|
||||
'dependencies' => [
|
||||
'woocommerce' => '8.0', // Requires WooCommerce 8.0+
|
||||
'wordpress' => '6.4', // Requires WordPress 6.4+
|
||||
]
|
||||
```
|
||||
|
||||
If dependencies are not met:
|
||||
- ❌ Addon is disabled automatically
|
||||
- ❌ Routes are not registered
|
||||
- ❌ Navigation items are hidden
|
||||
|
||||
---
|
||||
|
||||
### Route Registration
|
||||
|
||||
**Filter:** `woonoow/spa_routes`
|
||||
**Priority:** 25 (runs on `plugins_loaded`)
|
||||
**File:** `includes/Compat/RouteRegistry.php`
|
||||
|
||||
#### Basic Route
|
||||
|
||||
```php
|
||||
add_filter('woonoow/spa_routes', function($routes) {
|
||||
$routes[] = [
|
||||
'path' => '/subscriptions',
|
||||
'component_url' => plugin_dir_url(__FILE__) . 'dist/SubscriptionsList.js',
|
||||
'capability' => 'manage_woocommerce',
|
||||
'title' => 'Subscriptions',
|
||||
];
|
||||
return $routes;
|
||||
});
|
||||
```
|
||||
|
||||
#### Multiple Routes
|
||||
|
||||
```php
|
||||
add_filter('woonoow/spa_routes', function($routes) {
|
||||
$base_url = plugin_dir_url(__FILE__) . 'dist/';
|
||||
|
||||
$routes[] = [
|
||||
'path' => '/subscriptions',
|
||||
'component_url' => $base_url . 'SubscriptionsList.js',
|
||||
'capability' => 'manage_woocommerce',
|
||||
'title' => 'All Subscriptions',
|
||||
];
|
||||
|
||||
$routes[] = [
|
||||
'path' => '/subscriptions/new',
|
||||
'component_url' => $base_url . 'SubscriptionNew.js',
|
||||
'capability' => 'manage_woocommerce',
|
||||
'title' => 'New Subscription',
|
||||
];
|
||||
|
||||
$routes[] = [
|
||||
'path' => '/subscriptions/:id',
|
||||
'component_url' => $base_url . 'SubscriptionDetail.js',
|
||||
'capability' => 'manage_woocommerce',
|
||||
'title' => 'Subscription Detail',
|
||||
];
|
||||
|
||||
return $routes;
|
||||
});
|
||||
```
|
||||
|
||||
#### Route Configuration
|
||||
|
||||
| Property | Type | Required | Description |
|
||||
|----------|------|----------|-------------|
|
||||
| `path` | string | ✅ Yes | Route path (must start with `/`) |
|
||||
| `component_url` | string | ✅ Yes | URL to React component JS file |
|
||||
| `capability` | string | No | WordPress capability (default: `manage_woocommerce`) |
|
||||
| `title` | string | No | Page title |
|
||||
| `exact` | boolean | No | Exact path match (default: `false`) |
|
||||
| `props` | object | No | Props to pass to component |
|
||||
|
||||
---
|
||||
|
||||
### Navigation Injection
|
||||
|
||||
#### Add Main Menu Item
|
||||
|
||||
**Filter:** `woonoow/nav_tree`
|
||||
**Priority:** 30 (runs on `plugins_loaded`)
|
||||
**File:** `includes/Compat/NavigationRegistry.php`
|
||||
|
||||
```php
|
||||
add_filter('woonoow/nav_tree', function($tree) {
|
||||
$tree[] = [
|
||||
'key' => 'subscriptions',
|
||||
'label' => __('Subscriptions', 'my-addon'),
|
||||
'path' => '/subscriptions',
|
||||
'icon' => 'repeat', // lucide-react icon name
|
||||
'children' => [
|
||||
[
|
||||
'label' => __('All Subscriptions', 'my-addon'),
|
||||
'mode' => 'spa',
|
||||
'path' => '/subscriptions',
|
||||
],
|
||||
[
|
||||
'label' => __('New', 'my-addon'),
|
||||
'mode' => 'spa',
|
||||
'path' => '/subscriptions/new',
|
||||
],
|
||||
],
|
||||
];
|
||||
return $tree;
|
||||
});
|
||||
```
|
||||
|
||||
#### Inject into Existing Section
|
||||
|
||||
**Filter:** `woonoow/nav_tree/{key}/children`
|
||||
|
||||
```php
|
||||
// Add "Bundles" to Products menu
|
||||
add_filter('woonoow/nav_tree/products/children', function($children) {
|
||||
$children[] = [
|
||||
'label' => __('Bundles', 'my-addon'),
|
||||
'mode' => 'spa',
|
||||
'path' => '/products/bundles',
|
||||
];
|
||||
return $children;
|
||||
});
|
||||
|
||||
// Add "Reports" to Dashboard menu
|
||||
add_filter('woonoow/nav_tree/dashboard/children', function($children) {
|
||||
$children[] = [
|
||||
'label' => __('Custom Reports', 'my-addon'),
|
||||
'mode' => 'spa',
|
||||
'path' => '/reports',
|
||||
];
|
||||
return $children;
|
||||
});
|
||||
```
|
||||
|
||||
#### Available Sections
|
||||
|
||||
| Key | Label | Path |
|
||||
|-----|-------|------|
|
||||
| `dashboard` | Dashboard | `/` |
|
||||
| `orders` | Orders | `/orders` |
|
||||
| `products` | Products | `/products` |
|
||||
| `coupons` | Coupons | `/coupons` |
|
||||
| `customers` | Customers | `/customers` |
|
||||
| `settings` | Settings | `/settings` |
|
||||
|
||||
#### Navigation Item Schema
|
||||
|
||||
```typescript
|
||||
{
|
||||
key: string; // Unique key (for main items)
|
||||
label: string; // Display label (i18n recommended)
|
||||
path: string; // Route path
|
||||
icon?: string; // Lucide icon name (main items only)
|
||||
mode: 'spa' | 'bridge'; // Render mode
|
||||
href?: string; // External URL (bridge mode)
|
||||
exact?: boolean; // Exact path match
|
||||
children?: SubItem[]; // Submenu items
|
||||
}
|
||||
```
|
||||
|
||||
#### Lucide Icons
|
||||
|
||||
WooNooW uses [lucide-react](https://lucide.dev/) icons (16-20px, 1.5px stroke).
|
||||
|
||||
**Popular icons:**
|
||||
- `layout-dashboard` - Dashboard
|
||||
- `receipt-text` - Orders
|
||||
- `package` - Products
|
||||
- `tag` - Coupons
|
||||
- `users` - Customers
|
||||
- `settings` - Settings
|
||||
- `repeat` - Subscriptions
|
||||
- `calendar` - Bookings
|
||||
- `credit-card` - Payments
|
||||
- `bar-chart` - Analytics
|
||||
|
||||
---
|
||||
|
||||
### Component Development
|
||||
|
||||
#### Component Structure
|
||||
|
||||
Your React component will be dynamically imported and rendered:
|
||||
|
||||
```typescript
|
||||
// dist/MyAddonPage.tsx
|
||||
import React from 'react';
|
||||
|
||||
export default function MyAddonPage(props: any) {
|
||||
return (
|
||||
<div className="space-y-6">
|
||||
<div className="rounded-lg border border-border p-6 bg-card">
|
||||
<h2 className="text-xl font-semibold mb-2">My Addon</h2>
|
||||
<p className="text-sm opacity-70">Welcome to my addon!</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
#### Access WooNooW APIs
|
||||
|
||||
```typescript
|
||||
// Access REST API
|
||||
const api = (window as any).WNW_API;
|
||||
const response = await fetch(`${api.root}my-addon/endpoint`, {
|
||||
headers: {
|
||||
'X-WP-Nonce': api.nonce,
|
||||
},
|
||||
});
|
||||
|
||||
// Access store data
|
||||
const store = (window as any).WNW_STORE;
|
||||
console.log('Currency:', store.currency);
|
||||
console.log('Symbol:', store.currency_symbol);
|
||||
|
||||
// Access site info
|
||||
const wnw = (window as any).wnw;
|
||||
console.log('Site Title:', wnw.siteTitle);
|
||||
console.log('Admin URL:', wnw.adminUrl);
|
||||
```
|
||||
|
||||
#### Use WooNooW Components
|
||||
|
||||
```typescript
|
||||
import { __ } from '@/lib/i18n';
|
||||
import { formatMoney } from '@/lib/currency';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Card } from '@/components/ui/card';
|
||||
|
||||
export default function MyAddonPage() {
|
||||
return (
|
||||
<Card className="p-6">
|
||||
<h2>{__('My Addon', 'my-addon')}</h2>
|
||||
<p>{formatMoney(1234.56)}</p>
|
||||
<Button>{__('Click Me', 'my-addon')}</Button>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
#### Build Your Component
|
||||
|
||||
**Using Vite:**
|
||||
|
||||
```javascript
|
||||
// vite.config.js
|
||||
import { defineConfig } from 'vite';
|
||||
import react from '@vitejs/plugin-react';
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [react()],
|
||||
build: {
|
||||
lib: {
|
||||
entry: 'src/MyAddonPage.tsx',
|
||||
name: 'MyAddon',
|
||||
fileName: 'MyAddonPage',
|
||||
formats: ['es'],
|
||||
},
|
||||
rollupOptions: {
|
||||
external: ['react', 'react-dom'],
|
||||
output: {
|
||||
globals: {
|
||||
react: 'React',
|
||||
'react-dom': 'ReactDOM',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
```bash
|
||||
npm run build
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Best Practices
|
||||
|
||||
#### ✅ DO:
|
||||
|
||||
1. **Use Semantic Versioning**
|
||||
```php
|
||||
'version' => '1.2.3'
|
||||
```
|
||||
|
||||
2. **Declare Dependencies**
|
||||
```php
|
||||
'dependencies' => ['woocommerce' => '8.0']
|
||||
```
|
||||
|
||||
3. **Check Capabilities**
|
||||
```php
|
||||
'capability' => 'manage_woocommerce'
|
||||
```
|
||||
|
||||
4. **Internationalize Strings**
|
||||
```php
|
||||
'label' => __('Subscriptions', 'my-addon')
|
||||
```
|
||||
|
||||
5. **Use Namespaced Hooks**
|
||||
```php
|
||||
add_filter('woonoow/addon_registry', ...)
|
||||
```
|
||||
|
||||
6. **Validate User Input**
|
||||
```php
|
||||
$value = sanitize_text_field($_POST['value']);
|
||||
```
|
||||
|
||||
7. **Handle Errors Gracefully**
|
||||
```typescript
|
||||
try {
|
||||
// Load component
|
||||
} catch (error) {
|
||||
// Show error message
|
||||
}
|
||||
```
|
||||
|
||||
8. **Follow WooNooW UI Patterns**
|
||||
- Use Tailwind CSS classes
|
||||
- Use Shadcn UI components
|
||||
- Follow mobile-first design
|
||||
- Use `.ui-ctrl` class for controls
|
||||
|
||||
#### ❌ DON'T:
|
||||
|
||||
1. **Don't Hardcode URLs**
|
||||
```php
|
||||
// ❌ Bad
|
||||
'component_url' => 'https://mysite.com/addon.js'
|
||||
|
||||
// ✅ Good
|
||||
'component_url' => plugin_dir_url(__FILE__) . 'dist/addon.js'
|
||||
```
|
||||
|
||||
2. **Don't Skip Capability Checks**
|
||||
```php
|
||||
// ❌ Bad
|
||||
'capability' => ''
|
||||
|
||||
// ✅ Good
|
||||
'capability' => 'manage_woocommerce'
|
||||
```
|
||||
|
||||
3. **Don't Use Generic Hook Names**
|
||||
```php
|
||||
// ❌ Bad
|
||||
add_filter('addon_registry', ...)
|
||||
|
||||
// ✅ Good
|
||||
add_filter('woonoow/addon_registry', ...)
|
||||
```
|
||||
|
||||
4. **Don't Modify Core Navigation**
|
||||
```php
|
||||
// ❌ Bad - Don't remove core items
|
||||
unset($tree[0]);
|
||||
|
||||
// ✅ Good - Add your own items
|
||||
$tree[] = ['key' => 'my-addon', ...];
|
||||
```
|
||||
|
||||
5. **Don't Block the Main Thread**
|
||||
```typescript
|
||||
// ❌ Bad
|
||||
while (loading) { /* wait */ }
|
||||
|
||||
// ✅ Good
|
||||
if (loading) return <Loader />;
|
||||
```
|
||||
|
||||
6. **Don't Use Inline Styles**
|
||||
```typescript
|
||||
// ❌ Bad
|
||||
<div style={{color: 'red'}}>
|
||||
|
||||
// ✅ Good
|
||||
<div className="text-red-600">
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Customer SPA Addons
|
||||
|
||||
**Status:** 🚧 Coming Soon
|
||||
|
||||
Customer SPA addon injection will support:
|
||||
- Cart page customization
|
||||
- Checkout step injection
|
||||
- My Account page tabs
|
||||
- Widget areas
|
||||
- Custom forms
|
||||
|
||||
**Stay tuned for updates!**
|
||||
|
||||
---
|
||||
|
||||
## Testing & Debugging
|
||||
|
||||
### Enable Debug Mode
|
||||
|
||||
```php
|
||||
// wp-config.php
|
||||
define('WNW_DEV', true);
|
||||
```
|
||||
|
||||
This enables:
|
||||
- ✅ Console logging
|
||||
- ✅ Cache flushing
|
||||
- ✅ Detailed error messages
|
||||
|
||||
### Check Addon Registration
|
||||
|
||||
```javascript
|
||||
// Browser console
|
||||
console.log(window.WNW_ADDONS);
|
||||
console.log(window.WNW_ADDON_ROUTES);
|
||||
console.log(window.WNW_NAV_TREE);
|
||||
```
|
||||
|
||||
### Flush Caches
|
||||
|
||||
```php
|
||||
// Programmatically
|
||||
do_action('woonoow_flush_caches');
|
||||
|
||||
// Or via URL (admins only)
|
||||
// https://yoursite.com/wp-admin/?flush_wnw_cache=1
|
||||
```
|
||||
|
||||
### Common Issues
|
||||
|
||||
**Addon not appearing?**
|
||||
- Check dependencies are met
|
||||
- Verify capability requirements
|
||||
- Check browser console for errors
|
||||
- Flush caches
|
||||
|
||||
**Route not loading?**
|
||||
- Verify `component_url` is correct
|
||||
- Check file exists and is accessible
|
||||
- Look for JS errors in console
|
||||
- Ensure component exports default
|
||||
|
||||
**Navigation not showing?**
|
||||
- Check filter priority
|
||||
- Verify path matches route
|
||||
- Check i18n strings load
|
||||
- Inspect `window.WNW_NAV_TREE`
|
||||
|
||||
---
|
||||
|
||||
## Examples
|
||||
|
||||
### Example 1: Simple Addon
|
||||
|
||||
```php
|
||||
<?php
|
||||
/**
|
||||
* Plugin Name: WooNooW Hello World
|
||||
* Description: Minimal addon example
|
||||
* Version: 1.0.0
|
||||
*/
|
||||
|
||||
add_filter('woonoow/addon_registry', function($addons) {
|
||||
$addons['hello-world'] = [
|
||||
'id' => 'hello-world',
|
||||
'name' => 'Hello World',
|
||||
'version' => '1.0.0',
|
||||
];
|
||||
return $addons;
|
||||
});
|
||||
|
||||
add_filter('woonoow/spa_routes', function($routes) {
|
||||
$routes[] = [
|
||||
'path' => '/hello',
|
||||
'component_url' => plugin_dir_url(__FILE__) . 'dist/Hello.js',
|
||||
'capability' => 'read', // All logged-in users
|
||||
'title' => 'Hello World',
|
||||
];
|
||||
return $routes;
|
||||
});
|
||||
|
||||
add_filter('woonoow/nav_tree', function($tree) {
|
||||
$tree[] = [
|
||||
'key' => 'hello',
|
||||
'label' => 'Hello',
|
||||
'path' => '/hello',
|
||||
'icon' => 'smile',
|
||||
'children' => [],
|
||||
];
|
||||
return $tree;
|
||||
});
|
||||
```
|
||||
|
||||
```typescript
|
||||
// dist/Hello.tsx
|
||||
import React from 'react';
|
||||
|
||||
export default function Hello() {
|
||||
return (
|
||||
<div className="p-6">
|
||||
<h1 className="text-2xl font-bold">Hello, WooNooW!</h1>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
### Example 2: Full-Featured Addon
|
||||
|
||||
See `ADDON_INJECTION_READINESS_REPORT.md` for the complete Subscriptions addon example.
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Addon Registry Issues
|
||||
|
||||
**Problem:** Addon not registered
|
||||
|
||||
**Solutions:**
|
||||
1. Check `plugins_loaded` hook fires
|
||||
2. Verify filter name: `woonoow/addon_registry`
|
||||
3. Check dependencies are met
|
||||
4. Look for PHP errors in debug log
|
||||
|
||||
### Route Issues
|
||||
|
||||
**Problem:** Route returns 404
|
||||
|
||||
**Solutions:**
|
||||
1. Verify path starts with `/`
|
||||
2. Check `component_url` is accessible
|
||||
3. Ensure route is registered before navigation
|
||||
4. Check capability requirements
|
||||
|
||||
### Navigation Issues
|
||||
|
||||
**Problem:** Menu item not showing
|
||||
|
||||
**Solutions:**
|
||||
1. Check filter: `woonoow/nav_tree` or `woonoow/nav_tree/{key}/children`
|
||||
2. Verify path matches registered route
|
||||
3. Check i18n strings are loaded
|
||||
4. Inspect `window.WNW_NAV_TREE` in console
|
||||
|
||||
### Component Loading Issues
|
||||
|
||||
**Problem:** Component fails to load
|
||||
|
||||
**Solutions:**
|
||||
1. Check component exports `default`
|
||||
2. Verify file is built correctly
|
||||
3. Check for JS errors in console
|
||||
4. Ensure React/ReactDOM are available
|
||||
5. Test component URL directly in browser
|
||||
|
||||
---
|
||||
|
||||
## Support & Resources
|
||||
|
||||
**Documentation:**
|
||||
- `ADDON_INJECTION_READINESS_REPORT.md` - Technical analysis
|
||||
- `ADDONS_ADMIN_UI_REQUIREMENTS.md` - Requirements & status
|
||||
- `PROGRESS_NOTE.md` - Development progress
|
||||
|
||||
**Code References:**
|
||||
- `includes/Compat/AddonRegistry.php` - Addon registration
|
||||
- `includes/Compat/RouteRegistry.php` - Route management
|
||||
- `includes/Compat/NavigationRegistry.php` - Navigation building
|
||||
- `admin-spa/src/App.tsx` - Dynamic route loading
|
||||
- `admin-spa/src/nav/tree.ts` - Navigation tree
|
||||
|
||||
**Community:**
|
||||
- GitHub Issues: Report bugs
|
||||
- Discussions: Ask questions
|
||||
- Examples: Share your addons
|
||||
|
||||
---
|
||||
|
||||
**End of Guide**
|
||||
|
||||
**Version:** 1.0.0
|
||||
**Last Updated:** 2025-10-28
|
||||
**Status:** ✅ Production Ready
|
||||
Reference in New Issue
Block a user