@@ -13,16 +13,16 @@ import {
13
13
14
14
import { useSelect } from '@wordpress/data' ;
15
15
16
+ import { clearCache } from '../../../utils/api' ;
17
+
16
18
/**
17
19
* Internal dependencies.
18
20
*/
19
21
import {
20
- imagesNumber ,
21
- savedSize ,
22
- compressionPercentage ,
23
- traffic ,
24
- quota ,
25
- warning
22
+ bolt ,
23
+ update ,
24
+ offloadImage ,
25
+ settings
26
26
} from '../../../utils/icons' ;
27
27
28
28
import ProgressBar from '../../components/ProgressBar' ;
@@ -33,29 +33,67 @@ import LastImages from './LastImages';
33
33
const cardClasses = 'flex p-6 bg-light-blue border border-blue-300 rounded-md' ;
34
34
35
35
const metrics = [
36
- {
37
- label : optimoleDashboardApp . strings . metrics . metricsTitle1 ,
38
- description : optimoleDashboardApp . strings . metrics . metricsSubtitle1 ,
39
- value : 'images_number' ,
40
- icon : imagesNumber
41
- } ,
42
36
{
43
37
label : optimoleDashboardApp . strings . metrics . metricsTitle2 ,
44
38
description : optimoleDashboardApp . strings . metrics . metricsSubtitle2 ,
45
- value : 'saved_size' ,
46
- icon : savedSize
39
+ value : 'saved_size'
47
40
} ,
48
41
{
49
42
label : optimoleDashboardApp . strings . metrics . metricsTitle3 ,
50
43
description : optimoleDashboardApp . strings . metrics . metricsSubtitle3 ,
51
- value : 'compression_percentage' ,
52
- icon : compressionPercentage
44
+ value : 'compression_percentage'
53
45
} ,
54
46
{
55
47
label : optimoleDashboardApp . strings . metrics . metricsTitle4 ,
56
48
description : optimoleDashboardApp . strings . metrics . metricsSubtitle4 ,
57
- value : 'traffic' ,
58
- icon : traffic
49
+ value : 'traffic'
50
+ }
51
+ ] ;
52
+
53
+ const settingsTab = {
54
+ offload_image : 1 ,
55
+ advance : 2
56
+ } ;
57
+
58
+ const navigate = ( tabId ) => {
59
+ const links = window . optimoleDashboardApp . submenu_links ;
60
+ const settingsLink = links . find ( link => '#settings' === link . hash ) ;
61
+ if ( settingsLink ) {
62
+ const existingLink = document . querySelector ( `a[href="${ settingsLink . href } "]` ) ;
63
+ existingLink . click ( ) ;
64
+ setTimeout ( ( ) => {
65
+ const tabItems = document . querySelectorAll ( '.optml-settings ul li' ) ;
66
+ tabItems [ tabId ] ?. querySelector ( 'button' ) . click ( ) ;
67
+ window . scrollTo ( 0 , 0 ) ;
68
+ } , 500 ) ;
69
+ }
70
+ } ;
71
+
72
+ const quickactions = [
73
+ {
74
+ icon : < Icon icon = { bolt } className = "text-info" /> ,
75
+ title : optimoleDashboardApp . strings . quick_actions . speed_test_title ,
76
+ description : optimoleDashboardApp . strings . quick_actions . speed_test_desc ,
77
+ link : optimoleDashboardApp . strings . quick_actions . speed_test_link ,
78
+ value : 'speedTest'
79
+ } ,
80
+ {
81
+ icon : < Icon icon = { update } className = "text-info" /> ,
82
+ title : optimoleDashboardApp . strings . quick_actions . clear_cache_images ,
83
+ description : optimoleDashboardApp . strings . quick_actions . clear_cache ,
84
+ value : clearCache
85
+ } ,
86
+ {
87
+ icon : < Icon icon = { offloadImage } className = "text-info" /> ,
88
+ title : optimoleDashboardApp . strings . quick_actions . offload_images ,
89
+ description : optimoleDashboardApp . strings . quick_actions . offload_images_desc ,
90
+ value : ( ) => navigate ( settingsTab . offload_image )
91
+ } ,
92
+ {
93
+ icon : < Icon icon = { settings } className = "text-info" /> ,
94
+ title : optimoleDashboardApp . strings . quick_actions . advance_settings ,
95
+ description : optimoleDashboardApp . strings . quick_actions . configure_settings ,
96
+ value : ( ) => navigate ( settingsTab . advance )
59
97
}
60
98
] ;
61
99
@@ -109,97 +147,126 @@ const Dashboard = () => {
109
147
Math . floor ( Math . random ( ) * 40 ) + 10 ;
110
148
}
111
149
112
- // Format based on metric type
113
- if ( 'saved_size' === metric ) {
114
- return ( metricValue / 1000 ) . toFixed ( 2 ) + 'MB' ;
115
- }
116
-
117
- if ( 'compression_percentage' === metric ) {
118
- return metricValue . toFixed ( 2 ) + '%' ;
119
- }
120
-
121
- if ( 'traffic' === metric ) {
122
- return metricValue . toFixed ( 2 ) + 'MB' ;
123
- }
124
-
125
150
return metricValue ;
126
151
} ;
127
152
128
- return (
129
- < div className = "bg-white p-8 border-0 rounded-lg shadow-md" >
130
- { ( 0 < optimoleDashboardApp . strings . notice_just_activated . length && 'active' === userStatus ) && < ActivatedNotice /> }
153
+ const formatMetricValue = metric => {
154
+ const value = getFormattedMetric ( metric ) ;
155
+ const calcValue = 'saved_size' === metric ? ( value / 1000 ) . toFixed ( 2 ) : value . toFixed ( 2 ) ;
156
+ return (
157
+ < div className = 'flex items-end gap-1' >
158
+ < span className = 'text-2xl text-black font-bold' > { calcValue } </ span >
159
+ < span className = 'text-sm text-gray-500' > { 'compression_percentage' === metric ? '%' : 'MB' } </ span >
160
+ </ div >
161
+ ) ;
162
+ } ;
131
163
132
- { 'inactive' === userStatus && < InactiveWarning /> }
164
+ return (
165
+ < >
166
+ < div className = "bg-white p-8 border-0 rounded-lg shadow-md" >
167
+ { ( 0 < optimoleDashboardApp . strings . notice_just_activated . length && 'active' === userStatus ) && < ActivatedNotice /> }
133
168
134
- < div
135
- className = { classNames (
136
- cardClasses ,
137
- 'gap-8 flex-col sm:flex-row items-start sm:items-center'
138
- ) }
139
- >
140
- < Icon icon = { quota } />
169
+ { 'inactive' === userStatus && < InactiveWarning /> }
141
170
142
- < div className = "flex w-full flex-col" >
143
- < div className = " flex w-full justify-between" >
171
+ < div className = 'py-6 gap-6 flex-col sm:flex-row items-start sm:items-center' >
172
+ < div className = ' flex w-full justify-between sm:items-center' >
144
173
< div className = "text-gray-800 text-2xl font-bold" >
145
- { userData . visitors_pretty } / { userData . visitors_limit_pretty }
146
-
147
- < span className = "text-gray-600 text-base font-normal ml-2" >
174
+ { optimoleDashboardApp . strings . dashboard_title }
175
+ </ div >
176
+ < div className = "flex items-center gap-2" >
177
+ < div className = "text-gray-600 text-base font-normal ml-2" >
148
178
{ optimoleDashboardApp . strings . quota }
149
- </ span >
179
+ < span className = "pl-2 text-gray-800 font-bold" >
180
+ { userData . visitors_pretty } / { userData . visitors_limit_pretty }
181
+ </ span >
182
+ </ div >
183
+ < div className = 'w-20' >
184
+ < ProgressBar
185
+ value = { userData . visitors }
186
+ max = { userData . visitors_limit }
187
+ />
188
+ </ div >
189
+ < span > { visitorsLimitPercent } %</ span >
150
190
</ div >
151
-
152
- { ( 70 > visitorsLimitPercent ) && (
153
- < Button
154
- variant = "default"
155
- className = "optml__button rounded font-bold min-h-40"
156
- href = { optimoleDashboardApp . optimoleDashBilling }
157
- target = "_blank"
158
- >
159
- { optimoleDashboardApp . strings . upgrade . title }
160
- </ Button >
161
- ) }
162
191
</ div >
192
+ </ div >
163
193
194
+ < div
195
+ className = { classNames (
196
+ cardClasses ,
197
+ 'gap-8 flex-col sm:flex-row items-start sm:items-center'
198
+ ) }
199
+ >
164
200
< div >
165
- < ProgressBar
166
- className = "mt-2.5 mb-3 mx-0"
167
- value = { userData . visitors }
168
- max = { userData . visitors_limit }
169
- />
201
+ < div className = "text-gray-800 text-xl font-bold" >
202
+ { optimoleDashboardApp . strings . banner_title }
203
+ </ div >
204
+ < div className = "text-gray-600 text-base" >
205
+ { optimoleDashboardApp . strings . banner_description }
206
+ </ div >
207
+ </ div >
208
+ </ div >
209
+
210
+ < div className = "flex py-5 gap-5 flex-col md:flex-row" >
211
+ { metrics . map ( metric => {
212
+ return (
213
+ < div
214
+ key = { metric . value }
215
+ className = { classNames (
216
+ 'p-3 basis-1/3 flex-col items-start border rounded-md border-solid bg-white border-light-gray border-slate-400'
217
+ ) }
218
+ >
219
+ < div className = "flex w-full flex-col" >
220
+ < div className = "not-italic font-normal text-sm text-gray-500" >
221
+ { metric . label }
222
+ </ div >
223
+
224
+ < div >
225
+ { formatMetricValue ( metric . value ) }
226
+ </ div >
170
227
228
+ < div className = "font-normal text-sm text-gray-600" >
229
+ { metric . description }
230
+ </ div >
231
+ </ div >
232
+ </ div >
233
+ ) ;
234
+ } ) }
235
+ </ div >
236
+ </ div >
237
+ < div className = "my-3 bg-white p-8 border-0 rounded-lg shadow-md" >
238
+ < div className = "text-gray-800 font-bold text-2xl" > { optimoleDashboardApp . strings . quick_action_title } </ div >
239
+ < div className = "grid grid-cols-1 md:grid-cols-2 gap-5 py-5" >
240
+ { quickactions . map ( ( action , index ) => (
171
241
< div
172
- className = "optml__tooltip"
173
- style = { {
174
- left : visitorsLimitPercent + '%' ,
175
- marginLeft : 15 > visitorsLimitPercent ? '-15px' : '-20px' ,
176
- display : 100 < visitorsLimitPercent ? 'none' : 'block'
177
- } }
242
+ key = { index }
243
+ className = "flex items-start items-center gap-3 p-4 bg-gray-100 rounded-lg hover:bg-gray-200 transition-colors"
178
244
>
179
- < span > { visitorsLimitPercent } %</ span >
245
+ { action . icon }
246
+ < div className = "flex flex-col" >
247
+ < span className = "font-medium text-base text-gray-800" > { action . title } </ span >
248
+ { 'speedTest' === action . value ? (
249
+ < a href = { action . link } target = "_blank" className = "text-info text-sm font-medium hover:text-info" > { action . description } </ a >
250
+ ) : (
251
+ < Button
252
+ variant = "default"
253
+ className = "text-info text-sm font-medium p-0 h-5 focus:!shadow-none focus:!outline-none"
254
+ onClick = { ( ) => action . value ( ) }
255
+ >
256
+ { action . description }
257
+ </ Button >
258
+ ) }
259
+ </ div >
180
260
</ div >
181
- </ div >
261
+ ) ) }
182
262
</ div >
183
263
</ div >
184
-
185
- < div className = "flex py-5 gap-5 flex-col md:flex-row" >
186
- { metrics . map ( metric => {
187
- return (
188
- < DashboardMetricBox
189
- key = { metric . value }
190
- value = { getFormattedMetric ( metric . value ) }
191
- label = { metric . label }
192
- description = { metric . description }
193
- icon = { metric . icon }
194
- />
195
- ) ;
196
- } ) }
264
+ < div className = "bg-white p-8 border-0 rounded-lg shadow-md" >
265
+ { 'yes' !== optimoleDashboardApp . remove_latest_images && (
266
+ < LastImages />
267
+ ) }
197
268
</ div >
198
-
199
- { 'yes' !== optimoleDashboardApp . remove_latest_images && (
200
- < LastImages />
201
- ) }
202
- </ div >
269
+ </ >
203
270
) ;
204
271
} ;
205
272
0 commit comments