Skip to content
133 changes: 101 additions & 32 deletions assets/src/dashboard/parts/connected/dashboard/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand All @@ -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 );
Expand Down Expand Up @@ -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( () => {
Expand All @@ -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 ) {
Expand Down Expand Up @@ -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 = '';
Expand All @@ -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 (
<div className="grid gap-5">
<div className="bg-white p-8 border-0 rounded-lg shadow-md">
Expand Down Expand Up @@ -285,9 +335,11 @@ const Dashboard = () => {
</div>

<div className="flex pt-5 gap-5 flex-col md:flex-row">
{ 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 (
<div
Expand All @@ -297,18 +349,35 @@ const Dashboard = () => {
) }
>
<div className="flex w-full flex-col">
<div className="text-sm text-gray-500">
{ metric.label }
<div className='flex flex-row items-center gap-2 mb-2'>
<Icon icon={ metric.icon } size={ 16 } className="text-info" />
<div className="text-sm text-gray-500">
{ metric.label }
</div>
</div>

<div className='flex items-end gap-1'>
<span className='text-2xl text-black font-bold'>{formattedValue}</span>
<span className='text-sm text-gray-500'>{unit}</span>
</div>

<div className="font-normal text-gray-600">
<div className={ `font-normal text-gray-600 ${ showButton ? 'mb-3' : '' }` }>
{ metric.description }
</div>

{ showButton && (
<Button
variant="secondary"
size="small"
className="mt-auto font-semibold rounded-md w-fit px-3 flex items-center gap-1"
{ ...buttonAction }
>
{ metric.buttonText }
{ ( 'traffic' === metric.value ) && (
<Icon icon={ external } size={ 16 } />
) }
</Button>
) }
</div>
</div>
);
Expand Down
11 changes: 11 additions & 0 deletions assets/src/dashboard/utils/icons.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions assets/src/global.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -577,6 +577,7 @@ export interface UserData {
is_cname_assigned: string
extra_visits: boolean
renews_on: number
can_use_offloading: boolean
}

export interface AvailableApp2 {
Expand Down
10 changes: 10 additions & 0 deletions inc/admin.php
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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' ),
Expand Down
2 changes: 1 addition & 1 deletion inc/v2/Offload/Loader.php
Original file line number Diff line number Diff line change
Expand Up @@ -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' ] );
Expand Down
Loading