PluginProbe
King Addons for Elementor – 80+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce, Mega Menu, Popup Builder / 51.1.83
King Addons for Elementor – 80+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce, Mega Menu, Popup Builder v51.1.83
51.1.83 51.1.82 51.1.81 51.1.79 51.1.78 51.1.77 51.1.76 51.1.74 51.1.75 51.1.65 51.1.64 51.1.63 trunk 51.1.14 51.1.2 51.1.35 51.1.36 51.1.37 51.1.38 51.1.39 51.1.44 51.1.45 51.1.46 51.1.47 51.1.49 All 37 releases
king-addons / includes / extensions / Image_Optimizer / templates / admin-page.php

admin-page.php in King Addons for Elementor – 80+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce, Mega Menu, Popup Builder 51.1.83, at includes/extensions/Image_Optimizer/templates/admin-page.php

681 lines 38.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Image Optimizer admin page template.
4 * Premium Apple-inspired design with dark/light theme support.
5 *
6 * @package King_Addons
7 */
8
9 if (!defined('ABSPATH')) {
10 exit;
11 }
12
13 use King_Addons\Image_Optimizer\Image_Optimizer;
14 use King_Addons\Image_Optimizer\Image_Optimizer_DB;
15
16 $optimizer = Image_Optimizer::instance();
17 $settings = $optimizer->get_settings();
18 $stats = $optimizer->get_global_stats();
19 $is_pro = $optimizer->is_pro();
20 $quota = !$is_pro ? $optimizer->get_free_quota_state() : null;
21 $upgrade_url = $optimizer->get_upgrade_url('kng-img-optimizer');
22 $savings = Image_Optimizer_DB::get_total_savings();
23 $format_counts = Image_Optimizer_DB::count_images_by_format();
24
25 // Theme mode (per-user)
26 $theme_mode = get_user_meta(get_current_user_id(), 'king_addons_theme_mode', true);
27 if (empty($theme_mode)) {
28 $theme_mode = get_option('king_addons_theme_mode', '');
29 }
30 $allowed_theme_modes = ['dark', 'light', 'auto'];
31 if (!in_array($theme_mode, $allowed_theme_modes, true)) {
32 $theme_mode = 'auto';
33 }
34
35 // Enqueue shared V3 styles
36 wp_enqueue_style(
37 'king-addons-admin-v3',
38 KING_ADDONS_URL . 'includes/admin/layouts/shared/admin-v3-styles.css',
39 [],
40 KING_ADDONS_VERSION
41 );
42 ?>
43 <script>
44 (function() {
45 document.body.classList.add('ka-admin-v3');
46 const mode = '<?php echo esc_js($theme_mode); ?>';
47 const mql = window.matchMedia ? window.matchMedia('(prefers-color-scheme: dark)') : null;
48 const isDark = mode === 'auto' ? !!(mql && mql.matches) : mode === 'dark';
49 document.documentElement.classList.toggle('ka-v3-dark', isDark);
50 document.body.classList.toggle('ka-v3-dark', isDark);
51 })();
52 </script>
53
54 <div class="ka-admin-wrap ka-img-opt-wrap">
55 <!-- Header -->
56 <div class="ka-admin-header">
57 <div class="ka-admin-header-left">
58 <div class="ka-admin-header-icon" style="background: linear-gradient(135deg, #5e5ce6 0%, #bf5af2 100%);">
59 <span class="dashicons dashicons-format-image"></span>
60 </div>
61 <div>
62 <h1 class="ka-admin-title"><?php esc_html_e('Image Optimizer', 'king-addons'); ?></h1>
63 <p class="ka-admin-subtitle"><?php esc_html_e('Optimize your images for faster page loads and better SEO.', 'king-addons'); ?></p>
64 </div>
65 </div>
66 <div class="ka-admin-header-actions">
67 <!-- Theme Toggle -->
68 <div class="ka-v3-segmented" id="ka-v3-theme-segment" role="radiogroup" aria-label="<?php echo esc_attr__('Theme', 'king-addons'); ?>" data-active="<?php echo esc_attr($theme_mode); ?>">
69 <span class="ka-v3-segmented-indicator" aria-hidden="true"></span>
70 <button type="button" class="ka-v3-segmented-btn" data-theme="light" aria-pressed="<?php echo $theme_mode === 'light' ? 'true' : 'false'; ?>">
71 <span class="ka-v3-segmented-icon" aria-hidden="true">☀︎</span>
72 <?php esc_html_e('Light', 'king-addons'); ?>
73 </button>
74 <button type="button" class="ka-v3-segmented-btn" data-theme="dark" aria-pressed="<?php echo $theme_mode === 'dark' ? 'true' : 'false'; ?>">
75 <span class="ka-v3-segmented-icon" aria-hidden="true"></span>
76 <?php esc_html_e('Dark', 'king-addons'); ?>
77 </button>
78 <button type="button" class="ka-v3-segmented-btn" data-theme="auto" aria-pressed="<?php echo $theme_mode === 'auto' ? 'true' : 'false'; ?>">
79 <span class="ka-v3-segmented-icon" aria-hidden="true"></span>
80 <?php esc_html_e('Auto', 'king-addons'); ?>
81 </button>
82 </div>
83
84 <?php if (!$is_pro && is_array($quota)) : ?>
85 <div class="ka-img-opt-quota" id="ka-img-opt-quota" aria-label="<?php echo esc_attr__('Free plan quota', 'king-addons'); ?>">
86 <div class="ka-img-opt-quota-text">
87 <div class="ka-img-opt-quota-title"><?php esc_html_e('Free Plan', 'king-addons'); ?></div>
88 <div class="ka-img-opt-quota-sub">
89 <span id="ka-img-opt-quota-remaining"><?php echo esc_html((string) ($quota['remaining'] ?? '0')); ?></span>
90 <?php echo esc_html__(' / ', 'king-addons'); ?>
91 <span id="ka-img-opt-quota-limit"><?php echo esc_html((string) ($quota['limit'] ?? '200')); ?></span>
92 <?php esc_html_e('left this month', 'king-addons'); ?>
93 </div>
94 </div>
95 <a class="ka-btn ka-btn-primary" id="ka-img-opt-upgrade" href="<?php echo esc_url($upgrade_url); ?>" target="_blank" rel="noopener noreferrer">
96 <?php esc_html_e('Upgrade to Unlimited', 'king-addons'); ?>
97 </a>
98 </div>
99 <?php endif; ?>
100 </div>
101 </div>
102
103 <!-- Navigation Tabs -->
104 <div class="ka-img-opt-tabs">
105 <button type="button" class="ka-img-opt-tab active" data-tab="bulk"><?php esc_html_e('Bulk Optimizer', 'king-addons'); ?></button>
106 <button type="button" class="ka-img-opt-tab" data-tab="settings"><?php esc_html_e('Settings', 'king-addons'); ?></button>
107 </div>
108
109 <!-- Statistics Cards -->
110 <div class="ka-img-opt-stats">
111 <div class="ka-img-opt-stat-card">
112 <div class="ka-img-opt-stat-icon purple">
113 <span class="dashicons dashicons-format-gallery"></span>
114 </div>
115 <div class="ka-img-opt-stat-content">
116 <span class="ka-img-opt-stat-value" id="stat-total"><?php echo esc_html(number_format_i18n($stats['total_images'])); ?></span>
117 <span class="ka-img-opt-stat-label"><?php esc_html_e('Total Images', 'king-addons'); ?></span>
118 </div>
119 </div>
120 <div class="ka-img-opt-stat-card">
121 <div class="ka-img-opt-stat-icon orange">
122 <span class="dashicons dashicons-clock"></span>
123 </div>
124 <div class="ka-img-opt-stat-content">
125 <span class="ka-img-opt-stat-value" id="stat-pending"><?php echo esc_html(number_format_i18n($stats['pending_images'] ?? max(0, $stats['total_images'] - $stats['optimized_images']))); ?></span>
126 <span class="ka-img-opt-stat-label"><?php esc_html_e('Pending', 'king-addons'); ?></span>
127 </div>
128 </div>
129 <div class="ka-img-opt-stat-card">
130 <div class="ka-img-opt-stat-icon grey">
131 <span class="dashicons dashicons-warning"></span>
132 </div>
133 <div class="ka-img-opt-stat-content">
134 <span class="ka-img-opt-stat-value" id="stat-failed"><?php echo esc_html(number_format_i18n($stats['failed_images'] ?? 0)); ?></span>
135 <span class="ka-img-opt-stat-label"><?php esc_html_e('Failed', 'king-addons'); ?></span>
136 </div>
137 </div>
138 <div class="ka-img-opt-stat-card large-card">
139 <div class="ka-img-opt-stat-icon blue">
140 <span class="dashicons dashicons-performance"></span>
141 </div>
142 <div class="ka-img-opt-stat-content">
143 <span class="ka-img-opt-stat-value" id="stat-saved"><?php echo esc_html(Image_Optimizer::format_bytes($savings['total_saved'])); ?></span>
144 <span class="ka-img-opt-stat-label"><?php esc_html_e('Space Saved', 'king-addons'); ?></span>
145 </div>
146 </div>
147 <div class="ka-img-opt-stat-card">
148 <div class="ka-img-opt-stat-icon green">
149 <span class="dashicons dashicons-yes-alt"></span>
150 </div>
151 <div class="ka-img-opt-stat-content">
152 <span class="ka-img-opt-stat-value" id="stat-optimized"><?php echo esc_html(number_format_i18n($stats['optimized_images'])); ?></span>
153 <span class="ka-img-opt-stat-label"><?php esc_html_e('Optimized', 'king-addons'); ?></span>
154 </div>
155 </div>
156 </div>
157
158 <!-- Tab Content: Bulk Optimizer -->
159 <div class="ka-img-opt-tab-content active" id="tab-bulk">
160
161 <!-- Resume Banner (hidden by default) -->
162 <div class="ka-img-opt-resume-banner" id="resume-banner" style="display: none;">
163 <button type="button" class="ka-img-opt-resume-close" id="resume-close">
164 <span class="dashicons dashicons-no-alt"></span>
165 </button>
166 <div class="ka-img-opt-resume-body">
167 <div class="ka-img-opt-resume-icon">
168 <span class="dashicons dashicons-backup"></span>
169 </div>
170 <div class="ka-img-opt-resume-content">
171 <h3><?php esc_html_e('Resume Optimization', 'king-addons'); ?></h3>
172 <p><?php esc_html_e('Continue your interrupted optimization session.', 'king-addons'); ?></p>
173 <div class="ka-img-opt-resume-progress">
174 <span id="resume-count">0 of 0</span> <?php esc_html_e('images processed', 'king-addons'); ?>
175 </div>
176 </div>
177 </div>
178 <div class="ka-img-opt-resume-actions">
179 <button type="button" id="resume-btn" class="ka-btn ka-btn-primary"><?php esc_html_e('Resume', 'king-addons'); ?></button>
180 <button type="button" id="discard-btn" class="ka-btn ka-btn-secondary"><?php esc_html_e('Start Over', 'king-addons'); ?></button>
181 </div>
182 </div>
183
184 <!-- Optimization Options -->
185 <div class="ka-card ka-img-opt-options" id="optimization-options">
186 <div class="ka-card-header">
187 <span class="dashicons dashicons-admin-settings"></span>
188 <h2><?php esc_html_e('Optimization Settings', 'king-addons'); ?></h2>
189 </div>
190 <div class="ka-card-body">
191 <div class="ka-img-opt-option-group">
192 <label class="ka-img-opt-option-label"><?php esc_html_e('Mode', 'king-addons'); ?></label>
193 <p class="ka-row-desc" style="margin: 0;"><?php esc_html_e('Bulk convert PNG and JPEG images to modern WebP format with compression and transparency support.', 'king-addons'); ?></p>
194 </div>
195
196 <!-- Quality Slider -->
197 <div class="ka-img-opt-option-group">
198 <label class="ka-img-opt-option-label"><?php esc_html_e('Quality', 'king-addons'); ?></label>
199 <div class="ka-img-opt-quality-presets">
200 <button type="button" class="ka-img-opt-preset-btn" data-quality="95"><?php esc_html_e('Maximum', 'king-addons'); ?></button>
201 <button type="button" class="ka-img-opt-preset-btn active" data-quality="82"><?php esc_html_e('Balanced', 'king-addons'); ?></button>
202 <button type="button" class="ka-img-opt-preset-btn" data-quality="65"><?php esc_html_e('Web Optimized', 'king-addons'); ?></button>
203 <button type="button" class="ka-img-opt-preset-btn" data-quality="45"><?php esc_html_e('Max Compression', 'king-addons'); ?></button>
204 </div>
205 <div class="ka-img-opt-slider-wrap">
206 <input type="range" id="quality-slider" min="1" max="100" value="<?php echo esc_attr($settings['quality']); ?>" class="ka-img-opt-slider">
207 <output id="quality-output"><?php echo esc_html($settings['quality']); ?>%</output>
208 </div>
209 </div>
210
211 <!-- Advanced Settings Toggle -->
212 <div class="ka-img-opt-advanced-toggle" id="advanced-toggle">
213 <span class="dashicons dashicons-admin-generic"></span>
214 <?php esc_html_e('Advanced Settings', 'king-addons'); ?>
215 <span class="dashicons dashicons-arrow-down-alt2"></span>
216 </div>
217
218 <!-- Advanced Settings Content -->
219 <div class="ka-img-opt-advanced-content" id="advanced-content" style="display: none;">
220 <!-- Skip Small Images -->
221 <div class="ka-row">
222 <div class="ka-row-label"><?php esc_html_e('Skip Small Images', 'king-addons'); ?></div>
223 <div class="ka-row-field">
224 <label class="ka-toggle">
225 <input type="checkbox" id="skip-small" <?php checked($settings['skip_small']); ?>>
226 <span class="ka-toggle-slider"></span>
227 </label>
228 <p class="ka-row-desc"><?php esc_html_e('Skip images smaller than 10KB (already optimized).', 'king-addons'); ?></p>
229 </div>
230 </div>
231
232 <!-- Auto Replace URLs -->
233 <div class="ka-row">
234 <div class="ka-row-label"><?php esc_html_e('Auto Replace URLs', 'king-addons'); ?></div>
235 <div class="ka-row-field">
236 <label class="ka-toggle">
237 <input type="checkbox" id="auto-replace-urls" <?php checked($settings['auto_replace_urls']); ?>>
238 <span class="ka-toggle-slider"></span>
239 </label>
240 <p class="ka-row-desc"><?php esc_html_e('Automatically update image URLs in content after optimization.', 'king-addons'); ?></p>
241 </div>
242 </div>
243
244 <!-- Resize Large Images -->
245 <div class="ka-row">
246 <div class="ka-row-label"><?php esc_html_e('Resize Large Images', 'king-addons'); ?></div>
247 <div class="ka-row-field">
248 <label class="ka-toggle">
249 <input type="checkbox" id="resize-enabled" <?php checked($settings['resize_enabled']); ?>>
250 <span class="ka-toggle-slider"></span>
251 </label>
252 <div class="ka-img-opt-resize-options" style="<?php echo $settings['resize_enabled'] ? '' : 'display:none;'; ?>">
253 <label><?php esc_html_e('Max width:', 'king-addons'); ?>
254 <input type="number" id="max-width" value="<?php echo esc_attr($settings['max_width']); ?>" min="100" max="5000"> px
255 </label>
256 </div>
257 </div>
258 </div>
259
260 </div>
261
262 <!-- Start Button -->
263 <div class="ka-img-opt-actions">
264 <button type="button" id="start-optimization" class="ka-btn ka-btn-primary ka-btn-lg">
265 <span class="dashicons dashicons-controls-play"></span>
266 <?php esc_html_e('Start Optimization', 'king-addons'); ?>
267 </button>
268 </div>
269 </div>
270 </div>
271
272 <!-- Progress Section (hidden by default) -->
273 <div class="ka-card ka-img-opt-progress" id="progress-section" style="display: none;">
274 <div class="ka-card-header">
275 <span class="spinner ka-img-opt-title-spinner" id="ka-opt-progress-spinner" aria-hidden="true"></span>
276 <span class="dashicons dashicons-yes-alt ka-img-opt-title-check" id="ka-opt-progress-check" aria-hidden="true" style="display:none;"></span>
277 <h2><?php esc_html_e('Optimization Progress', 'king-addons'); ?></h2>
278 </div>
279 <div class="ka-card-body">
280 <!-- Progress Bar -->
281 <div class="ka-img-opt-progress-bar">
282 <div class="ka-img-opt-progress-fill" id="progress-fill" style="width: 0%;"></div>
283 </div>
284 <div class="ka-img-opt-progress-info">
285 <span id="progress-percent">0%</span>
286 <span id="progress-count">0 / 0</span>
287 </div>
288
289 <!-- Current File -->
290 <div class="ka-img-opt-current-file" id="current-file">
291 <span class="dashicons dashicons-format-image"></span>
292 <span id="current-filename"><?php esc_html_e('Preparing...', 'king-addons'); ?></span>
293 </div>
294
295 <!-- Live Stats -->
296 <div class="ka-img-opt-live-stats">
297 <div class="ka-img-opt-live-stat">
298 <span class="ka-img-opt-live-stat-value" id="live-success">0</span>
299 <span class="ka-img-opt-live-stat-label"><?php esc_html_e('Optimized', 'king-addons'); ?></span>
300 </div>
301 <div class="ka-img-opt-live-stat">
302 <span class="ka-img-opt-live-stat-value" id="live-skipped">0</span>
303 <span class="ka-img-opt-live-stat-label"><?php esc_html_e('Skipped', 'king-addons'); ?></span>
304 </div>
305 <div class="ka-img-opt-live-stat">
306 <span class="ka-img-opt-live-stat-value" id="live-errors">0</span>
307 <span class="ka-img-opt-live-stat-label"><?php esc_html_e('Errors', 'king-addons'); ?></span>
308 </div>
309 <div class="ka-img-opt-live-stat">
310 <span class="ka-img-opt-live-stat-value" id="live-saved">0 KB</span>
311 <span class="ka-img-opt-live-stat-label"><?php esc_html_e('Saved', 'king-addons'); ?></span>
312 </div>
313 </div>
314
315 <!-- Live List (Processed/Remaining) -->
316 <div class="ka-img-opt-live-list-card" id="ka-img-opt-live-list-card">
317 <div class="ka-img-opt-live-list-head">
318 <div class="ka-img-opt-live-tabs" role="tablist" aria-label="<?php esc_attr_e('Live processing list', 'king-addons'); ?>">
319 <button type="button" class="ka-img-opt-live-tab active" data-view="processed" role="tab" aria-selected="true">
320 <?php esc_html_e('Processed', 'king-addons'); ?>
321 <span class="ka-img-opt-live-tab-count" id="ka-live-processed-count">0</span>
322 </button>
323 <button type="button" class="ka-img-opt-live-tab" data-view="remaining" role="tab" aria-selected="false">
324 <?php esc_html_e('Remaining', 'king-addons'); ?>
325 <span class="ka-img-opt-live-tab-count" id="ka-live-remaining-count">0</span>
326 </button>
327 </div>
328
329 <div class="ka-img-opt-live-filters" aria-label="<?php esc_attr_e('Filter processed items', 'king-addons'); ?>">
330 <button type="button" class="ka-img-opt-live-filter active" data-filter="all"><?php esc_html_e('All', 'king-addons'); ?></button>
331 <button type="button" class="ka-img-opt-live-filter" data-filter="success"><?php esc_html_e('Optimized', 'king-addons'); ?></button>
332 <button type="button" class="ka-img-opt-live-filter" data-filter="skipped"><?php esc_html_e('Skipped', 'king-addons'); ?></button>
333 <button type="button" class="ka-img-opt-live-filter" data-filter="error"><?php esc_html_e('Failed', 'king-addons'); ?></button>
334 </div>
335 </div>
336
337 <div class="ka-img-opt-live-list" id="ka-live-list" aria-live="polite"></div>
338
339 <div class="ka-img-opt-live-pagination">
340 <button type="button" class="ka-btn ka-btn-secondary" id="ka-live-prev"><?php esc_html_e('Prev', 'king-addons'); ?></button>
341 <span class="ka-img-opt-live-page" id="ka-live-page">1 / 1</span>
342 <button type="button" class="ka-btn ka-btn-secondary" id="ka-live-next"><?php esc_html_e('Next', 'king-addons'); ?></button>
343 </div>
344 </div>
345
346 <!-- Control Buttons -->
347 <div class="ka-img-opt-controls">
348 <button type="button" id="pause-btn" class="ka-btn ka-btn-secondary">
349 <span class="dashicons dashicons-controls-pause"></span>
350 <?php esc_html_e('Pause', 'king-addons'); ?>
351 </button>
352 <button type="button" id="stop-btn" class="ka-btn ka-btn-secondary">
353 <span class="dashicons dashicons-no"></span>
354 <?php esc_html_e('Stop', 'king-addons'); ?>
355 </button>
356 </div>
357 </div>
358 </div>
359
360 <!-- Results Section (hidden by default) -->
361 <div class="ka-card ka-img-opt-results" id="results-section" style="display: none;">
362 <div class="ka-card-header">
363 <span class="dashicons dashicons-yes-alt"></span>
364 <h2><?php esc_html_e('Optimization Complete', 'king-addons'); ?></h2>
365 </div>
366 <div class="ka-card-body">
367 <!-- Summary -->
368 <div class="ka-img-opt-results-summary">
369 <div class="ka-img-opt-result-item success">
370 <span class="ka-img-opt-result-icon dashicons dashicons-yes-alt" aria-hidden="true"></span>
371 <span class="ka-img-opt-result-value" id="result-success">0</span>
372 <span class="ka-img-opt-result-label"><?php esc_html_e('Images Optimized', 'king-addons'); ?></span>
373 </div>
374 <div class="ka-img-opt-result-item saved">
375 <span class="ka-img-opt-result-icon dashicons dashicons-database" aria-hidden="true"></span>
376 <span class="ka-img-opt-result-value" id="result-saved">0 MB</span>
377 <span class="ka-img-opt-result-label"><?php esc_html_e('Space Saved', 'king-addons'); ?></span>
378 </div>
379 <div class="ka-img-opt-result-item percent">
380 <span class="ka-img-opt-result-icon dashicons dashicons-chart-bar" aria-hidden="true"></span>
381 <span class="ka-img-opt-result-value" id="result-percent">0%</span>
382 <span class="ka-img-opt-result-label"><?php esc_html_e('Average Reduction', 'king-addons'); ?></span>
383 </div>
384 </div>
385
386 <!-- Actions -->
387 <div class="ka-img-opt-actions">
388 <button type="button" id="optimize-more" class="ka-btn ka-btn-primary">
389 <span class="dashicons dashicons-update"></span>
390 <?php esc_html_e('Optimize More', 'king-addons'); ?>
391 </button>
392 <a href="<?php echo esc_url(admin_url('upload.php')); ?>" class="ka-btn ka-btn-secondary">
393 <span class="dashicons dashicons-format-gallery"></span>
394 <?php esc_html_e('View Media Library', 'king-addons'); ?>
395 </a>
396 </div>
397 </div>
398 </div>
399
400 <!-- Image Format Breakdown -->
401 <div class="ka-card ka-img-opt-formats">
402 <div class="ka-card-header">
403 <span class="dashicons dashicons-chart-pie"></span>
404 <h2><?php esc_html_e('Image Library Breakdown', 'king-addons'); ?></h2>
405 </div>
406 <div class="ka-card-body">
407 <div class="ka-img-opt-format-list" id="ka-img-opt-format-list">
408 <?php foreach ($format_counts as $format => $count): ?>
409 <div class="ka-img-opt-format-item">
410 <div class="ka-img-opt-format-info">
411 <span class="ka-img-opt-format-name"><?php echo esc_html(strtoupper($format)); ?></span>
412 <span class="ka-img-opt-format-count"><?php echo esc_html(number_format_i18n($count)); ?></span>
413 </div>
414 <div class="ka-img-opt-format-bar">
415 <div class="ka-img-opt-format-bar-fill" style="width: <?php echo esc_attr(min(100, ($count / max($stats['total_images'], 1)) * 100)); ?>%;"></div>
416 </div>
417 </div>
418 <?php endforeach; ?>
419 </div>
420 </div>
421 </div>
422 </div>
423
424 <!-- Tab Content: Settings -->
425 <div class="ka-img-opt-tab-content" id="tab-settings">
426 <div class="ka-card">
427 <div class="ka-card-header">
428 <span class="dashicons dashicons-admin-generic"></span>
429 <h2><?php esc_html_e('Global Settings', 'king-addons'); ?></h2>
430 </div>
431 <div class="ka-card-body">
432 <!-- Default Quality -->
433 <div class="ka-row">
434 <div class="ka-row-label"><?php esc_html_e('Default Quality', 'king-addons'); ?></div>
435 <div class="ka-row-field">
436 <div class="ka-img-opt-slider-wrap">
437 <input type="range" id="settings-quality" min="1" max="100" value="<?php echo esc_attr($settings['quality']); ?>" class="ka-img-opt-slider">
438 <output id="settings-quality-output"><?php echo esc_html($settings['quality']); ?>%</output>
439 </div>
440 <p class="ka-row-desc"><?php esc_html_e('Default compression quality for new optimizations.', 'king-addons'); ?></p>
441 </div>
442 </div>
443
444 <!-- Skip Small Files -->
445 <div class="ka-row">
446 <div class="ka-row-label"><?php esc_html_e('Skip Small Files', 'king-addons'); ?></div>
447 <div class="ka-row-field">
448 <label class="ka-toggle">
449 <input type="checkbox" id="settings-skip-small" <?php checked($settings['skip_small']); ?>>
450 <span class="ka-toggle-slider"></span>
451 </label>
452 <p class="ka-row-desc"><?php esc_html_e('Skip images smaller than 10KB to avoid over-optimization.', 'king-addons'); ?></p>
453 </div>
454 </div>
455
456 <!-- Auto Replace URLs -->
457 <div class="ka-row">
458 <div class="ka-row-label"><?php esc_html_e('Auto Replace URLs', 'king-addons'); ?></div>
459 <div class="ka-row-field">
460 <label class="ka-toggle">
461 <input type="checkbox" id="settings-auto-replace" <?php checked($settings['auto_replace_urls']); ?>>
462 <span class="ka-toggle-slider"></span>
463 </label>
464 <p class="ka-row-desc"><?php esc_html_e('Automatically update image URLs in database after optimization.', 'king-addons'); ?></p>
465 </div>
466 </div>
467
468 <!-- Auto Optimize Uploads (Browser) -->
469 <div class="ka-row <?php echo !$is_pro ? 'ka-pro-locked' : ''; ?>">
470 <div class="ka-row-label">
471 <?php esc_html_e('Auto Optimize Uploads', 'king-addons'); ?>
472 <?php if (!$is_pro) : ?>
473 <span class="ka-pro-badge" aria-label="<?php echo esc_attr__('Pro feature', 'king-addons'); ?>">PRO</span>
474 <?php endif; ?>
475 </div>
476 <div class="ka-row-field">
477 <label class="ka-toggle">
478 <input type="checkbox" id="settings-auto-optimize-uploads" <?php checked($is_pro && !empty($settings['auto_optimize_uploads'])); ?> <?php disabled(!$is_pro); ?>>
479 <span class="ka-toggle-slider"></span>
480 </label>
481 <p class="ka-row-desc">
482 <?php esc_html_e('Automatically optimize newly uploaded images in Media Library.', 'king-addons'); ?>
483 <?php if (!$is_pro) : ?>
484 <a href="<?php echo esc_url($upgrade_url); ?>" target="_blank" rel="noopener noreferrer"><?php esc_html_e('Upgrade to enable.', 'king-addons'); ?></a>
485 <?php endif; ?>
486 </p>
487 </div>
488 </div>
489
490 <!-- Resize Large Images -->
491 <div class="ka-row">
492 <div class="ka-row-label"><?php esc_html_e('Resize Large Images', 'king-addons'); ?></div>
493 <div class="ka-row-field">
494 <label class="ka-toggle">
495 <input type="checkbox" id="settings-resize-enabled" <?php checked(!empty($settings['resize_enabled'])); ?>>
496 <span class="ka-toggle-slider"></span>
497 </label>
498 <div class="ka-img-opt-resize-options" style="<?php echo !empty($settings['resize_enabled']) ? '' : 'display:none;'; ?>">
499 <label><?php esc_html_e('Max width:', 'king-addons'); ?>
500 <input type="number" id="settings-max-width" value="<?php echo esc_attr($settings['max_width']); ?>" min="100" max="5000"> px
501 </label>
502 </div>
503 <p class="ka-row-desc"><?php esc_html_e('If enabled, images wider than Max width will be resized in the browser before converting to WebP.', 'king-addons'); ?></p>
504 </div>
505 </div>
506
507 <!-- Save Button -->
508 <div class="ka-img-opt-actions">
509 <button type="button" id="save-settings" class="ka-btn ka-btn-primary">
510 <span class="dashicons dashicons-saved"></span>
511 <?php esc_html_e('Save Settings', 'king-addons'); ?>
512 </button>
513 </div>
514 </div>
515 </div>
516
517 <!-- Restore Section -->
518 <div class="ka-card">
519 <div class="ka-card-header">
520 <span class="dashicons dashicons-backup" style="color: #ff9500;"></span>
521 <h2><?php esc_html_e('Restore & Maintenance', 'king-addons'); ?></h2>
522 </div>
523 <div class="ka-card-body">
524 <div class="ka-img-opt-restore-section">
525 <h3><?php esc_html_e('Restore All Original Images', 'king-addons'); ?></h3>
526 <p><?php esc_html_e('Restore all images to their original versions and delete optimized WebP files.', 'king-addons'); ?></p>
527 <button type="button" id="restore-all" class="ka-btn ka-btn-secondary danger">
528 <span class="dashicons dashicons-undo"></span>
529 <?php esc_html_e('Restore All Originals', 'king-addons'); ?>
530 </button>
531
532 <div id="restore-all-progress" style="display:none; margin-top: 14px;">
533 <div class="ka-img-opt-progress-bar">
534 <div class="ka-img-opt-progress-fill" id="restore-progress-fill" style="width: 0%;"></div>
535 </div>
536 <div class="ka-img-opt-progress-info">
537 <span id="restore-progress-percent">0%</span>
538 <span id="restore-progress-count">0 / 0</span>
539 </div>
540 <div class="ka-img-opt-current-file">
541 <span class="dashicons dashicons-format-image"></span>
542 <span id="restore-current-filename"><?php esc_html_e('Preparing...', 'king-addons'); ?></span>
543 </div>
544 </div>
545 </div>
546
547 <div class="ka-img-opt-restore-section">
548 <h3><?php esc_html_e('Sync Media Library Metadata', 'king-addons'); ?></h3>
549 <p><?php esc_html_e('If WebP files exist in uploads but Media Library still shows old file sizes or paths, run a sync to update attachment metadata.', 'king-addons'); ?></p>
550 <button type="button" id="sync-media-library" class="ka-btn ka-btn-secondary">
551 <span class="dashicons dashicons-update"></span>
552 <?php esc_html_e('Sync Media Library', 'king-addons'); ?>
553 </button>
554 <button type="button" id="sync-media-library-stop" class="ka-btn ka-btn-secondary" style="display:none; margin-left: 8px;">
555 <span class="dashicons dashicons-no"></span>
556 <?php esc_html_e('Stop', 'king-addons'); ?>
557 </button>
558
559 <div id="sync-media-library-progress" style="display:none; margin-top: 14px;">
560 <div class="ka-img-opt-progress-bar">
561 <div class="ka-img-opt-progress-fill" id="sync-progress-fill" style="width: 0%;"></div>
562 </div>
563 <div class="ka-img-opt-progress-info">
564 <span id="sync-progress-percent">0%</span>
565 <span id="sync-progress-count">0 / 0</span>
566 </div>
567 <div class="ka-img-opt-current-file">
568 <span class="dashicons dashicons-format-image"></span>
569 <span id="sync-current-filename"><?php esc_html_e('Preparing...', 'king-addons'); ?></span>
570 </div>
571 </div>
572 </div>
573 </div>
574 </div>
575
576 </div>
577 </div>
578
579 <!-- PRO / Free limits modal -->
580 <div class="ka-img-opt-modal" id="ka-img-opt-pro-modal" style="display:none;" aria-hidden="true">
581 <div class="ka-img-opt-modal__overlay" data-ka-modal-close="1"></div>
582 <div class="ka-img-opt-modal__dialog" role="dialog" aria-modal="true" aria-labelledby="ka-img-opt-pro-modal-title">
583 <div class="ka-img-opt-modal__head">
584 <div class="ka-img-opt-modal__icon" aria-hidden="true">
585 <span class="dashicons dashicons-star-filled"></span>
586 </div>
587 <div class="ka-img-opt-modal__titles">
588 <div class="ka-img-opt-modal__title" id="ka-img-opt-pro-modal-title"><?php esc_html_e('Free Plan Limit Reached', 'king-addons'); ?></div>
589 <div class="ka-img-opt-modal__sub" id="ka-img-opt-pro-modal-sub">
590 <?php esc_html_e('You can optimize up to 200 images per month in the Free plan.', 'king-addons'); ?>
591 </div>
592 </div>
593 </div>
594
595 <div class="ka-img-opt-modal__body">
596 <div class="ka-img-opt-modal__quota">
597 <span class="ka-img-opt-modal__quota-k"><?php esc_html_e('Remaining this month:', 'king-addons'); ?></span>
598 <span class="ka-img-opt-modal__quota-v"><span id="ka-img-opt-modal-remaining">0</span> / <span id="ka-img-opt-modal-limit">200</span></span>
599 </div>
600 <ul class="ka-img-opt-modal__list">
601 <li><?php esc_html_e('200 optimizations per month', 'king-addons'); ?></li>
602 <li><?php esc_html_e('Auto Optimize Uploads is a PRO feature', 'king-addons'); ?></li>
603 <li><?php esc_html_e('Upgrade to Unlimited to remove limits', 'king-addons'); ?></li>
604 </ul>
605 </div>
606
607 <div class="ka-img-opt-modal__actions">
608 <a class="ka-btn ka-btn-primary" id="ka-img-opt-modal-upgrade" href="<?php echo esc_url($upgrade_url); ?>" target="_blank" rel="noopener noreferrer">
609 <?php esc_html_e('Upgrade to Unlimited', 'king-addons'); ?>
610 </a>
611 <button type="button" class="ka-btn ka-btn-secondary" data-ka-modal-close="1"><?php esc_html_e('Not now', 'king-addons'); ?></button>
612 </div>
613 </div>
614 </div>
615
616 <script>
617 // Theme toggle handler
618 document.addEventListener('DOMContentLoaded', function() {
619 const segment = document.getElementById('ka-v3-theme-segment');
620 if (segment) {
621 const buttons = segment.querySelectorAll('.ka-v3-segmented-btn');
622
623 function setPressedState(activeMode) {
624 segment.setAttribute('data-active', activeMode);
625 buttons.forEach((btn) => {
626 const theme = btn.getAttribute('data-theme');
627 btn.setAttribute('aria-pressed', theme === activeMode ? 'true' : 'false');
628 });
629 }
630
631 function applyThemeMode(mode) {
632 const mql = window.matchMedia ? window.matchMedia('(prefers-color-scheme: dark)') : null;
633 const isDark = mode === 'auto' ? !!(mql && mql.matches) : mode === 'dark';
634 document.documentElement.classList.toggle('ka-v3-dark', isDark);
635 document.body.classList.toggle('ka-v3-dark', isDark);
636 }
637
638 buttons.forEach(function(btn) {
639 btn.addEventListener('click', function(e) {
640 e.preventDefault();
641 const mode = (this.getAttribute('data-theme') || 'dark').toString();
642
643 setPressedState(mode);
644 applyThemeMode(mode);
645
646 // Save preference (same handler as Dashboard V3)
647 try {
648 const body = new URLSearchParams();
649 body.set('action', 'king_addons_save_dashboard_ui');
650 body.set('nonce', '<?php echo esc_js(wp_create_nonce('king_addons_dashboard_ui')); ?>');
651 body.set('key', 'theme_mode');
652 body.set('value', mode);
653
654 fetch(ajaxurl, {
655 method: 'POST',
656 headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8' },
657 body: body.toString(),
658 credentials: 'same-origin'
659 });
660 } catch (e) {}
661 });
662 });
663
664 // Ensure correct state on load
665 const initial = (segment.getAttribute('data-active') || 'dark').toString();
666 setPressedState(initial);
667 applyThemeMode(initial);
668 }
669
670 // Tab switching
671 document.querySelectorAll('.ka-img-opt-tab').forEach(function(tab) {
672 tab.addEventListener('click', function() {
673 document.querySelectorAll('.ka-img-opt-tab').forEach(t => t.classList.remove('active'));
674 document.querySelectorAll('.ka-img-opt-tab-content').forEach(c => c.classList.remove('active'));
675 this.classList.add('active');
676 document.getElementById('tab-' + this.dataset.tab).classList.add('active');
677 });
678 });
679 });
680 </script>
681