# 🔌 Dashboard Analytics - API Integration Guide **Created:** Nov 4, 2025 9:21 AM (GMT+7) --- ## 🎯 Overview Dashboard now supports **real data from API** with a toggle to switch between real and dummy data for development/testing. **Default:** Real data (dummy data toggle OFF) --- ## 📁 Files Created ### 1. **Analytics API Module** **File:** `/admin-spa/src/lib/analyticsApi.ts` Defines all analytics endpoints: ```typescript export const AnalyticsApi = { overview: (params?: AnalyticsParams) => api.get('/woonoow/v1/analytics/overview', params), revenue: (params?: AnalyticsParams) => api.get('/woonoow/v1/analytics/revenue', params), orders: (params?: AnalyticsParams) => api.get('/woonoow/v1/analytics/orders', params), products: (params?: AnalyticsParams) => api.get('/woonoow/v1/analytics/products', params), customers: (params?: AnalyticsParams) => api.get('/woonoow/v1/analytics/customers', params), coupons: (params?: AnalyticsParams) => api.get('/woonoow/v1/analytics/coupons', params), taxes: (params?: AnalyticsParams) => api.get('/woonoow/v1/analytics/taxes', params), }; ``` ### 2. **Analytics Hooks** **File:** `/admin-spa/src/hooks/useAnalytics.ts` React Query hooks for each endpoint: ```typescript // Generic hook useAnalytics(endpoint, dummyData, additionalParams) // Specific hooks useRevenueAnalytics(dummyData, granularity?) useOrdersAnalytics(dummyData) useProductsAnalytics(dummyData) useCustomersAnalytics(dummyData) useCouponsAnalytics(dummyData) useTaxesAnalytics(dummyData) useOverviewAnalytics(dummyData) ``` --- ## 🔄 How It Works ### 1. **Context State** ```typescript // DashboardContext.tsx const [useDummyData, setUseDummyData] = useState(false); // Default: real data ``` ### 2. **Hook Logic** ```typescript // useAnalytics.ts const { data, isLoading, error } = useQuery({ queryKey: ['analytics', endpoint, period, additionalParams], queryFn: async () => { const params = { period: period === 'all' ? undefined : period, ...additionalParams }; return await AnalyticsApi[endpoint](params); }, enabled: !useDummy, // Only fetch when NOT using dummy data staleTime: 5 * 60 * 1000, // 5 minutes }); // Return dummy data if toggle is on, otherwise return API data return { data: useDummy ? dummyData : (data || dummyData), isLoading: useDummy ? false : isLoading, error: useDummy ? null : error, }; ``` ### 3. **Component Usage** ```typescript // Before (old way) const { period, useDummy } = useDashboardPeriod(); const data = useDummy ? DUMMY_DATA : DUMMY_DATA; // Always dummy! // After (new way) const { period } = useDashboardPeriod(); const { data, isLoading, error } = useCustomersAnalytics(DUMMY_CUSTOMERS_DATA); // Loading state if (isLoading) return ; // Error state if (error) return ; // Use data normally ``` --- ## 📊 API Endpoints Required ### Backend PHP REST API Routes All endpoints should be registered under `/woonoow/v1/analytics/`: #### 1. **Overview** - `GET /woonoow/v1/analytics/overview` **Query Params:** - `period`: '7', '14', '30', or omit for all-time - `start_date`: ISO date (for custom range) - `end_date`: ISO date (for custom range) **Response:** Same structure as `DUMMY_DATA` in `Dashboard/index.tsx` --- #### 2. **Revenue** - `GET /woonoow/v1/analytics/revenue` **Query Params:** - `period`: '7', '14', '30', or omit for all-time - `granularity`: 'day', 'week', 'month' **Response:** Same structure as `DUMMY_REVENUE_DATA` --- #### 3. **Orders** - `GET /woonoow/v1/analytics/orders` **Query Params:** - `period`: '7', '14', '30', or omit for all-time **Response:** Same structure as `DUMMY_ORDERS_DATA` --- #### 4. **Products** - `GET /woonoow/v1/analytics/products` **Query Params:** - `period`: '7', '14', '30', or omit for all-time **Response:** Same structure as `DUMMY_PRODUCTS_DATA` --- #### 5. **Customers** - `GET /woonoow/v1/analytics/customers` **Query Params:** - `period`: '7', '14', '30', or omit for all-time **Response:** Same structure as `DUMMY_CUSTOMERS_DATA` --- #### 6. **Coupons** - `GET /woonoow/v1/analytics/coupons` **Query Params:** - `period`: '7', '14', '30', or omit for all-time **Response:** Same structure as `DUMMY_COUPONS_DATA` --- #### 7. **Taxes** - `GET /woonoow/v1/analytics/taxes` **Query Params:** - `period`: '7', '14', '30', or omit for all-time **Response:** Same structure as `DUMMY_TAXES_DATA` --- ## 🔧 Backend Implementation Guide ### Step 1: Register REST Routes ```php // includes/Admin/Analytics/AnalyticsController.php namespace WooNooW\Admin\Analytics; class AnalyticsController { public function register_routes() { register_rest_route('woonoow/v1', '/analytics/overview', [ 'methods' => 'GET', 'callback' => [$this, 'get_overview'], 'permission_callback' => [$this, 'check_permission'], ]); register_rest_route('woonoow/v1', '/analytics/revenue', [ 'methods' => 'GET', 'callback' => [$this, 'get_revenue'], 'permission_callback' => [$this, 'check_permission'], ]); // ... register other endpoints } public function check_permission() { return current_user_can('manage_woocommerce'); } public function get_overview(\WP_REST_Request $request) { $period = $request->get_param('period'); $start_date = $request->get_param('start_date'); $end_date = $request->get_param('end_date'); // Calculate date range $dates = $this->calculate_date_range($period, $start_date, $end_date); // Fetch data from WooCommerce $data = [ 'metrics' => $this->get_overview_metrics($dates), 'salesChart' => $this->get_sales_chart($dates), 'orderStatusDistribution' => $this->get_order_status_distribution($dates), 'lowStock' => $this->get_low_stock_products(), ]; return rest_ensure_response($data); } private function calculate_date_range($period, $start_date, $end_date) { if ($start_date && $end_date) { return ['start' => $start_date, 'end' => $end_date]; } if (!$period) { // All time return ['start' => null, 'end' => null]; } $days = intval($period); $end = current_time('Y-m-d'); $start = date('Y-m-d', strtotime("-{$days} days")); return ['start' => $start, 'end' => $end]; } // ... implement other methods } ``` ### Step 2: Query WooCommerce Data ```php private function get_overview_metrics($dates) { global $wpdb; $where = $this->build_date_where_clause($dates); // Use HPOS tables $orders_table = $wpdb->prefix . 'wc_orders'; $query = " SELECT COUNT(*) as total_orders, SUM(total_amount) as total_revenue, AVG(total_amount) as avg_order_value FROM {$orders_table} WHERE status IN ('wc-completed', 'wc-processing') {$where} "; $results = $wpdb->get_row($query); // Calculate comparison with previous period $previous_metrics = $this->get_previous_period_metrics($dates); return [ 'revenue' => [ 'today' => floatval($results->total_revenue), 'yesterday' => floatval($previous_metrics->total_revenue), 'change' => $this->calculate_change_percent( $results->total_revenue, $previous_metrics->total_revenue ), ], // ... other metrics ]; } ``` --- ## 🎨 Frontend Implementation ### Example: Update Revenue.tsx ```typescript import { useRevenueAnalytics } from '@/hooks/useAnalytics'; import { DUMMY_REVENUE_DATA } from './data/dummyRevenue'; export default function RevenueAnalytics() { const { period } = useDashboardPeriod(); const [granularity, setGranularity] = useState<'day' | 'week' | 'month'>('day'); // Fetch real data or use dummy data const { data, isLoading, error } = useRevenueAnalytics(DUMMY_REVENUE_DATA, granularity); if (isLoading) return ; if (error) return ; // Use data normally... } ``` --- ## 🔀 Toggle Behavior ### When Dummy Data Toggle is OFF (default): 1. ✅ Fetches real data from API 2. ✅ Shows loading spinner while fetching 3. ✅ Shows error message if API fails 4. ✅ Caches data for 5 minutes (React Query) 5. ✅ Automatically refetches when period changes ### When Dummy Data Toggle is ON: 1. ✅ Uses dummy data immediately (no API call) 2. ✅ No loading state 3. ✅ No error state 4. ✅ Perfect for development/testing --- ## 📋 Migration Checklist ### Frontend (React): - [x] Create `analyticsApi.ts` with all endpoints - [x] Create `useAnalytics.ts` hooks - [x] Update `DashboardContext` default to `false` - [x] Update `Customers.tsx` as example - [ ] Update `Revenue.tsx` - [ ] Update `Orders.tsx` - [ ] Update `Products.tsx` - [ ] Update `Coupons.tsx` - [ ] Update `Taxes.tsx` - [ ] Update `Dashboard/index.tsx` (overview) ### Backend (PHP): - [ ] Create `AnalyticsController.php` - [ ] Register REST routes - [ ] Implement `/analytics/overview` - [ ] Implement `/analytics/revenue` - [ ] Implement `/analytics/orders` - [ ] Implement `/analytics/products` - [ ] Implement `/analytics/customers` - [ ] Implement `/analytics/coupons` - [ ] Implement `/analytics/taxes` - [ ] Add permission checks - [ ] Add data caching (transients) - [ ] Add error handling --- ## 🚀 Benefits 1. **Real-time Data**: Dashboard shows actual store data 2. **Development Friendly**: Toggle to dummy data for testing 3. **Performance**: React Query caching reduces API calls 4. **Error Handling**: Graceful fallback to dummy data 5. **Type Safety**: TypeScript interfaces match API responses 6. **Maintainable**: Single source of truth for API endpoints --- ## 🔮 Future Enhancements 1. **Custom Date Range**: Add date picker for custom ranges 2. **Export Data**: Download analytics as CSV/PDF 3. **Real-time Updates**: WebSocket for live data 4. **Comparison Mode**: Compare multiple periods side-by-side 5. **Scheduled Reports**: Email reports automatically --- **Status:** ✅ Frontend ready - Backend implementation needed!