Repository: Codeinwp/optimole-wp
Pull request #898: Add optimizaiton tips in sidebar
Author: login: girishpanchal30
Labels: name: released
description: Indicate that an issue has been resolved and released in a particular version of the product.
Created: 2025-03-21T07:04:12Z | Merged: 2025-03-24T18:11:47Z

### All Submissions:

* [x] Have you followed the [Optimole Contributing guideline](https://github.com/Codeinwp/optimole-wp/blob/master/CONTRIBUTING.md)?
* [x] Does your code follow the [WordPress' coding standards](https://make.wordpress.org/core/handbook/best-practices/coding-standards/)?
* [x] Have you checked to ensure there aren't other open [Pull Requests](../../pulls) for the same update/change? 
 

### Changes proposed in this Pull Request:
Add new sidebar box.
 

Closes https://github.com/Codeinwp/optimole-service/issues/1347

### How to test the changes in this Pull Request:

### Other information:

* [x] Have you added an explanation of what your changes do and why you'd like us to include them?
* [x] Have you written new tests for your changes, as applicable?
* [x] Have you successfully ran tests with your changes locally?
 



Diff:
diff --git a/assets/src/dashboard/parts/connected/OptimizationStatus.js b/assets/src/dashboard/parts/connected/OptimizationStatus.js
new file mode 100644
index 000000000..1453280b6
--- /dev/null
+++ b/assets/src/dashboard/parts/connected/OptimizationStatus.js
@@ -0,0 +1,69 @@
+/**
+ * WordPress dependencies.
+ */
+import { Icon } from '@wordpress/components';
+import { closeSmall, check } from '@wordpress/icons';
+
+import { useSelect } from '@wordpress/data';
+
+const OptimizationStatus = () => {
+	const statuses = useSelect( select => {
+		const { getSiteSettings } = select( 'optimole' );
+		const siteSettings = getSiteSettings();
+		return [
+			{
+				active: 'enabled' === siteSettings?.image_replacer,
+				label: optimoleDashboardApp.strings.optimization_status.statusTitle1,
+				description: optimoleDashboardApp.strings.optimization_status.statusSubTitle1
+			},
+			{
+				active: 'enabled' === siteSettings?.lazyload,
+				label: optimoleDashboardApp.strings.optimization_status.statusTitle2,
+				description: optimoleDashboardApp.strings.optimization_status.statusSubTitle2
+			},
+			{
+				active: 'disabled' === siteSettings?.scale,
+				label: optimoleDashboardApp.strings.optimization_status.statusTitle3,
+				description: optimoleDashboardApp.strings.optimization_status.statusSubTitle3
+			}
+		];
+	});
+
+	return (
+		<div className="bg-white flex flex-col text-gray-700 border-0 rounded-lg shadow-md p-8">
+			<h3 className="text-base m-0">{ optimoleDashboardApp.strings.optimization_status.title }</h3>
+			<ul>
+				{ statuses.map( ( status, index ) => {
+					let statusClass = status.active ? 'success' : 'danger';
+					return (
+						<li
+							key={ index }
+							className="flex items-start gap-2"
+						>
+							{ status.active ? (
+								<Icon icon={check} className="fill-success bg-success/20 rounded-full" size={20} />
+							) : (
+								<Icon icon={closeSmall} className="fill-danger bg-danger/20 rounded-full" size={20} />
+							) }
+
+							<div>
+								<span className='text-gray-700 font-normal font-semibold'>
+									{ status.label }
+								</span>
+								<p className="m-0">{ status.description }</p>
+							</div>
+						</li>
+					);
+				}) }
+			</ul>
+			<p
+				className="m-0 mt-3"
+				dangerouslySetInnerHTML={ {
+					__html: optimoleDashboardApp.strings.optimization_tips
+				} }
+			/>
+		</div>
+	);
+};
+
+export default OptimizationStatus;
diff --git a/assets/src/dashboard/parts/connected/Sidebar.js b/assets/src/dashboard/parts/connected/Sidebar.js
index 4f67618cb..d8a8359fb 100644
--- a/assets/src/dashboard/parts/connected/Sidebar.js
+++ b/assets/src/dashboard/parts/connected/Sidebar.js
@@ -12,6 +12,8 @@ import { useSelect } from '@wordpress/data';
 import { addQueryArgs } from '@wordpress/url';
 
 import SPCRecommendation from './SPCRecommendation';
+import OptimizationStatus from './OptimizationStatus';
+
 const reasons = [
 	optimoleDashboardApp.strings.upgrade.reason_1,
 	optimoleDashboardApp.strings.upgrade.reason_2,
@@ -125,6 +127,8 @@ const Sidebar = () => {
 				</Button>
 			) }
 
+			<OptimizationStatus />
+
 			{ showSPCRecommendation && (
 				<SPCRecommendation />
 			) }
diff --git a/inc/admin.php b/inc/admin.php
index 625e3fc1d..8bdf076df 100755
--- a/inc/admin.php
+++ b/inc/admin.php
@@ -2073,6 +2073,21 @@ private function get_dashboard_strings() {
 			],
 			'cron_error'                     => sprintf( /* translators: 1 is code to disable cron, 2 value of the constant */ __( 'It seems that you have the %1$s constant defined as %2$s. The offloading process uses cron events to offload the images in the background. Please remove the constant from your wp-config.php file in order for the offloading process to work.', 'optimole-wp' ), '<code>DISABLE_WP_CRON</code>', '<code>true</code>' ),
 			'cancel'                         => __( 'Cancel', 'optimole-wp' ),
+			'optimization_status'            => [
+				'title'           => __( 'Optimization Status', 'optimole-wp' ),
+				'statusTitle1'    => __( 'Image Handling', 'optimole-wp' ),
+				'statusSubTitle1' => __( 'All images are optimized automatically', 'optimole-wp' ),
+				'statusTitle2'    => __( 'Smart Lazy-Loading', 'optimole-wp' ),
+				'statusSubTitle2' => __( 'Images load as visitors scroll', 'optimole-wp' ),
+				'statusTitle3'    => __( 'Image Scalling', 'optimole-wp' ),
+				'statusSubTitle3' => __( 'All images are perfectly sized for devices', 'optimole-wp' ),
+			],
+			'optimization_tips'              => sprintf(
+			/* translators: 1 is the opening anchor tag, 2 is the closing anchor tag */
+				__( '%1$sView all optimization tips%2$s', 'optimole-wp' ),
+				'<a class="flex justify-center font-bold rounded hover:opacity-90 transition-opacity" href="https://docs.optimole.com/article/2238-optimization-tips" target="_blank"> ',
+				'<span style="text-decoration:none; font-size:15px; margin-top:2px;" class="dashicons dashicons-external"></span></a>'
+			),
 		];
 	}
 


