PluginProbe
Search Atlas SEO – OTTO AI SEO Automation for WordPress / 2.6.12
Search Atlas SEO – OTTO AI SEO Automation for WordPress v2.6.12
2.6.26 2.6.25 2.6.24 2.6.23 2.6.22 2.6.21 2.6.20 2.6.19 2.6.18 2.6.17 2.6.16 2.6.15 2.6.14 2.6.13 2.6.12 2.6.11 2.6.10 2.6.9 2.6.8 2.6.7 2.6.6 2.6.5 2.6.4 2.6.3 2.5.23 All 138 releases
metasync / views / metasync-redirection.php

metasync-redirection.php in Search Atlas SEO – OTTO AI SEO Automation for WordPress 2.6.12, at views/metasync-redirection.php

900 lines 30.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <style type="text/css">
2 <?php
3 // If this file is called directly, abort.
4 if (!defined('ABSPATH')) {
5 exit;
6 }
7 ?>
8 /* Root Variables - Dashboard Color Scheme */
9 :root {
10 --dashboard-bg: #0f1419;
11 --dashboard-card-bg: #1a1f26;
12 --dashboard-card-hover: #222831;
13 --dashboard-text-primary: #ffffff;
14 --dashboard-text-secondary: #9ca3af;
15 --dashboard-accent: #3b82f6;
16 --dashboard-accent-hover: #2563eb;
17 --dashboard-success: #10b981;
18 --dashboard-warning: #f59e0b;
19 --dashboard-error: #ef4444;
20 --dashboard-border: #374151;
21 --dashboard-gradient-primary: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
22 --dashboard-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.3), 0 4px 6px -2px rgba(0, 0, 0, 0.1);
23 --dashboard-shadow-hover: 0 20px 25px -5px rgba(0, 0, 0, 0.4), 0 10px 10px -5px rgba(0, 0, 0, 0.2);
24 }
25
26 .column-cb {
27 width: 2.2em;
28 }
29
30 .wrap .wp-list-table th.check-column,
31 .wrap .wp-list-table td.check-column {
32 width: 2.2em;
33 padding: 8px 0 0 3px;
34 vertical-align: middle;
35 }
36
37 .wrap .wp-list-table th.check-column input[type="checkbox"],
38 .wrap .wp-list-table td.check-column input[type="checkbox"] {
39 margin: 0;
40 padding: 0;
41 vertical-align: middle;
42 }
43
44 .column-sources_from {
45 width: 25%;
46 }
47
48 .column-url_redirect_to {
49 width: 25%;
50 }
51
52 .column-http_code {
53 width: 10%;
54 }
55
56 .column-pattern_type {
57 width: 12%;
58 }
59
60 .column-hits_count {
61 width: 8%;
62 }
63
64 .column-status {
65 width: 10%;
66 }
67
68 .column-last_accessed_at {
69 width: 10%;
70 }
71
72 /* Page background */
73 body {
74 background: var(--dashboard-bg) !important;
75 }
76
77 .wrap {
78 background: var(--dashboard-bg) !important;
79 color: var(--dashboard-text-primary) !important;
80 }
81
82 /* Enhanced table styling with higher specificity */
83 .wrap .wp-list-table {
84 background: var(--dashboard-card-bg) !important;
85 border: 1px solid var(--dashboard-border) !important;
86 border-radius: 12px !important;
87 overflow: hidden !important;
88 box-shadow: var(--dashboard-shadow) !important;
89 }
90
91 .wrap .wp-list-table th {
92 background: var(--dashboard-card-hover) !important;
93 color: var(--dashboard-text-primary) !important;
94 border-bottom: 1px solid var(--dashboard-border) !important;
95 font-weight: 600 !important;
96 }
97
98 .wrap .wp-list-table td {
99 background: var(--dashboard-card-bg) !important;
100 border-bottom: 1px solid var(--dashboard-border) !important;
101 color: var(--dashboard-text-secondary) !important;
102 }
103
104 .wrap .wp-list-table tr:hover td {
105 background: var(--dashboard-card-hover) !important;
106 color: var(--dashboard-text-primary) !important;
107 }
108
109 .wrap .wp-list-table tr:nth-child(even) td {
110 background: var(--dashboard-card-bg) !important;
111 }
112
113 .wrap .wp-list-table tr:nth-child(odd) td {
114 background: rgba(255, 255, 255, 0.05) !important;
115 }
116
117 .wrap .wp-list-table tr:nth-child(even):hover td {
118 background: var(--dashboard-card-hover) !important;
119 color: var(--dashboard-text-primary) !important;
120 }
121
122 .wrap .wp-list-table tr:nth-child(odd):hover td {
123 background: var(--dashboard-card-hover) !important;
124 color: var(--dashboard-text-primary) !important;
125 }
126
127 /* Optimized table row backgrounds - alternating pattern for all rows */
128 .wrap .wp-list-table tbody tr:nth-child(odd) td {
129 background: var(--dashboard-card-bg) !important;
130 }
131
132 .wrap .wp-list-table tbody tr:nth-child(even) td {
133 background: rgba(255, 255, 255, 0.05) !important;
134 }
135
136 /* Ensure hover states work correctly */
137 .wrap .wp-list-table tbody tr:nth-child(odd):hover td {
138 background: var(--dashboard-card-hover) !important;
139 color: var(--dashboard-text-primary) !important;
140 }
141
142 .wrap .wp-list-table tbody tr:nth-child(even):hover td {
143 background: var(--dashboard-card-hover) !important;
144 color: var(--dashboard-text-primary) !important;
145 }
146
147 /* Button styling with higher specificity */
148 .wrap .button-primary,
149 .wrap .button-primary:visited,
150 .wrap input[type="submit"].button-primary,
151 .wrap input[type="button"].button-primary {
152 background: var(--dashboard-accent) !important;
153 border-color: var(--dashboard-accent) !important;
154 color: white !important;
155 border-radius: 8px !important;
156 font-weight: 500 !important;
157 transition: all 0.3s ease !important;
158 text-decoration: none !important;
159 }
160
161 .wrap .button-primary:hover,
162 .wrap .button-primary:focus,
163 .wrap input[type="submit"].button-primary:hover,
164 .wrap input[type="button"].button-primary:hover {
165 background: var(--dashboard-accent-hover) !important;
166 border-color: var(--dashboard-accent-hover) !important;
167 transform: translateY(-1px) !important;
168 box-shadow: var(--dashboard-shadow-hover) !important;
169 color: white !important;
170 text-decoration: none !important;
171 }
172
173 .wrap .button-secondary,
174 .wrap .button-secondary:visited,
175 .wrap input[type="submit"].button-secondary,
176 .wrap input[type="button"].button-secondary {
177 background: transparent !important;
178 border: 1px solid var(--dashboard-border) !important;
179 color: var(--dashboard-text-secondary) !important;
180 border-radius: 8px !important;
181 transition: all 0.3s ease !important;
182 text-decoration: none !important;
183 }
184
185 .wrap .button-secondary:hover,
186 .wrap .button-secondary:focus,
187 .wrap input[type="submit"].button-secondary:hover,
188 .wrap input[type="button"].button-secondary:hover {
189 background: var(--dashboard-card-hover) !important;
190 color: var(--dashboard-text-primary) !important;
191 border-color: var(--dashboard-accent) !important;
192 text-decoration: none !important;
193 }
194
195 /* Specific button targeting */
196 .wrap input[type="submit"]#doaction,
197 .wrap input[type="submit"]#post-query-submit,
198 .wrap input[type="submit"]#search-submit,
199 .wrap input[type="submit"].button {
200 background: var(--dashboard-accent) !important;
201 border-color: var(--dashboard-accent) !important;
202 color: white !important;
203 border-radius: 8px !important;
204 font-weight: 500 !important;
205 transition: all 0.3s ease !important;
206 }
207
208 .wrap input[type="submit"]#doaction:hover,
209 .wrap input[type="submit"]#post-query-submit:hover,
210 .wrap input[type="submit"]#search-submit:hover,
211 .wrap input[type="submit"].button:hover {
212 background: var(--dashboard-accent-hover) !important;
213 border-color: var(--dashboard-accent-hover) !important;
214 transform: translateY(-1px) !important;
215 box-shadow: var(--dashboard-shadow-hover) !important;
216 color: white !important;
217 }
218
219 /* Link button styling */
220 .wrap a.button,
221 .wrap a.button:visited {
222 background: var(--dashboard-accent) !important;
223 border-color: var(--dashboard-accent) !important;
224 color: white !important;
225 border-radius: 8px !important;
226 font-weight: 500 !important;
227 transition: all 0.3s ease !important;
228 text-decoration: none !important;
229 display: inline-block !important;
230 padding: 8px 16px !important;
231 }
232
233 .wrap a.button:hover,
234 .wrap a.button:focus {
235 background: var(--dashboard-accent-hover) !important;
236 border-color: var(--dashboard-accent-hover) !important;
237 transform: translateY(-1px) !important;
238 box-shadow: var(--dashboard-shadow-hover) !important;
239 color: white !important;
240 text-decoration: none !important;
241 }
242
243 /* Add Redirection Form Styling — hidden by default, shown via inline style by JS */
244 .wrap #add-redirection-form {
245 display: none;
246 background: var(--dashboard-card-bg) !important;
247 border: 1px solid var(--dashboard-border) !important;
248 border-radius: 12px !important;
249 padding: 24px !important;
250 margin-bottom: 24px !important;
251 box-shadow: var(--dashboard-shadow) !important;
252 }
253
254 .wrap #add-redirection-form h1 {
255 color: var(--dashboard-text-primary) !important;
256 margin-bottom: 20px !important;
257 font-size: 1.5rem !important;
258 font-weight: 600 !important;
259 }
260
261 .wrap #add-redirection-form .form-table {
262 background: transparent !important;
263 border: none !important;
264 }
265
266 .wrap #add-redirection-form .form-table th {
267 background: transparent !important;
268 color: var(--dashboard-text-primary) !important;
269 font-weight: 600 !important;
270 padding: 12px 0 !important;
271 width: 150px !important;
272 }
273
274 .wrap #add-redirection-form .form-table td {
275 background: transparent !important;
276 color: var(--dashboard-text-secondary) !important;
277 padding: 15px !important;
278 }
279
280 .wrap #add-redirection-form input[type="text"],
281 .wrap #add-redirection-form input[type="url"],
282 .wrap #add-redirection-form textarea {
283 background: var(--dashboard-card-hover) !important;
284 border: 1px solid var(--dashboard-border) !important;
285 color: var(--dashboard-text-primary) !important;
286 border-radius: 8px !important;
287 padding: 8px 12px !important;
288 width: 100% !important;
289 max-width: 500px !important;
290 }
291
292 .wrap #add-redirection-form input[type="text"]:focus,
293 .wrap #add-redirection-form input[type="url"]:focus,
294 .wrap #add-redirection-form textarea:focus {
295 border-color: var(--dashboard-accent) !important;
296 box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1) !important;
297 outline: none !important;
298 }
299
300 .wrap #add-redirection-form textarea {
301 min-height: 80px !important;
302 resize: vertical !important;
303 }
304
305 .wrap #add-redirection-form input[type="radio"] {
306 margin-right: 8px !important;
307 accent-color: var(--dashboard-accent) !important;
308 }
309
310 .wrap #add-redirection-form label {
311 color: var(--dashboard-text-secondary) !important;
312 margin-right: 16px !important;
313 font-weight: 500 !important;
314 }
315
316 .wrap #add-redirection-form .source-url-list {
317 background: var(--dashboard-card-hover) !important;
318 border: 1px solid var(--dashboard-border) !important;
319 border-radius: 8px !important;
320 padding: 12px !important;
321 margin: 8px 0 !important;
322 }
323
324 .wrap #add-redirection-form .source-url-list li {
325 background: transparent !important;
326 border: none !important;
327 padding: 8px 0 !important;
328 margin: 0 !important;
329 display: flex !important;
330 align-items: center !important;
331 gap: 12px !important;
332 }
333
334 .wrap #add-redirection-form .source-url-list input[type="text"] {
335 flex: 1 !important;
336 max-width: none !important;
337 margin: 0 !important;
338 }
339
340 /* Target the actual select elements */
341 .wrap #add-redirection-form select[name="search_type[]"],
342 .wrap #add-redirection-form select {
343 background: var(--dashboard-card-hover) !important;
344 border: 1px solid var(--dashboard-border) !important;
345 color: var(--dashboard-text-primary) !important;
346 border-radius: 6px !important;
347 padding: 6px 8px !important;
348 min-width: 120px !important;
349 appearance: none !important;
350 -moz-appearance: none !important;
351 -webkit-appearance: none !important;
352 background-image: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23ffffff' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3e%3cpolyline points='6,9 12,15 18,9'%3e%3c/polyline%3e%3c/svg%3e") !important;
353 background-repeat: no-repeat !important;
354 background-position: right 8px center !important;
355 background-size: 16px !important;
356 padding-right: 32px !important;
357 cursor: pointer !important;
358 margin-left: 8px !important;
359 }
360
361 .wrap #add-redirection-form select[name="search_type[]"]:focus,
362 .wrap #add-redirection-form select:focus {
363 border-color: var(--dashboard-accent) !important;
364 box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1) !important;
365 outline: none !important;
366 }
367
368 .wrap #add-redirection-form select[name="search_type[]"] option,
369 .wrap #add-redirection-form select option {
370 background: var(--dashboard-card-hover) !important;
371 color: var(--dashboard-text-primary) !important;
372 padding: 8px !important;
373 }
374
375 /* Target the actual remove button class */
376 .wrap #add-redirection-form .source_url_delete,
377 .wrap #add-redirection-form button.source_url_delete {
378 background: var(--dashboard-error) !important;
379 border: 1px solid var(--dashboard-error) !important;
380 color: white !important;
381 border-radius: 6px !important;
382 padding: 6px 12px !important;
383 font-size: 12px !important;
384 font-weight: 500 !important;
385 transition: all 0.3s ease !important;
386 cursor: pointer !important;
387 display: inline-block !important;
388 margin-left: 8px !important;
389 }
390
391 .wrap #add-redirection-form .source_url_delete:hover,
392 .wrap #add-redirection-form button.source_url_delete:hover {
393 background: #dc2626 !important;
394 border-color: #dc2626 !important;
395 transform: translateY(-1px) !important;
396 color: white !important;
397 }
398
399 .wrap #add-redirection-form .add-source-url {
400 background: var(--dashboard-accent) !important;
401 border: 1px solid var(--dashboard-accent) !important;
402 color: white !important;
403 border-radius: 8px !important;
404 padding: 8px 16px !important;
405 font-weight: 500 !important;
406 transition: all 0.3s ease !important;
407 margin-top: 8px !important;
408 }
409
410 .wrap #add-redirection-form .add-source-url:hover {
411 background: var(--dashboard-accent-hover) !important;
412 border-color: var(--dashboard-accent-hover) !important;
413 transform: translateY(-1px) !important;
414 box-shadow: var(--dashboard-shadow-hover) !important;
415 }
416
417 .wrap #add-redirection-form .form-actions {
418 background: transparent !important;
419 border: none !important;
420 padding: 20px 0 0 0 !important;
421 margin-top: 20px !important;
422 border-top: 1px solid var(--dashboard-border) !important;
423 }
424
425 .wrap #add-redirection-form .form-actions input[type="submit"] {
426 background: var(--dashboard-accent) !important;
427 border: 1px solid var(--dashboard-accent) !important;
428 color: white !important;
429 border-radius: 8px !important;
430 padding: 10px 20px !important;
431 font-weight: 500 !important;
432 margin-right: 12px !important;
433 transition: all 0.3s ease !important;
434 }
435
436 .wrap #add-redirection-form .form-actions input[type="submit"]:hover {
437 background: var(--dashboard-accent-hover) !important;
438 border-color: var(--dashboard-accent-hover) !important;
439 transform: translateY(-1px) !important;
440 box-shadow: var(--dashboard-shadow-hover) !important;
441 }
442
443 .wrap #add-redirection-form .form-actions input[type="button"] {
444 background: transparent !important;
445 border: 1px solid var(--dashboard-border) !important;
446 color: var(--dashboard-text-secondary) !important;
447 border-radius: 8px !important;
448 padding: 10px 20px !important;
449 font-weight: 500 !important;
450 transition: all 0.3s ease !important;
451 }
452
453 .wrap #add-redirection-form .form-actions input[type="button"]:hover {
454 background: var(--dashboard-card-hover) !important;
455 color: var(--dashboard-text-primary) !important;
456 border-color: var(--dashboard-accent) !important;
457 }
458
459 /* Additional form element styling */
460 .wrap #add-redirection-form input[type="radio"]:checked {
461 accent-color: var(--dashboard-accent) !important;
462 }
463
464 .wrap #add-redirection-form input[type="radio"]:checked + label {
465 color: var(--dashboard-text-primary) !important;
466 font-weight: 600 !important;
467 }
468
469 /* Ensure all buttons in the form are properly styled */
470 .wrap #add-redirection-form button,
471 .wrap #add-redirection-form input[type="button"],
472 .wrap #add-redirection-form input[type="submit"] {
473 font-family: inherit !important;
474 font-size: 14px !important;
475 line-height: 1.4 !important;
476 vertical-align: middle !important;
477 }
478
479 /* Fix any remaining button styling issues */
480 .wrap #add-redirection-form .button,
481 .wrap #add-redirection-form .button-secondary {
482 background: transparent !important;
483 border: 1px solid var(--dashboard-border) !important;
484 color: var(--dashboard-text-secondary) !important;
485 border-radius: 8px !important;
486 padding: 8px 16px !important;
487 font-weight: 500 !important;
488 transition: all 0.3s ease !important;
489 text-decoration: none !important;
490 display: inline-block !important;
491 cursor: pointer !important;
492 }
493
494 .wrap #add-redirection-form .button:hover,
495 .wrap #add-redirection-form .button-secondary:hover {
496 background: var(--dashboard-card-hover) !important;
497 color: var(--dashboard-text-primary) !important;
498 border-color: var(--dashboard-accent) !important;
499 text-decoration: none !important;
500 }
501
502 /* Additional targeting for form elements */
503 .wrap #add-redirection-form #source_urls li {
504 display: flex !important;
505 align-items: center !important;
506 gap: 8px !important;
507 margin-bottom: 8px !important;
508 padding: 8px !important;
509 background: var(--dashboard-card-hover) !important;
510 border-radius: 8px !important;
511 border: 1px solid var(--dashboard-border) !important;
512 }
513
514 .wrap #add-redirection-form #source_urls li input[type="text"] {
515 flex: 1 !important;
516 background: var(--dashboard-card-bg) !important;
517 border: 1px solid var(--dashboard-border) !important;
518 color: var(--dashboard-text-primary) !important;
519 border-radius: 6px !important;
520 padding: 6px 8px !important;
521 }
522
523 /* Force override for any conflicting styles */
524 .wrap #add-redirection-form * {
525 box-sizing: border-box !important;
526 }
527
528 /* Page headers and content */
529 .wp-heading-inline {
530 color: var(--dashboard-text-primary) !important;
531 }
532
533 h1, h2, h3 {
534 color: var(--dashboard-text-primary) !important;
535 }
536
537 /* Tablenav styling */
538 /* ── Tablenav ── */
539 .wrap .tablenav {
540 background: var(--dashboard-card-bg);
541 border: 1px solid var(--dashboard-border);
542 border-radius: 8px;
543 padding: 12px 16px;
544 margin-bottom: 16px;
545 box-shadow: var(--dashboard-shadow);
546 display: flex;
547 align-items: center;
548 flex-wrap: wrap;
549 gap: 8px;
550 }
551 .wrap .tablenav * { box-sizing: border-box; margin: 0; }
552
553 /* Left group: filters / bulk actions — shrinks equally with search */
554 .wrap .tablenav .alignleft,
555 .wrap .tablenav .actions {
556 display: flex;
557 align-items: center;
558 flex-wrap: nowrap;
559 gap: 6px;
560 flex: 1 1 0;
561 min-width: 0;
562 }
563
564 /* Right group: pagination */
565 .wrap .tablenav .alignright {
566 display: flex;
567 align-items: center;
568 flex-wrap: wrap;
569 gap: 6px;
570 margin-left: auto;
571 min-width: 0;
572 }
573
574 /* Search box — sits inline with filters, shrinks to fit */
575 .wrap .tablenav .metasync-search-box {
576 display: flex;
577 align-items: center;
578 flex-wrap: nowrap;
579 gap: 6px;
580 flex: 1 1 0;
581 min-width: 0;
582 }
583 .wrap .tablenav .metasync-search-box input[type="search"] {
584 flex: 1 1 60px;
585 min-width: 0;
586 width: auto;
587 }
588
589 /* ── Shared control height ── */
590 .wrap .tablenav select,
591 .wrap .tablenav input[type="search"],
592 .wrap .tablenav input[type="text"],
593 .wrap .tablenav input[type="submit"],
594 .wrap .tablenav input[type="button"],
595 .wrap .tablenav .button {
596 height: 34px;
597 font-size: 13px;
598 font-weight: 500;
599 border-radius: 6px;
600 padding: 0 10px;
601 line-height: 34px;
602 }
603
604 /* Selects — shrinkable, text truncates when compressed */
605 .wrap .tablenav select {
606 background: var(--dashboard-card-bg);
607 border: 1px solid var(--dashboard-border);
608 color: var(--dashboard-text-primary);
609 appearance: none;
610 -webkit-appearance: none;
611 background-image: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23ffffff' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3e%3cpolyline points='6,9 12,15 18,9'%3e%3c/polyline%3e%3c/svg%3e");
612 background-repeat: no-repeat;
613 background-position: right 6px center;
614 background-size: 14px;
615 padding-right: 28px;
616 cursor: pointer;
617 flex: 1 1 0;
618 min-width: 0;
619 overflow: hidden;
620 text-overflow: ellipsis;
621 }
622 .wrap .tablenav select:focus {
623 border-color: var(--dashboard-accent);
624 box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.15);
625 outline: none;
626 }
627 .wrap .tablenav select option {
628 background: var(--dashboard-card-bg);
629 color: var(--dashboard-text-primary);
630 }
631
632 /* Text / search inputs — fully flexible */
633 .wrap .tablenav input[type="search"],
634 .wrap .tablenav input[type="text"] {
635 background: var(--dashboard-card-bg);
636 border: 1px solid var(--dashboard-border);
637 color: var(--dashboard-text-primary);
638 width: auto;
639 min-width: 0;
640 flex: 1 1 80px;
641 }
642 .wrap .tablenav input[type="search"]:focus,
643 .wrap .tablenav input[type="text"]:focus {
644 border-color: var(--dashboard-accent);
645 box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.15);
646 outline: none;
647 }
648
649 /* Pagination current-page — narrow */
650 .wrap .tablenav-pages input.current-page,
651 .wrap .tablenav .current-page {
652 width: 3em !important;
653 min-width: 3em !important;
654 flex: 0 0 3em !important;
655 text-align: center;
656 padding: 0 4px;
657 }
658
659 /* Buttons */
660 .wrap .tablenav input[type="submit"],
661 .wrap .tablenav input[type="button"],
662 .wrap .tablenav .button {
663 white-space: nowrap;
664 display: inline-flex;
665 align-items: center;
666 justify-content: center;
667 flex-shrink: 0;
668 }
669
670
671 /* Item count badge */
672 .wrap .tablenav .displaying-num {
673 color: var(--dashboard-text-primary);
674 font-size: 12px;
675 font-weight: 500;
676 background: var(--dashboard-card-hover);
677 padding: 0 10px;
678 border-radius: 6px;
679 border: 1px solid var(--dashboard-border);
680 height: 30px;
681 line-height: 28px;
682 white-space: nowrap;
683 }
684
685 /* Pagination controls */
686 .wrap .tablenav-pages {
687 display: flex;
688 align-items: center;
689 gap: 4px;
690 margin-left: auto;
691 flex-wrap: wrap;
692 }
693 .wrap .tablenav-pages .paging-input {
694 display: inline-flex;
695 align-items: center;
696 gap: 4px;
697 }
698 .wrap .tablenav .alignright span,
699 .wrap .tablenav .alignright p {
700 color: var(--dashboard-text-primary);
701 font-size: 12px;
702 padding: 0;
703 border: none;
704 background: transparent;
705 height: auto;
706 }
707
708 .wrap .tablenav label {
709 padding: 0;
710 white-space: nowrap;
711 font-weight: 500;
712 color: var(--dashboard-text-primary);
713 font-size: 13px;
714 }
715
716 /* Page title action styling */
717 .page-title-action {
718 background: var(--dashboard-accent) !important;
719 border-color: var(--dashboard-accent) !important;
720 color: white !important;
721 border-radius: 8px !important;
722 font-weight: 500 !important;
723 transition: all 0.3s ease !important;
724 text-decoration: none !important;
725 padding: 8px 16px !important;
726 display: inline-flex !important;
727 align-items: center !important;
728 gap: 8px !important;
729 }
730 .page-title-action:hover {
731 background: var(--dashboard-accent-hover) !important;
732 border-color: var(--dashboard-accent-hover) !important;
733 transform: translateY(-1px);
734 box-shadow: var(--dashboard-shadow-hover) !important;
735 color: white !important;
736 }
737
738 /* Status indicators */
739 .status-active { color: var(--dashboard-success) !important; font-weight: 600; }
740 .status-inactive { color: var(--dashboard-text-secondary) !important; font-weight: 600; }
741
742 /* HTTP code styling */
743 .http-code-301, .http-code-302, .http-code-307 { color: var(--dashboard-accent) !important; font-weight: 600; }
744 .http-code-410, .http-code-451 { color: var(--dashboard-warning) !important; font-weight: 600; }
745
746 /* Duplicate element guards */
747 .wrap .wp-list-table + .wp-list-table { display: none !important; }
748 .wrap .tablenav + .tablenav { display: none !important; }
749 .wrap .wp-list-table thead:not(:first-of-type) { display: none !important; }
750
751 /* ── Responsive ── */
752 @media (max-width: 1200px) {
753 .wrap .tablenav { padding: 10px 12px; gap: 6px; }
754 .wrap .tablenav select,
755 .wrap .tablenav input[type="search"],
756 .wrap .tablenav input[type="text"],
757 .wrap .tablenav input[type="submit"],
758 .wrap .tablenav .button {
759 height: 30px; font-size: 12px; line-height: 30px; padding: 0 8px;
760 }
761 .wrap .tablenav select { padding-right: 22px; background-size: 12px; }
762 }
763
764 @media (max-width: 782px) {
765 .wrap .tablenav { padding: 10px; gap: 8px; }
766 .wrap .tablenav .alignleft,
767 .wrap .tablenav .alignright,
768 .wrap .tablenav .actions,
769 .wrap .tablenav .metasync-search-box { width: 100%; flex: 1 1 100%; }
770 .wrap .tablenav select { flex: 1 1 0%; }
771 .wrap .tablenav-pages { margin-left: 0; width: 100%; justify-content: center; }
772 }
773
774 /* Description text styling */
775 .wrap .description,
776 .wrap p.description {
777 color: var(--dashboard-text-secondary, #9ca3af) !important;
778 font-size: 13px !important;
779 line-height: 1.5 !important;
780 }
781
782 /* Health status column */
783 .column-health_status { width: 7%; text-align: center; }
784 .health-status-cell { display: inline-block; cursor: default; font-size: 16px; }
785
786 /* Body-appended floating tooltip — escapes all table stacking contexts */
787 .health-tooltip-floating {
788 position: fixed;
789 display: block;
790 background: #1e293b;
791 border: 1px solid #475569;
792 border-radius: 6px;
793 padding: 6px 12px;
794 z-index: 999999;
795 white-space: nowrap;
796 font-size: 12px;
797 color: #cbd5e1;
798 box-shadow: 0 4px 16px rgba(0,0,0,0.6);
799 pointer-events: none;
800 }
801 .wrap .wp-list-table thead tr:first-child th:first-child { border-top-left-radius: 12px; }
802 .wrap .wp-list-table thead tr:first-child th:last-child { border-top-right-radius: 12px; }
803 .wrap .wp-list-table tbody tr:last-child td:first-child { border-bottom-left-radius: 12px; }
804 .wrap .wp-list-table tbody tr:last-child td:last-child { border-bottom-right-radius: 12px; }
805 </style>
806
807 <div class="wrap">
808 <a href="<?php echo esc_url(admin_url('admin.php?page=' . Metasync_Admin::$page_slug . '-redirections&action=add')); ?>" class="page-title-action">Add New Redirect</a>
809
810 <!-- Import from SEO Plugins Button -->
811 <a href="<?php echo esc_url(admin_url('admin.php?page=' . Metasync_Admin::$page_slug . '-import-external&tab=redirections')); ?>" class="page-title-action" style="background: #10b981 !important; border-color: #10b981 !important;">
812 <span>📥</span> Import from SEO Plugins
813 </a>
814
815 <!-- Check Health Button -->
816 <button type="button" id="metasync-check-health-btn" class="page-title-action" style="background: #f59e0b !important; border-color: #f59e0b !important; color: #000 !important;">
817 Check Health
818 </button>
819
820 <!-- Allow External Redirects Setting -->
821 <?php
822 if (isset($_POST['metasync_save_external_redirects']) && current_user_can('manage_options') && wp_verify_nonce($_POST['_metasync_external_nonce'], 'metasync_external_redirects_toggle')) {
823 $allow_external = isset($_POST['metasync_allow_external_redirects']) ? 1 : 0;
824 update_option('metasync_allow_external_redirects', $allow_external, true);
825 echo '<div class="notice notice-success is-dismissible"><p>External redirects setting updated.</p></div>';
826 }
827 $allow_external_current = get_option('metasync_allow_external_redirects', 0);
828 ?>
829 <div style="background: var(--dashboard-card-bg, #1a1f26); border: 1px solid var(--dashboard-border, #374151); border-radius: 8px; padding: 12px 16px; margin: 15px 0; display: flex; align-items: center; gap: 12px;">
830 <form method="post" style="display: flex; align-items: center; gap: 12px; margin: 0;">
831 <?php wp_nonce_field('metasync_external_redirects_toggle', '_metasync_external_nonce'); ?>
832 <label style="display: flex; align-items: center; gap: 8px; cursor: pointer; color: var(--dashboard-text-primary, #fff); font-weight: 500;">
833 <input type="checkbox" name="metasync_allow_external_redirects" value="1" <?php checked($allow_external_current, 1); ?> onchange="this.form.submit();" style="width: 16px; height: 16px;">
834 Allow External Redirects
835 </label>
836 <input type="hidden" name="metasync_save_external_redirects" value="1">
837 <?php if ($allow_external_current) : ?>
838 <span style="color: var(--dashboard-warning, #f59e0b); font-size: 13px;">External redirects are enabled. Redirects can point to other websites.</span>
839 <?php else : ?>
840 <span style="color: var(--dashboard-text-secondary, #9ca3af); font-size: 13px;">External redirects are disabled. All redirects will stay on your site for security.</span>
841 <?php endif; ?>
842 </form>
843 </div>
844
845 <!-- Forms are NOT created automatically, so you need to wrap the table in one to use features like bulk actions -->
846 <form id="redirection-form" method="post" action="">
847 <?php wp_nonce_field('metasync_redirection_form', 'metasync_redirection_nonce'); ?>
848 <?php include "metasync-add-redirection.php";
849 $request_data = metasync_sanitize_input_array($_REQUEST); ?>
850 <!-- For plugins, we also need to ensure that the form posts back to our current page -->
851 <input type="hidden" name="page" value="<?php echo esc_attr($request_data['page']) ?>" />
852
853 <!-- Search and Filter Controls -->
854 <div class="tablenav top">
855
856 <div class="alignleft actions">
857 <label for="status-filter" class="screen-reader-text">Filter by status</label>
858 <select name="status_filter" id="status-filter">
859 <option value="">All Statuses</option>
860 <option value="active" <?php selected(isset($_REQUEST['status_filter']) ? $_REQUEST['status_filter'] : '', 'active'); ?>>Active</option>
861 <option value="inactive" <?php selected(isset($_REQUEST['status_filter']) ? $_REQUEST['status_filter'] : '', 'inactive'); ?>>Inactive</option>
862 </select>
863
864 <label for="pattern-filter" class="screen-reader-text">Filter by pattern type</label>
865 <select name="pattern_filter" id="pattern-filter">
866 <option value="">All Patterns</option>
867 <option value="exact" <?php selected(isset($_REQUEST['pattern_filter']) ? $_REQUEST['pattern_filter'] : '', 'exact'); ?>>Exact Match</option>
868 <option value="start" <?php selected(isset($_REQUEST['pattern_filter']) ? $_REQUEST['pattern_filter'] : '', 'start'); ?>>Starts With</option>
869 <option value="end" <?php selected(isset($_REQUEST['pattern_filter']) ? $_REQUEST['pattern_filter'] : '', 'end'); ?>>Ends With</option>
870 <option value="wildcard" <?php selected(isset($_REQUEST['pattern_filter']) ? $_REQUEST['pattern_filter'] : '', 'wildcard'); ?>>Wildcard (*)</option>
871 <option value="regex" <?php selected(isset($_REQUEST['pattern_filter']) ? $_REQUEST['pattern_filter'] : '', 'regex'); ?>>Regex Pattern</option>
872 </select>
873
874 <label for="http-code-filter" class="screen-reader-text">Filter by HTTP code</label>
875 <select name="http_code_filter" id="http-code-filter">
876 <option value="">All Types</option>
877 <option value="301" <?php selected(isset($_REQUEST['http_code_filter']) ? $_REQUEST['http_code_filter'] : '', '301'); ?>>301 Permanent</option>
878 <option value="302" <?php selected(isset($_REQUEST['http_code_filter']) ? $_REQUEST['http_code_filter'] : '', '302'); ?>>302 Temporary</option>
879 <option value="307" <?php selected(isset($_REQUEST['http_code_filter']) ? $_REQUEST['http_code_filter'] : '', '307'); ?>>307 Temporary</option>
880 <option value="410" <?php selected(isset($_REQUEST['http_code_filter']) ? $_REQUEST['http_code_filter'] : '', '410'); ?>>410 Gone</option>
881 <option value="451" <?php selected(isset($_REQUEST['http_code_filter']) ? $_REQUEST['http_code_filter'] : '', '451'); ?>>451 Unavailable</option>
882 </select>
883
884 <input type="submit" name="filter_action" id="post-query-submit" class="button" value="Filter">
885 </div>
886
887 <div class="metasync-search-box">
888 <label class="screen-reader-text" for="post-search-input">Search Redirections:</label>
889 <input type="search" id="post-search-input" name="s" value="<?php echo esc_attr(isset($_REQUEST['s']) ? $_REQUEST['s'] : ''); ?>" placeholder="Search redirections...">
890 <input type="submit" id="search-submit" class="button" value="Search">
891 </div>
892 </div>
893
894 <!-- Now we can render the completed list table -->
895 <?php $MetasyncRedirection->display() ?>
896 </form>
897
898 </div>
899
900