# thinkrank/1.0.0/src/admin/components/pages/UsageAnalytics.js

ThinkRank AI SEO – AI SEO Plugin for WordPress: Schema, XML Sitemaps, Meta Tags, Search Console &amp; Local SEO, version 1.0.0. 331 lines.

- Page: https://pluginprobe.com/plugins/thinkrank/1.0.0/code/src/admin/components/pages/UsageAnalytics.js
- Raw: https://pluginprobe.com/plugins/thinkrank/1.0.0/raw/src/admin/components/pages/UsageAnalytics.js
- Modified: 2025-08-10T07:57:44+00:00

Line numbers below start at 1. Link to a line or a range by appending a fragment to the
page URL, for example `https://pluginprobe.com/plugins/thinkrank/1.0.0/code/src/admin/components/pages/UsageAnalytics.js#L10-L20`.

```javascript
/**
 * Usage Analytics Page Component
 *
 * AI usage analytics and performance tracking with real data integration
 *
 * @package ThinkRank
 * @since 1.0.0
 */

import { __ } from '@wordpress/i18n';
import { Card, CardBody, CardHeader, Spinner, Notice, SelectControl, TabPanel } from '@wordpress/components';
import { useSelect, useDispatch } from '@wordpress/data';
import { useEffect, useState } from '@wordpress/element';
import { edit, chartBar, currencyDollar, backup, plugins, starFilled, check, trendingUp } from '@wordpress/icons';
import UsageBreakdown from './UsageBreakdown';

/**
 * Icon Component - Renders WordPress icons consistently
 */
const Icon = ({ icon, className = "thinkrank-w-5 thinkrank-h-5" }) => {
    return (
        <span className={className}>
            {icon}
        </span>
    );
};

/**
 * MetricCard Component
 */
const MetricCard = ({ title, value, change, prefix = '', suffix = '', subtitle = '', icon = null }) => {
    const changeColorClass = change > 0 ? 'thinkrank-text-green' : change < 0 ? 'thinkrank-text-red' : 'thinkrank-text-secondary';
    const changeSymbol = change > 0 ? '+' : '';

    // More meaningful text for zero change
    const getChangeText = () => {
        if (change !== 0) {
            return `${changeSymbol}${change}%`;
        }
        // Show meaningful text based on the metric type
        if (title.includes('Success Rate')) return 'Successful AI Responses';
        if (title.includes('Features Used')) return 'Diverse toolkit usage';
        if (title.includes('Most Used')) return ''; // No change text needed - has subtitle
        if (title.includes('AI Optimizations')) return 'Total count';
        return 'No change';
    };

    return (
        <div className="thinkrank-card thinkrank-card--elevated">
            <div className="thinkrank-card__body">
                <div className="thinkrank-flex thinkrank-items-center thinkrank-gap-2 thinkrank-mb-4">
                    {icon && <Icon icon={icon} className="thinkrank-w-5 thinkrank-h-5 thinkrank-text-blue thinkrank-flex-shrink-0" />}
                    <h3 className="thinkrank-text-xs thinkrank-font-semibold thinkrank-text-muted thinkrank-uppercase thinkrank-tracking-wide thinkrank-mt-0 thinkrank-mb-0">
                        {title}
                    </h3>
                </div>
                <div>
                    <p className="thinkrank-text-3xl thinkrank-font-bold thinkrank-text-primary thinkrank-mb-2 thinkrank-leading-none">
                        {prefix}{typeof value === 'number' ? value.toLocaleString() : value}{suffix}
                    </p>
                    {subtitle && <p className="thinkrank-text-sm thinkrank-text-secondary thinkrank-mb-1">{subtitle}</p>}
                    <p className={`thinkrank-text-sm thinkrank-font-medium ${changeColorClass}`}>
                        {getChangeText()}
                    </p>
                </div>
            </div>
        </div>
    );
};

/**
 * Overview Tab Component
 */
const OverviewTab = () => {
    const [period, setPeriod] = useState('30d');

    // Select data from the analytics store
    const {
        dashboardMetrics,
        isLoading,
        error,
        hasData,
        lastUpdated,
        featureBreakdown,
        providerBreakdown
    } = useSelect((select) => {
        const analyticsSelect = select('thinkrank/analytics');
        return {
            dashboardMetrics: analyticsSelect.getDashboardMetrics(),
            isLoading: analyticsSelect.getIsLoading(),
            error: analyticsSelect.getError(),
            hasData: analyticsSelect.hasData(),
            lastUpdated: analyticsSelect.getLastUpdated(),
            featureBreakdown: analyticsSelect.getFeatureBreakdown(),
            providerBreakdown: analyticsSelect.getProviderBreakdown()
        };
    }, []);

    // Get dispatch functions
    const { fetchMetrics } = useDispatch('thinkrank/analytics');

    // Fetch data on component mount and when period changes
    useEffect(() => {
        fetchMetrics(period);
    }, [period, fetchMetrics]);

    // Period options
    const periodOptions = [
        { label: __('Last 7 days', 'thinkrank'), value: '7d' },
        { label: __('Last 30 days', 'thinkrank'), value: '30d' },
        { label: __('Last 90 days', 'thinkrank'), value: '90d' },
        { label: __('All time', 'thinkrank'), value: 'all' }
    ];

    return (
        <div className="thinkrank-card thinkrank-card--elevated thinkrank-mb-6">
            <div className="thinkrank-card__header">
                <div className="thinkrank-flex thinkrank-justify-between thinkrank-items-center thinkrank-flex-wrap thinkrank-gap-4">
                    <h2 className="thinkrank-text-2xl thinkrank-font-bold thinkrank-text-primary thinkrank-mb-0">
                        {__('Usage Overview', 'thinkrank')}
                    </h2>
                    <SelectControl
                        label={__('Time Period', 'thinkrank')}
                        value={period}
                        options={periodOptions}
                        onChange={setPeriod}
                        className="thinkrank-min-w-40"
                        __next40pxDefaultSize={true}
                        __nextHasNoMarginBottom={true}
                    />
                </div>
            </div>
            <div className="thinkrank-card__body">
                {error && (
                    <Notice status="error" isDismissible={false}>
                        <p>{__('Error loading analytics data:', 'thinkrank')} {error.message}</p>
                    </Notice>
                )}

                {isLoading && (
                    <div className="thinkrank-flex thinkrank-flex-col thinkrank-items-center thinkrank-justify-center thinkrank-p-8 thinkrank-text-center">
                        <Spinner />
                        <p className="thinkrank-mt-4 thinkrank-text-secondary">{__('Loading analytics data...', 'thinkrank')}</p>
                    </div>
                )}

                {!isLoading && !error && (
                    <>
                        {/* Row 1: Core Performance Metrics */}
                        <div className="thinkrank-grid thinkrank-grid-cols-1-xs thinkrank-grid-cols-2-md thinkrank-grid-cols-4-lg thinkrank-gap-6 thinkrank-mb-6">
                            <MetricCard
                                title={dashboardMetrics.postsAnalyzed.label}
                                value={dashboardMetrics.postsAnalyzed.value}
                                change={dashboardMetrics.postsAnalyzed.change}
                                icon={edit}
                            />

                            <MetricCard
                                title={dashboardMetrics.aiOptimizations.label}
                                value={dashboardMetrics.aiOptimizations.value}
                                change={dashboardMetrics.aiOptimizations.change}
                                icon={trendingUp}
                            />

                            <MetricCard
                                title={dashboardMetrics.averageSeoScore.label}
                                value={dashboardMetrics.averageSeoScore.value}
                                change={dashboardMetrics.averageSeoScore.change}
                                suffix={dashboardMetrics.averageSeoScore.suffix}
                                icon={chartBar}
                            />

                            <MetricCard
                                title={dashboardMetrics.totalCost.label}
                                value={dashboardMetrics.totalCost.value.toFixed(4)}
                                change={dashboardMetrics.totalCost.change}
                                prefix={dashboardMetrics.totalCost.prefix}
                                subtitle={dashboardMetrics.totalCost.subtitle}
                                icon={currencyDollar}
                            />
                        </div>

                        {/* Row 2: Feature & Efficiency Metrics */}
                        <div className="thinkrank-grid thinkrank-grid-cols-1-xs thinkrank-grid-cols-2-md thinkrank-grid-cols-4-lg thinkrank-gap-6 thinkrank-mb-8">
                            <MetricCard
                                title={dashboardMetrics.featuresUsed.label}
                                value={dashboardMetrics.featuresUsed.value}
                                change={dashboardMetrics.featuresUsed.change}
                                icon={plugins}
                            />

                            <MetricCard
                                title={dashboardMetrics.timeSaved.label}
                                value={dashboardMetrics.timeSaved.value}
                                change={dashboardMetrics.timeSaved.change}
                                suffix={dashboardMetrics.timeSaved.suffix}
                                subtitle={dashboardMetrics.timeSaved.subtitle}
                                icon={backup}
                            />

                            <MetricCard
                                title={dashboardMetrics.mostUsedFeature.label}
                                value={dashboardMetrics.mostUsedFeature.value}
                                change={dashboardMetrics.mostUsedFeature.change}
                                subtitle={dashboardMetrics.mostUsedFeature.subtitle}
                                icon={starFilled}
                            />

                            <MetricCard
                                title={dashboardMetrics.successRate.label}
                                value={dashboardMetrics.successRate.value}
                                change={dashboardMetrics.successRate.change}
                                suffix={dashboardMetrics.successRate.suffix}
                                icon={check}
                            />
                        </div>

                        {!hasData && (
                            <div className="thinkrank-text-center thinkrank-p-8 thinkrank-bg-gray-50 thinkrank-rounded-lg thinkrank-mb-6">
                                <p className="thinkrank-text-secondary thinkrank-text-base thinkrank-mb-0">
                                    {__('No analytics data available yet. Start using AI features to see your usage statistics.', 'thinkrank')}
                                </p>
                            </div>
                        )}

                        {hasData && (
                            <div className="thinkrank-grid thinkrank-grid-cols-1-xs thinkrank-grid-cols-2-lg thinkrank-gap-8 thinkrank-mt-8">
                                <div className="thinkrank-card">
                                    <div className="thinkrank-card__body">
                                        <h3 className="thinkrank-text-lg thinkrank-font-semibold thinkrank-text-primary thinkrank-mb-4">
                                            {__('Feature Usage Breakdown', 'thinkrank')}
                                        </h3>
                                        <div className="thinkrank-space-y-3">
                                            {Object.entries(featureBreakdown).map(([feature, count]) => (
                                                <div key={feature} className="thinkrank-flex thinkrank-justify-between thinkrank-items-center thinkrank-py-2 thinkrank-border-b thinkrank-border-gray-200 last:thinkrank-border-b-0">
                                                    <span className="thinkrank-font-medium thinkrank-text-primary">
                                                        {feature.replace(/_/g, ' ').replace(/\b\w/g, l => l.toUpperCase()).replace(/\bSeo\b/g, 'SEO')}
                                                    </span>
                                                    <span className="thinkrank-font-semibold thinkrank-text-blue">{count}</span>
                                                </div>
                                            ))}
                                        </div>
                                    </div>
                                </div>

                                <div className="thinkrank-card">
                                    <div className="thinkrank-card__body">
                                        <h3 className="thinkrank-text-lg thinkrank-font-semibold thinkrank-text-primary thinkrank-mb-4">
                                            {__('Provider Cost Breakdown', 'thinkrank')}
                                        </h3>
                                        <div className="thinkrank-space-y-3">
                                            {Object.entries(providerBreakdown).map(([provider, data]) => (
                                                <div key={provider} className="thinkrank-flex thinkrank-justify-between thinkrank-items-center thinkrank-py-2 thinkrank-border-b thinkrank-border-gray-200 last:thinkrank-border-b-0">
                                                    <span className="thinkrank-font-medium thinkrank-text-primary">
                                                        {provider.charAt(0).toUpperCase() + provider.slice(1)}
                                                    </span>
                                                    <span className="thinkrank-font-semibold thinkrank-text-blue">
                                                        ${data.cost?.toFixed(4) || '0.0000'} ({data.percentage || 0}%)
                                                    </span>
                                                </div>
                                            ))}
                                        </div>
                                    </div>
                                </div>
                            </div>
                        )}

                        {lastUpdated && (
                            <div className="thinkrank-mt-8 thinkrank-pt-6 thinkrank-border-t thinkrank-border-gray-200 thinkrank-text-center">
                                <p className="thinkrank-text-sm thinkrank-text-secondary thinkrank-mb-0">
                                    {__('Last updated:', 'thinkrank')} {new Date(lastUpdated).toLocaleString()}
                                </p>
                            </div>
                        )}
                    </>
                )}
            </div>
        </div>
    );
};

/**
 * Main Analytics Component with Tabs
 */
const Analytics = () => {
    const tabs = [
        {
            name: 'overview',
            title: __('Overview', 'thinkrank'),
            className: 'thinkrank-tab-overview'
        },
        {
            name: 'usage-breakdown',
            title: __('Usage Breakdown', 'thinkrank'),
            className: 'thinkrank-tab-usage-breakdown'
        }
    ];

    return (
        <div className="thinkrank-ui">
            <div className="thinkrank-mb-6">
                <h1 className="thinkrank-text-3xl thinkrank-font-bold thinkrank-text-primary thinkrank-mb-2">
                    {__('AI Usage & Performance Analytics', 'thinkrank')}
                </h1>
                <p className="thinkrank-text-secondary thinkrank-text-lg">
                    {__('Track your AI usage, costs, and plugin performance analytics', 'thinkrank')}
                </p>
            </div>

            <TabPanel
                className="thinkrank-tab-panel"
                activeClass="is-active"
                tabs={tabs}
            >
                {(tab) => {
                    switch (tab.name) {
                        case 'overview':
                            return <OverviewTab />;
                        case 'usage-breakdown':
                            return <UsageBreakdown />;
                        default:
                            return <OverviewTab />;
                    }
                }}
            </TabPanel>
        </div>
    );
};

export default Analytics;

```