Reviews:
user: login: abaicus
body: @girishpanchal30 I left some comments on the issue. Let's keep consistent sizing between the SPC recommendation list / heading, and this new box in the sidebar.

Other than that I've also asked @vytisbulkevicius for some input on how the checkboxes should behave.

Thank you!
state: CHANGES_REQUESTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-24T09:03:49Z
user: login: abaicus
body: @girishpanchal30 besides what I mentioned, things look good. 

Let's wait for @vytisbulkevicius's input and see how we further update this. 

Thank you! 👍🏻 
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-24T12:06:01Z
user: login: girishpanchal30
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-24T12:28:59Z
user: login: girishpanchal30
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-24T12:31:37Z
user: login: abaicus
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-24T12:33:26Z
user: login: abaicus
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-24T12:36:15Z
user: login: vytisbulkevicius
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-24T12:37:14Z
user: login: abaicus
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-24T12:38:39Z
user: login: girishpanchal30
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-24T12:42:09Z
user: login: girishpanchal30
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-24T12:47:05Z
user: login: abaicus
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-24T12:48:01Z
user: login: girishpanchal30
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-24T12:57:32Z
user: login: abaicus
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-24T13:03:41Z
user: login: abaicus
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-03-24T13:03:55Z

Review comments:
diff_hunk: @@ -0,0 +1,77 @@
+/**
+ * WordPress dependencies.
+ */
+import { Icon } from '@wordpress/components';
+import { closeSmall, check } from '@wordpress/icons';
+
+import { useSelect } from '@wordpress/data';
+
+const OptimizationStatus = () => {
+	const {
+		statuses
+	} = useSelect( select => {
+		const { getSiteSettings } = select( 'optimole' );
+
+		const siteSettings = getSiteSettings();
+
+		const statuses = [
+			{
+				active: 'enabled' === siteSettings?.image_replacer,
+				label: optimoleDashboardApp.strings.optimization_status.statusTitle1,
+				description: optimoleDashboardApp.strings.optimization_status.statusSubTitle1
+			},
+			{
+				active: 'enabled' === siteSettings?.lazyload,
+				label: optimoleDashboardApp.strings.optimization_status.statusTitle2,
+				description: optimoleDashboardApp.strings.optimization_status.statusSubTitle2
+			},
+			{
+				active: 'enabled' === siteSettings?.scale,
+				label: optimoleDashboardApp.strings.optimization_status.statusTitle3,
+				description: optimoleDashboardApp.strings.optimization_status.statusSubTitle3
+			}
+		];
+
+		return {
+			statuses: statuses
+		};
+	});
path: assets/src/dashboard/parts/connected/OptimizationStatus.js
user: login: abaicus
body: > [!IMPORTANT]
> It seems that the `scale` settings is somehow inverted. So we have to check if it's `disabled` instead of `enabled`. 
> I don't recall exactly what happened here, but it's probably some backwards compatibility.

--- 

@vytisbulkevicius Here when we toggle the respective settings, the sidebar widget is **not** updated unless you save the settings. I think this might be confusing to users.

Also I think having them as red, without any indication what setting the user should change to make them all green might be frustrating and require the user to dive into the settings.

Do you think we should have them real-time updated? 

@girishpanchal30 if @vytisbulkevicius agrees that they should be toggled with the settings value, instead of on save, we should pass the setting props through the component tree from [here](https://github.com/Codeinwp/optimole-wp/blob/eaae2096c4cf7123752e8683a9454a5313d26f71/assets/src/dashboard/parts/connected/index.js#L98), and make sure we keep things in sync as they are updated. 

Otherwise, there is no need for destructuring and returning an object here:

```suggestion
	const statuses = useSelect( select => {
		const { getSiteSettings } = select( 'optimole' );

		const siteSettings = getSiteSettings();

		return [
			{
				active: 'enabled' === siteSettings?.image_replacer,
				label: optimoleDashboardApp.strings.optimization_status.statusTitle1,
				description: optimoleDashboardApp.strings.optimization_status.statusSubTitle1
			},
			{
				active: 'enabled' === siteSettings?.lazyload,
				label: optimoleDashboardApp.strings.optimization_status.statusTitle2,
				description: optimoleDashboardApp.strings.optimization_status.statusSubTitle2
			},
			{
			    // 👇🏻 We should make sure to change this 👇🏻 
				active: 'disabled' === siteSettings?.scale,
				label: optimoleDashboardApp.strings.optimization_status.statusTitle3,
				description: optimoleDashboardApp.strings.optimization_status.statusSubTitle3
			}
		];
	});
```
created_at: 2025-03-24T12:00:26Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,77 @@
+/**
+ * WordPress dependencies.
+ */
+import { Icon } from '@wordpress/components';
+import { closeSmall, check } from '@wordpress/icons';
+
+import { useSelect } from '@wordpress/data';
+
+const OptimizationStatus = () => {
+	const {
+		statuses
+	} = useSelect( select => {
+		const { getSiteSettings } = select( 'optimole' );
+
+		const siteSettings = getSiteSettings();
+
+		const statuses = [
+			{
+				active: 'enabled' === siteSettings?.image_replacer,
+				label: optimoleDashboardApp.strings.optimization_status.statusTitle1,
+				description: optimoleDashboardApp.strings.optimization_status.statusSubTitle1
+			},
+			{
+				active: 'enabled' === siteSettings?.lazyload,
+				label: optimoleDashboardApp.strings.optimization_status.statusTitle2,
+				description: optimoleDashboardApp.strings.optimization_status.statusSubTitle2
+			},
+			{
+				active: 'enabled' === siteSettings?.scale,
+				label: optimoleDashboardApp.strings.optimization_status.statusTitle3,
+				description: optimoleDashboardApp.strings.optimization_status.statusSubTitle3
+			}
+		];
+
+		return {
+			statuses: statuses
+		};
+	});
path: assets/src/dashboard/parts/connected/OptimizationStatus.js
user: login: girishpanchal30
body: > It seems that the scale settings is somehow inverted. So we have to check if it's disabled instead of enabled.

@abaicus The scale tip will toggle based on the screencast settings below. Do you think we should change it to `disabled`?  

For backward compatibility, I believe we should check if `disabled !== scale`. What are your thoughts?

![image](https://github.com/user-attachments/assets/ebaf94c9-dc29-4189-a953-b21bc7370e63)

created_at: 2025-03-24T12:28:59Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,77 @@
+/**
+ * WordPress dependencies.
+ */
+import { Icon } from '@wordpress/components';
+import { closeSmall, check } from '@wordpress/icons';
+
+import { useSelect } from '@wordpress/data';
+
+const OptimizationStatus = () => {
+	const {
+		statuses
+	} = useSelect( select => {
+		const { getSiteSettings } = select( 'optimole' );
+
+		const siteSettings = getSiteSettings();
+
+		const statuses = [
+			{
+				active: 'enabled' === siteSettings?.image_replacer,
+				label: optimoleDashboardApp.strings.optimization_status.statusTitle1,
+				description: optimoleDashboardApp.strings.optimization_status.statusSubTitle1
+			},
+			{
+				active: 'enabled' === siteSettings?.lazyload,
+				label: optimoleDashboardApp.strings.optimization_status.statusTitle2,
+				description: optimoleDashboardApp.strings.optimization_status.statusSubTitle2
+			},
+			{
+				active: 'enabled' === siteSettings?.scale,
+				label: optimoleDashboardApp.strings.optimization_status.statusTitle3,
+				description: optimoleDashboardApp.strings.optimization_status.statusSubTitle3
+			}
+		];
+
+		return {
+			statuses: statuses
+		};
+	});
path: assets/src/dashboard/parts/connected/OptimizationStatus.js
user: login: girishpanchal30
body: I noticed that `'disabled' !==` is used in other parts of the code as well -  https://github.com/search?q=repo%3ACodeinwp%2Foptimole-wp%20%27disabled%27%20!%3D%3D&type=code
created_at: 2025-03-24T12:31:37Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,77 @@
+/**
+ * WordPress dependencies.
+ */
+import { Icon } from '@wordpress/components';
+import { closeSmall, check } from '@wordpress/icons';
+
+import { useSelect } from '@wordpress/data';
+
+const OptimizationStatus = () => {
+	const {
+		statuses
+	} = useSelect( select => {
+		const { getSiteSettings } = select( 'optimole' );
+
+		const siteSettings = getSiteSettings();
+
+		const statuses = [
+			{
+				active: 'enabled' === siteSettings?.image_replacer,
+				label: optimoleDashboardApp.strings.optimization_status.statusTitle1,
+				description: optimoleDashboardApp.strings.optimization_status.statusSubTitle1
+			},
+			{
+				active: 'enabled' === siteSettings?.lazyload,
+				label: optimoleDashboardApp.strings.optimization_status.statusTitle2,
+				description: optimoleDashboardApp.strings.optimization_status.statusSubTitle2
+			},
+			{
+				active: 'enabled' === siteSettings?.scale,
+				label: optimoleDashboardApp.strings.optimization_status.statusTitle3,
+				description: optimoleDashboardApp.strings.optimization_status.statusSubTitle3
+			}
+		];
+
+		return {
+			statuses: statuses
+		};
+	});
path: assets/src/dashboard/parts/connected/OptimizationStatus.js
user: login: abaicus
body: For `scale` it is always checked the other way around: 

https://github.com/Codeinwp/optimole-wp/blob/eaae2096c4cf7123752e8683a9454a5313d26f71/assets/src/dashboard/parts/connected/settings/Lazyload.js#L39

https://github.com/Codeinwp/optimole-wp/blob/eaae2096c4cf7123752e8683a9454a5313d26f71/inc/admin.php#L562


created_at: 2025-03-24T12:33:26Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,77 @@
+/**
+ * WordPress dependencies.
+ */
+import { Icon } from '@wordpress/components';
+import { closeSmall, check } from '@wordpress/icons';
+
+import { useSelect } from '@wordpress/data';
+
+const OptimizationStatus = () => {
+	const {
+		statuses
+	} = useSelect( select => {
+		const { getSiteSettings } = select( 'optimole' );
+
+		const siteSettings = getSiteSettings();
+
+		const statuses = [
+			{
+				active: 'enabled' === siteSettings?.image_replacer,
+				label: optimoleDashboardApp.strings.optimization_status.statusTitle1,
+				description: optimoleDashboardApp.strings.optimization_status.statusSubTitle1
+			},
+			{
+				active: 'enabled' === siteSettings?.lazyload,
+				label: optimoleDashboardApp.strings.optimization_status.statusTitle2,
+				description: optimoleDashboardApp.strings.optimization_status.statusSubTitle2
+			},
+			{
+				active: 'enabled' === siteSettings?.scale,
+				label: optimoleDashboardApp.strings.optimization_status.statusTitle3,
+				description: optimoleDashboardApp.strings.optimization_status.statusSubTitle3
+			}
+		];
+
+		return {
+			statuses: statuses
+		};
+	});
path: assets/src/dashboard/parts/connected/OptimizationStatus.js
user: login: abaicus
body: Does the optimization stat for `scaling` stay as green when the toggle is set to enabled for you and the setting is set to enabled with the current version on this branch?
created_at: 2025-03-24T12:36:15Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,77 @@
+/**
+ * WordPress dependencies.
+ */
+import { Icon } from '@wordpress/components';
+import { closeSmall, check } from '@wordpress/icons';
+
+import { useSelect } from '@wordpress/data';
+
+const OptimizationStatus = () => {
+	const {
+		statuses
+	} = useSelect( select => {
+		const { getSiteSettings } = select( 'optimole' );
+
+		const siteSettings = getSiteSettings();
+
+		const statuses = [
+			{
+				active: 'enabled' === siteSettings?.image_replacer,
+				label: optimoleDashboardApp.strings.optimization_status.statusTitle1,
+				description: optimoleDashboardApp.strings.optimization_status.statusSubTitle1
+			},
+			{
+				active: 'enabled' === siteSettings?.lazyload,
+				label: optimoleDashboardApp.strings.optimization_status.statusTitle2,
+				description: optimoleDashboardApp.strings.optimization_status.statusSubTitle2
+			},
+			{
+				active: 'enabled' === siteSettings?.scale,
+				label: optimoleDashboardApp.strings.optimization_status.statusTitle3,
+				description: optimoleDashboardApp.strings.optimization_status.statusSubTitle3
+			}
+		];
+
+		return {
+			statuses: statuses
+		};
+	});
path: assets/src/dashboard/parts/connected/OptimizationStatus.js
user: login: vytisbulkevicius
body: @abaicus, @girishpanchal30 

> Here when we toggle the respective settings, the sidebar widget is not updated unless you save the settings. I think this might be confusing to users.

I don't think this is a problem. For a feature to work you need to save it so only enabling and changing the status could be even more confusing that you already enabled it and don't need to save the settings anymore. So IMO it's fine and we can keep it this way.

created_at: 2025-03-24T12:37:14Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,77 @@
+/**
+ * WordPress dependencies.
+ */
+import { Icon } from '@wordpress/components';
+import { closeSmall, check } from '@wordpress/icons';
+
+import { useSelect } from '@wordpress/data';
+
+const OptimizationStatus = () => {
+	const {
+		statuses
+	} = useSelect( select => {
+		const { getSiteSettings } = select( 'optimole' );
+
+		const siteSettings = getSiteSettings();
+
+		const statuses = [
+			{
+				active: 'enabled' === siteSettings?.image_replacer,
+				label: optimoleDashboardApp.strings.optimization_status.statusTitle1,
+				description: optimoleDashboardApp.strings.optimization_status.statusSubTitle1
+			},
+			{
+				active: 'enabled' === siteSettings?.lazyload,
+				label: optimoleDashboardApp.strings.optimization_status.statusTitle2,
+				description: optimoleDashboardApp.strings.optimization_status.statusSubTitle2
+			},
+			{
+				active: 'enabled' === siteSettings?.scale,
+				label: optimoleDashboardApp.strings.optimization_status.statusTitle3,
+				description: optimoleDashboardApp.strings.optimization_status.statusSubTitle3
+			}
+		];
+
+		return {
+			statuses: statuses
+		};
+	});
path: assets/src/dashboard/parts/connected/OptimizationStatus.js
user: login: abaicus
body: @vytisbulkevicius thanks for confirming 👍🏻 

@girishpanchal30 we can go ahead with the store values in this case 👍🏻 
created_at: 2025-03-24T12:38:39Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,77 @@
+/**
+ * WordPress dependencies.
+ */
+import { Icon } from '@wordpress/components';
+import { closeSmall, check } from '@wordpress/icons';
+
+import { useSelect } from '@wordpress/data';
+
+const OptimizationStatus = () => {
+	const {
+		statuses
+	} = useSelect( select => {
+		const { getSiteSettings } = select( 'optimole' );
+
+		const siteSettings = getSiteSettings();
+
+		const statuses = [
+			{
+				active: 'enabled' === siteSettings?.image_replacer,
+				label: optimoleDashboardApp.strings.optimization_status.statusTitle1,
+				description: optimoleDashboardApp.strings.optimization_status.statusSubTitle1
+			},
+			{
+				active: 'enabled' === siteSettings?.lazyload,
+				label: optimoleDashboardApp.strings.optimization_status.statusTitle2,
+				description: optimoleDashboardApp.strings.optimization_status.statusSubTitle2
+			},
+			{
+				active: 'enabled' === siteSettings?.scale,
+				label: optimoleDashboardApp.strings.optimization_status.statusTitle3,
+				description: optimoleDashboardApp.strings.optimization_status.statusSubTitle3
+			}
+		];
+
+		return {
+			statuses: statuses
+		};
+	});
path: assets/src/dashboard/parts/connected/OptimizationStatus.js
user: login: girishpanchal30
body: @abaicus Thanks! I've updated the condition in the latest commit.
created_at: 2025-03-24T12:42:09Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,77 @@
+/**
+ * WordPress dependencies.
+ */
+import { Icon } from '@wordpress/components';
+import { closeSmall, check } from '@wordpress/icons';
+
+import { useSelect } from '@wordpress/data';
+
+const OptimizationStatus = () => {
+	const {
+		statuses
+	} = useSelect( select => {
+		const { getSiteSettings } = select( 'optimole' );
+
+		const siteSettings = getSiteSettings();
+
+		const statuses = [
+			{
+				active: 'enabled' === siteSettings?.image_replacer,
+				label: optimoleDashboardApp.strings.optimization_status.statusTitle1,
+				description: optimoleDashboardApp.strings.optimization_status.statusSubTitle1
+			},
+			{
+				active: 'enabled' === siteSettings?.lazyload,
+				label: optimoleDashboardApp.strings.optimization_status.statusTitle2,
+				description: optimoleDashboardApp.strings.optimization_status.statusSubTitle2
+			},
+			{
+				active: 'enabled' === siteSettings?.scale,
+				label: optimoleDashboardApp.strings.optimization_status.statusTitle3,
+				description: optimoleDashboardApp.strings.optimization_status.statusSubTitle3
+			}
+		];
+
+		return {
+			statuses: statuses
+		};
+	});
path: assets/src/dashboard/parts/connected/OptimizationStatus.js
user: login: girishpanchal30
body: @abaicus Should I mark this as resolved?
created_at: 2025-03-24T12:47:05Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,77 @@
+/**
+ * WordPress dependencies.
+ */
+import { Icon } from '@wordpress/components';
+import { closeSmall, check } from '@wordpress/icons';
+
+import { useSelect } from '@wordpress/data';
+
+const OptimizationStatus = () => {
+	const {
+		statuses
+	} = useSelect( select => {
+		const { getSiteSettings } = select( 'optimole' );
+
+		const siteSettings = getSiteSettings();
+
+		const statuses = [
+			{
+				active: 'enabled' === siteSettings?.image_replacer,
+				label: optimoleDashboardApp.strings.optimization_status.statusTitle1,
+				description: optimoleDashboardApp.strings.optimization_status.statusSubTitle1
+			},
+			{
+				active: 'enabled' === siteSettings?.lazyload,
+				label: optimoleDashboardApp.strings.optimization_status.statusTitle2,
+				description: optimoleDashboardApp.strings.optimization_status.statusSubTitle2
+			},
+			{
+				active: 'enabled' === siteSettings?.scale,
+				label: optimoleDashboardApp.strings.optimization_status.statusTitle3,
+				description: optimoleDashboardApp.strings.optimization_status.statusSubTitle3
+			}
+		];
+
+		return {
+			statuses: statuses
+		};
+	});
path: assets/src/dashboard/parts/connected/OptimizationStatus.js
user: login: abaicus
body: Can you also update the destructuring please, like i mentioned in the initial comment?
created_at: 2025-03-24T12:48:01Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,77 @@
+/**
+ * WordPress dependencies.
+ */
+import { Icon } from '@wordpress/components';
+import { closeSmall, check } from '@wordpress/icons';
+
+import { useSelect } from '@wordpress/data';
+
+const OptimizationStatus = () => {
+	const {
+		statuses
+	} = useSelect( select => {
+		const { getSiteSettings } = select( 'optimole' );
+
+		const siteSettings = getSiteSettings();
+
+		const statuses = [
+			{
+				active: 'enabled' === siteSettings?.image_replacer,
+				label: optimoleDashboardApp.strings.optimization_status.statusTitle1,
+				description: optimoleDashboardApp.strings.optimization_status.statusSubTitle1
+			},
+			{
+				active: 'enabled' === siteSettings?.lazyload,
+				label: optimoleDashboardApp.strings.optimization_status.statusTitle2,
+				description: optimoleDashboardApp.strings.optimization_status.statusSubTitle2
+			},
+			{
+				active: 'enabled' === siteSettings?.scale,
+				label: optimoleDashboardApp.strings.optimization_status.statusTitle3,
+				description: optimoleDashboardApp.strings.optimization_status.statusSubTitle3
+			}
+		];
+
+		return {
+			statuses: statuses
+		};
+	});
path: assets/src/dashboard/parts/connected/OptimizationStatus.js
user: login: girishpanchal30
body: @abaicus Done as suggested!
created_at: 2025-03-24T12:57:32Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,77 @@
+/**
+ * WordPress dependencies.
+ */
+import { Icon } from '@wordpress/components';
+import { closeSmall, check } from '@wordpress/icons';
+
+import { useSelect } from '@wordpress/data';
+
+const OptimizationStatus = () => {
+	const {
+		statuses
+	} = useSelect( select => {
+		const { getSiteSettings } = select( 'optimole' );
+
+		const siteSettings = getSiteSettings();
+
+		const statuses = [
+			{
+				active: 'enabled' === siteSettings?.image_replacer,
+				label: optimoleDashboardApp.strings.optimization_status.statusTitle1,
+				description: optimoleDashboardApp.strings.optimization_status.statusSubTitle1
+			},
+			{
+				active: 'enabled' === siteSettings?.lazyload,
+				label: optimoleDashboardApp.strings.optimization_status.statusTitle2,
+				description: optimoleDashboardApp.strings.optimization_status.statusSubTitle2
+			},
+			{
+				active: 'enabled' === siteSettings?.scale,
+				label: optimoleDashboardApp.strings.optimization_status.statusTitle3,
+				description: optimoleDashboardApp.strings.optimization_status.statusSubTitle3
+			}
+		];
+
+		return {
+			statuses: statuses
+		};
+	});
path: assets/src/dashboard/parts/connected/OptimizationStatus.js
user: login: abaicus
body: Great! Thank you @girishpanchal30! 👍🏻 
created_at: 2025-03-24T13:03:41Z
author_association: CONTRIBUTOR

PR comments:
user: login: pirate-bot
created_at: 2025-03-21T07:05:49Z
body: Plugin build for c07eb3526cf4607c11487ee49906a76e7ab0a31e is ready :bellhop_bell:!
- Download [build](https://verti-artifacts.s3.amazonaws.com/optimole-wp-feat-opml-service-1347-1144ba0e/optimole-wp.zip)
- Download [dev](https://verti-artifacts.s3.amazonaws.com/optimole-wp-feat-opml-service-1347-1144ba0e/optimole-wp-dev.zip)
author_association: COLLABORATOR
user: login: girishpanchal30
created_at: 2025-03-24T09:59:58Z
body: @abaicus Any idea why `fill-danger bg-danger/20` isn't working on the SVG?
author_association: CONTRIBUTOR
user: login: girishpanchal30
created_at: 2025-03-24T10:37:38Z
body: @abaicus I've fixed the all feedbacks and now it look like below.

![image](https://github.com/user-attachments/assets/9d403ba3-56c3-4f80-8e87-02544a2aa6b7)

author_association: CONTRIBUTOR
user: login: pirate-bot
created_at: 2025-04-14T10:29:12Z
body: :tada: This PR is included in version 4.0.0 :tada:

The release is available on [GitHub release](https://github.com/Codeinwp/optimole-wp/releases/tag/v4.0.0)

Your **[semantic-release](https://github.com/semantic-release/semantic-release)** bot :package::rocket:
author_association: COLLABORATOR