diff --git a/assets/src/dashboard/parts/connected/dashboard/index.js b/assets/src/dashboard/parts/connected/dashboard/index.js index b0aa594f..968d6c88 100644 --- a/assets/src/dashboard/parts/connected/dashboard/index.js +++ b/assets/src/dashboard/parts/connected/dashboard/index.js @@ -13,9 +13,9 @@ import { } from '@wordpress/components'; import { sprintf } from '@wordpress/i18n'; - +import { useMemo } from '@wordpress/element'; import { useSelect } from '@wordpress/data'; -import { warning, help } from '@wordpress/icons'; +import { warning, external, help } from '@wordpress/icons'; import { clearCache } from '../../../utils/api'; @@ -26,40 +26,25 @@ import { bolt, update, offloadImage, - settings + settings, + globe, + arrowDownToLine, + cloudDownload, + chartBarDecreasing } from '../../../utils/icons'; import ProgressBar from '../../components/ProgressBar'; -import DashboardMetricBox from '../../components/DashboardMetricBox'; import LastImages from './LastImages'; -import { useMemo } from 'react'; const cardClasses = 'flex p-6 bg-light-blue border border-blue-300 rounded-md'; -const metrics = [ - { - label: optimoleDashboardApp.strings.metrics.metricsTitle2, - description: optimoleDashboardApp.strings.metrics.metricsSubtitle2, - value: 'saved_size' - }, - { - label: optimoleDashboardApp.strings.metrics.metricsTitle3, - description: optimoleDashboardApp.strings.metrics.metricsSubtitle3, - value: 'compression_percentage' - }, - { - label: optimoleDashboardApp.strings.metrics.metricsTitle4, - description: optimoleDashboardApp.strings.metrics.metricsSubtitle4, - value: 'traffic' - } -]; - const settingsTab = { offload_image: 1, advance: 2 }; + const navigate = ( tabId ) => { const links = window.optimoleDashboardApp.submenu_links; const settingsLink = links.find( link => '#settings' === link.hash ); @@ -140,6 +125,50 @@ const Dashboard = () => { }; }); + const availableMetrics = useMemo( () => { + const metrics = [ + { + icon: arrowDownToLine, + label: optimoleDashboardApp.strings.metrics.metricsTitle2, + description: optimoleDashboardApp.strings.metrics.metricsSubtitle2, + value: 'saved_size', + hasButton: true, + buttonText: optimoleDashboardApp.strings.metrics.adjust_compression + }, + { + icon: chartBarDecreasing, + label: optimoleDashboardApp.strings.metrics.metricsTitle3, + description: optimoleDashboardApp.strings.metrics.metricsSubtitle3, + value: 'compression_percentage', + hasButton: true, + buttonText: optimoleDashboardApp.strings.metrics.adjust_compression + }, + { + icon: globe, + label: optimoleDashboardApp.strings.metrics.metricsTitle4, + description: optimoleDashboardApp.strings.metrics.metricsSubtitle4, + value: 'traffic', + hasButton: true, + buttonText: optimoleDashboardApp.strings.metrics.view_analytics + } + ]; + + if ( userData?.can_use_offloading ) { + metrics.push( + { + icon: cloudDownload, + label: optimoleDashboardApp.strings.metrics.metricsTitle5, + description: optimoleDashboardApp.strings.metrics.metricsSubtitle5, + value: 'offloaded_images', + hasButton: true, + buttonText: optimoleDashboardApp.strings.metrics.manage_offloading + } + ); + } + + return metrics; + }, [ userData ]); + const visitorsLimitPercent = ( ( userData.visitors / userData.visitors_limit ) * 100 ).toFixed( 0 ); const renewalDate = useMemo( () => { @@ -159,11 +188,15 @@ const Dashboard = () => { // Fallback for missing data if ( undefined === value ) { - value = 'saved_size' === type ? - Math.floor( Math.random() * 2500000 ) + 500000 : // Mock KB - 'traffic' === type ? - Math.floor( Math.random() * 2500 ) + 500 : // Mock MB - Math.floor( Math.random() * 40 ) + 10; // Mock Percentage + if ( 'saved_size' === type ) { + value = Math.floor( Math.random() * 2500000 ) + 500000; // Mock KB + } else if ( 'traffic' === type ) { + value = Math.floor( Math.random() * 2500 ) + 500; // Mock MB + } else if ( 'offloaded_images' === type ) { + value = Math.floor( Math.random() * 500 ) + 50; // Mock images count + } else { + value = Math.floor( Math.random() * 40 ) + 10; // Mock Percentage + } } switch ( type ) { @@ -196,6 +229,10 @@ const Dashboard = () => { unit = 'TB'; } break; + case 'offloaded_images': + formattedValue = parseInt( value ); + unit = 1 === formattedValue ? optimoleDashboardApp.strings.metrics.image : optimoleDashboardApp.strings.metrics.images; + break; default: formattedValue = parseFloat( value ).toFixed( 2 ); unit = ''; @@ -204,6 +241,19 @@ const Dashboard = () => { return { formattedValue, unit }; }; + const getMetricButtonAction = ( metricValue ) => { + switch ( metricValue ) { + case 'saved_size': + return { onClick: () => navigate( settingsTab.advance ) }; + case 'compression_percentage': + return { onClick: () => navigate( settingsTab.advance ) }; + case 'traffic': + return { href: window.optimoleDashboardApp.optimoleDashMetrics, target: '_blank' }; + case 'offloaded_images': + return { onClick: () => navigate( settingsTab.offload_image ) }; + } + }; + return (
@@ -285,9 +335,11 @@ const Dashboard = () => {
- { metrics.map( metric => { + { availableMetrics.map( metric => { const rawValue = userData[ metric.value ]; const { formattedValue, unit } = formatMetric( metric.value, rawValue ); + const buttonAction = getMetricButtonAction( metric.value ); + const showButton = 'free' !== userData.plan && metric.hasButton; return (
{ ) } >
-
- { metric.label } +
+ +
+ { metric.label } +
@@ -306,9 +361,23 @@ const Dashboard = () => { {unit}
-
+
{ metric.description }
+ + { showButton && ( + + ) }
); diff --git a/assets/src/dashboard/utils/icons.js b/assets/src/dashboard/utils/icons.js index 4520a328..82d1f3ad 100644 --- a/assets/src/dashboard/utils/icons.js +++ b/assets/src/dashboard/utils/icons.js @@ -174,3 +174,14 @@ export const user = ( ); +export const arrowDownToLine = ( + +); + +export const cloudDownload = ( + +); + +export const chartBarDecreasing = ( + +); diff --git a/assets/src/global.d.ts b/assets/src/global.d.ts index 5bdf096e..9dcacfbd 100644 --- a/assets/src/global.d.ts +++ b/assets/src/global.d.ts @@ -577,6 +577,7 @@ export interface UserData { is_cname_assigned: string extra_visits: boolean renews_on: number + can_use_offloading: boolean } export interface AvailableApp2 { diff --git a/inc/admin.php b/inc/admin.php index 0ad50566..18d6d420 100755 --- a/inc/admin.php +++ b/inc/admin.php @@ -1382,6 +1382,7 @@ private function localize_dashboard_app() { 'optimoleHome' => tsdk_translate_link( 'https://optimole.com/' ), 'optimoleDashHome' => tsdk_translate_link( 'https://dashboard.optimole.com/', 'query' ), 'optimoleDashBilling' => tsdk_translate_link( 'https://dashboard.optimole.com/settings/billing', 'query' ), + 'optimoleDashMetrics' => tsdk_translate_link( tsdk_utmify( 'https://dashboard.optimole.com/metrics', 'wp-plugin', 'shortcut' ) ), 'offload_upgrade_url' => tsdk_translate_link( tsdk_utmify( 'https://optimole.com/pricing/', 'offload' ) ), 'days_since_install' => round( ( time() - get_option( 'optimole_wp_install', 0 ) ) / DAY_IN_SECONDS ), 'is_offload_media_available' => $is_offload_media_available, @@ -1748,6 +1749,15 @@ private function get_dashboard_strings() { 'metricsSubtitle3' => __( 'Average Reduction', 'optimole-wp' ), 'metricsTitle4' => __( 'CDN Traffic', 'optimole-wp' ), 'metricsSubtitle4' => __( 'This month', 'optimole-wp' ), + 'metricsTitle5' => __( 'Offloaded images', 'optimole-wp' ), + 'metricsSubtitle5' => __( 'Offloaded to cloud', 'optimole-wp' ), + // translators: is used as singular when the number of images is 1 for a unit label. + 'image' => __( 'image', 'optimole-wp' ), + // translators: is used as plural when the number of images is more than 1 for a unit label. + 'images' => __( 'images', 'optimole-wp' ), + 'view_analytics' => __( 'View Analytics', 'optimole-wp' ), + 'adjust_compression' => __( 'Adjust Compression', 'optimole-wp' ), + 'manage_offloading' => __( 'Manage image offloading', 'optimole-wp' ), ], 'quick_actions' => [ 'speed_test_title' => __( 'Test Your Site Speed', 'optimole-wp' ), diff --git a/inc/v2/Offload/Loader.php b/inc/v2/Offload/Loader.php index e3f9e8b4..ac75e722 100644 --- a/inc/v2/Offload/Loader.php +++ b/inc/v2/Offload/Loader.php @@ -25,7 +25,7 @@ public function __construct() { * Adds filters to integrate the custom image editor into WordPress. */ public function register_hooks() { - if( has_filter( 'wp_image_editors', 'photon_subsizes_override_image_editors' )){ + if ( has_filter( 'wp_image_editors', 'photon_subsizes_override_image_editors' ) ) { return; } add_filter( 'wp_image_editors', [ $this, 'register_image_editor' ] );