Refactor IGNY8 Bridge to use API key authentication exclusively
- Removed email/password authentication and related settings from the plugin. - Updated API connection logic to utilize only the API key for authentication. - Simplified the admin interface by removing webhook-related settings and messages. - Enhanced the settings page with improved UI and status indicators for API connection. - Added a new REST API endpoint to check plugin status and connection health. - Updated styles for a modernized look and feel across the admin interface.
This commit is contained in:
@@ -1,32 +1,297 @@
|
||||
/**
|
||||
* Admin Styles
|
||||
*
|
||||
* All styles for IGNY8 Bridge admin interface
|
||||
* Update this file to change global design
|
||||
* Admin Styles - IGNY8 Bridge
|
||||
* Updated with IGNY8 brand colors and modern UI
|
||||
*
|
||||
* @package Igny8Bridge
|
||||
*/
|
||||
|
||||
/* ============================================
|
||||
IGNY8 Brand Colors
|
||||
============================================ */
|
||||
:root {
|
||||
--igny8-primary: #3B82F6;
|
||||
--igny8-primary-hover: #2563EB;
|
||||
--igny8-success: #10B981;
|
||||
--igny8-warning: #F59E0B;
|
||||
--igny8-error: #EF4444;
|
||||
--igny8-purple: #8B5CF6;
|
||||
--igny8-gray: #6B7280;
|
||||
--igny8-light-gray: #F3F4F6;
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
Container & Layout
|
||||
============================================ */
|
||||
|
||||
.igny8-settings-container {
|
||||
max-width: 1200px;
|
||||
max-width: 1400px;
|
||||
}
|
||||
|
||||
.igny8-settings-card {
|
||||
background: #fff;
|
||||
border: 1px solid #ccd0d4;
|
||||
box-shadow: 0 1px 1px rgba(0,0,0,.04);
|
||||
padding: 20px;
|
||||
margin: 20px 0;
|
||||
border: 1px solid #E5E7EB;
|
||||
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06);
|
||||
padding: 24px;
|
||||
margin: 24px 0;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.igny8-settings-card h2 {
|
||||
margin-top: 0;
|
||||
padding-bottom: 10px;
|
||||
border-bottom: 1px solid #eee;
|
||||
padding-bottom: 12px;
|
||||
border-bottom: 2px solid var(--igny8-light-gray);
|
||||
color: #111827;
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
Toggle Switch
|
||||
============================================ */
|
||||
|
||||
.igny8-toggle-wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.igny8-toggle-input {
|
||||
position: relative;
|
||||
width: 48px;
|
||||
height: 24px;
|
||||
-webkit-appearance: none;
|
||||
appearance: none;
|
||||
background: var(--igny8-gray);
|
||||
outline: none;
|
||||
border-radius: 24px;
|
||||
cursor: pointer;
|
||||
transition: 0.3s;
|
||||
}
|
||||
|
||||
.igny8-toggle-input:checked {
|
||||
background: var(--igny8-success);
|
||||
}
|
||||
|
||||
.igny8-toggle-input::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border-radius: 50%;
|
||||
top: 2px;
|
||||
left: 2px;
|
||||
background: #fff;
|
||||
transition: 0.3s;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.igny8-toggle-input:checked::before {
|
||||
left: 26px;
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
Sync Operations Grid
|
||||
============================================ */
|
||||
|
||||
.igny8-sync-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
|
||||
gap: 20px;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.igny8-sync-card {
|
||||
background: #fff;
|
||||
border: 2px solid #E5E7EB;
|
||||
border-radius: 12px;
|
||||
padding: 24px;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.igny8-sync-card:hover {
|
||||
border-color: var(--igny8-primary);
|
||||
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.igny8-sync-card-highlight {
|
||||
border-color: var(--igny8-primary);
|
||||
background: linear-gradient(135deg, #EFF6FF 0%, #DBEAFE 100%);
|
||||
}
|
||||
|
||||
.igny8-sync-icon {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
background: var(--igny8-primary);
|
||||
border-radius: 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-bottom: 16px;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.igny8-sync-card h3 {
|
||||
margin: 0 0 8px 0;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: #111827;
|
||||
}
|
||||
|
||||
.igny8-sync-description {
|
||||
font-size: 14px;
|
||||
color: #6B7280;
|
||||
line-height: 1.5;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.igny8-sync-meta {
|
||||
font-size: 12px;
|
||||
color: #9CA3AF;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.igny8-sync-time {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.igny8-sync-button {
|
||||
width: 100%;
|
||||
height: 40px;
|
||||
background: var(--igny8-primary) !important;
|
||||
border-color: var(--igny8-primary) !important;
|
||||
color: white !important;
|
||||
font-weight: 500 !important;
|
||||
border-radius: 8px !important;
|
||||
transition: all 0.2s ease !important;
|
||||
}
|
||||
|
||||
.igny8-sync-button:hover:not(:disabled) {
|
||||
background: var(--igny8-primary-hover) !important;
|
||||
border-color: var(--igny8-primary-hover) !important;
|
||||
transform: translateY(-1px);
|
||||
box-shadow: 0 4px 6px -1px rgba(59, 130, 246, 0.3);
|
||||
}
|
||||
|
||||
.igny8-sync-button:disabled {
|
||||
opacity: 0.5 !important;
|
||||
cursor: not-allowed !important;
|
||||
}
|
||||
|
||||
.button-loading {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
Statistics Cards
|
||||
============================================ */
|
||||
|
||||
.igny8-stats-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
|
||||
gap: 20px;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.igny8-stat-card {
|
||||
background: linear-gradient(135deg, #ffffff 0%, #f9fafb 100%);
|
||||
border: 1px solid #E5E7EB;
|
||||
border-radius: 12px;
|
||||
padding: 20px;
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 16px;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.igny8-stat-card:hover {
|
||||
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.igny8-stat-icon {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
border-radius: 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.igny8-stat-content {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.igny8-stat-label {
|
||||
font-size: 12px;
|
||||
color: #6B7280;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05em;
|
||||
margin-bottom: 4px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.igny8-stat-value {
|
||||
font-size: 28px;
|
||||
font-weight: 700;
|
||||
color: #111827;
|
||||
line-height: 1.2;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.igny8-stat-meta {
|
||||
font-size: 12px;
|
||||
color: #9CA3AF;
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
Semantic Summary
|
||||
============================================ */
|
||||
|
||||
.igny8-semantic-summary {
|
||||
margin-top: 24px;
|
||||
padding: 20px;
|
||||
background: linear-gradient(135deg, #F3E8FF 0%, #E9D5FF 100%);
|
||||
border-radius: 12px;
|
||||
border: 1px solid #D8B4FE;
|
||||
}
|
||||
|
||||
.igny8-semantic-summary h3 {
|
||||
margin: 0 0 16px 0;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: #6B21A8;
|
||||
}
|
||||
|
||||
.igny8-semantic-stats {
|
||||
display: flex;
|
||||
gap: 32px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.igny8-semantic-stat {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.igny8-semantic-stat .value {
|
||||
font-size: 24px;
|
||||
font-weight: 700;
|
||||
color: #7C3AED;
|
||||
}
|
||||
|
||||
.igny8-semantic-stat .label {
|
||||
font-size: 12px;
|
||||
color: #8B5CF6;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05em;
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
@@ -34,103 +299,13 @@
|
||||
============================================ */
|
||||
|
||||
.igny8-status-connected {
|
||||
color: #46b450;
|
||||
font-weight: bold;
|
||||
color: var(--igny8-success);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.igny8-status-disconnected {
|
||||
color: #dc3232;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.igny8-test-result {
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.igny8-test-result .igny8-success {
|
||||
color: #46b450;
|
||||
}
|
||||
|
||||
.igny8-test-result .igny8-error {
|
||||
color: #dc3232;
|
||||
}
|
||||
|
||||
.igny8-test-result .igny8-loading {
|
||||
color: #2271b1;
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
Sync Operations
|
||||
============================================ */
|
||||
|
||||
.igny8-sync-actions {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 10px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.igny8-sync-actions .button {
|
||||
min-width: 150px;
|
||||
}
|
||||
|
||||
.igny8-sync-status {
|
||||
margin-top: 15px;
|
||||
padding: 10px;
|
||||
border-radius: 4px;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.igny8-sync-status.igny8-sync-status-success {
|
||||
background-color: #d4edda;
|
||||
border: 1px solid #c3e6cb;
|
||||
color: #155724;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.igny8-sync-status.igny8-sync-status-error {
|
||||
background-color: #f8d7da;
|
||||
border: 1px solid #f5c6cb;
|
||||
color: #721c24;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.igny8-sync-status.igny8-sync-status-loading {
|
||||
background-color: #d1ecf1;
|
||||
border: 1px solid #bee5eb;
|
||||
color: #0c5460;
|
||||
display: block;
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
Statistics
|
||||
============================================ */
|
||||
|
||||
.igny8-stats-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
||||
gap: 20px;
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
.igny8-stat-item {
|
||||
padding: 15px;
|
||||
background: #f9f9f9;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.igny8-stat-label {
|
||||
font-size: 12px;
|
||||
color: #666;
|
||||
text-transform: uppercase;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.igny8-stat-value {
|
||||
font-size: 24px;
|
||||
font-weight: bold;
|
||||
color: #2271b1;
|
||||
color: var(--igny8-error);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
@@ -141,47 +316,74 @@
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
|
||||
gap: 16px;
|
||||
margin-top: 15px;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.igny8-diagnostic-item {
|
||||
padding: 15px;
|
||||
background-color: #f6f7f7;
|
||||
border: 1px solid #dcdcde;
|
||||
border-radius: 4px;
|
||||
padding: 16px;
|
||||
background: linear-gradient(135deg, #F9FAFB 0%, #F3F4F6 100%);
|
||||
border: 1px solid #E5E7EB;
|
||||
border-radius: 8px;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.igny8-diagnostic-item:hover {
|
||||
border-color: var(--igny8-primary);
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.igny8-diagnostic-label {
|
||||
font-size: 11px;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05em;
|
||||
color: #555d66;
|
||||
margin-bottom: 6px;
|
||||
color: #6B7280;
|
||||
margin-bottom: 8px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.igny8-diagnostic-value {
|
||||
font-size: 18px;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: #1d2327;
|
||||
color: #111827;
|
||||
}
|
||||
|
||||
.igny8-diagnostic-item .description {
|
||||
margin: 6px 0 0;
|
||||
color: #646970;
|
||||
color: #9CA3AF;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
Buttons
|
||||
Sync Status Messages
|
||||
============================================ */
|
||||
|
||||
.igny8-button-group {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
margin: 15px 0;
|
||||
.igny8-sync-status {
|
||||
margin-top: 20px;
|
||||
padding: 16px;
|
||||
border-radius: 8px;
|
||||
display: none;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.igny8-button-group .button {
|
||||
flex: 1;
|
||||
.igny8-sync-status.igny8-sync-status-success {
|
||||
background-color: #D1FAE5;
|
||||
border: 1px solid #6EE7B7;
|
||||
color: #065F46;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.igny8-sync-status.igny8-sync-status-error {
|
||||
background-color: #FEE2E2;
|
||||
border: 1px solid #FCA5A5;
|
||||
color: #991B1B;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.igny8-sync-status.igny8-sync-status-loading {
|
||||
background-color: #DBEAFE;
|
||||
border: 1px solid #93C5FD;
|
||||
color: #1E40AF;
|
||||
display: block;
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
@@ -193,18 +395,6 @@
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.igny8-spinner {
|
||||
display: inline-block;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
border: 2px solid #f3f3f3;
|
||||
border-top: 2px solid #2271b1;
|
||||
border-radius: 50%;
|
||||
animation: igny8-spin 1s linear infinite;
|
||||
margin-right: 8px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
@keyframes igny8-spin {
|
||||
0% { transform: rotate(0deg); }
|
||||
100% { transform: rotate(360deg); }
|
||||
@@ -215,112 +405,35 @@
|
||||
============================================ */
|
||||
|
||||
.igny8-message {
|
||||
padding: 12px;
|
||||
padding: 16px;
|
||||
margin: 15px 0;
|
||||
border-left: 4px solid;
|
||||
background: #fff;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.igny8-message.igny8-message-success {
|
||||
border-color: #46b450;
|
||||
background-color: #f0f8f0;
|
||||
border-color: var(--igny8-success);
|
||||
background-color: #F0FDF4;
|
||||
color: #065F46;
|
||||
}
|
||||
|
||||
.igny8-message.igny8-message-error {
|
||||
border-color: #dc3232;
|
||||
background-color: #fff5f5;
|
||||
border-color: var(--igny8-error);
|
||||
background-color: #FEF2F2;
|
||||
color: #991B1B;
|
||||
}
|
||||
|
||||
.igny8-message.igny8-message-info {
|
||||
border-color: #2271b1;
|
||||
background-color: #f0f6fc;
|
||||
border-color: var(--igny8-primary);
|
||||
background-color: #EFF6FF;
|
||||
color: #1E40AF;
|
||||
}
|
||||
|
||||
.igny8-message.igny8-message-warning {
|
||||
border-color: #f0b849;
|
||||
background-color: #fffbf0;
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
Tables
|
||||
============================================ */
|
||||
|
||||
.igny8-table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin: 15px 0;
|
||||
}
|
||||
|
||||
.igny8-table th,
|
||||
.igny8-table td {
|
||||
padding: 10px;
|
||||
text-align: left;
|
||||
border-bottom: 1px solid #ddd;
|
||||
}
|
||||
|
||||
.igny8-table th {
|
||||
background-color: #f9f9f9;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.igny8-table tr:hover {
|
||||
background-color: #f9f9f9;
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
Admin Columns
|
||||
============================================ */
|
||||
|
||||
.igny8-badge {
|
||||
display: inline-block;
|
||||
padding: 3px 8px;
|
||||
border-radius: 3px;
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.igny8-badge-igny8 {
|
||||
background-color: #2271b1;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.igny8-badge-wordpress {
|
||||
background-color: #646970;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.igny8-terms-list {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.igny8-term-badge {
|
||||
display: inline-block;
|
||||
padding: 2px 6px;
|
||||
background-color: #f0f0f1;
|
||||
border: 1px solid #c3c4c7;
|
||||
border-radius: 2px;
|
||||
font-size: 11px;
|
||||
color: #50575e;
|
||||
}
|
||||
|
||||
.igny8-empty {
|
||||
color: #a7aaad;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.igny8-action-link {
|
||||
color: #2271b1;
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.igny8-action-link:hover {
|
||||
color: #135e96;
|
||||
text-decoration: underline;
|
||||
border-color: var(--igny8-warning);
|
||||
background-color: #FFFBEB;
|
||||
color: #92400E;
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
@@ -328,12 +441,8 @@
|
||||
============================================ */
|
||||
|
||||
@media (max-width: 782px) {
|
||||
.igny8-sync-actions {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.igny8-sync-actions .button {
|
||||
width: 100%;
|
||||
.igny8-sync-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.igny8-stats-grid {
|
||||
@@ -345,3 +454,16 @@
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 600px) {
|
||||
.igny8-settings-card {
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.igny8-sync-card {
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.igny8-stat-card {
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,9 +62,9 @@ class Igny8Admin {
|
||||
* Register settings
|
||||
*/
|
||||
public function register_settings() {
|
||||
register_setting('igny8_settings', 'igny8_email');
|
||||
// Email/password settings removed - using API key only
|
||||
register_setting('igny8_settings', 'igny8_site_id');
|
||||
register_setting('igny8_settings', 'igny8_enable_two_way_sync', array(
|
||||
register_setting('igny8_bridge_connection', 'igny8_connection_enabled', array(
|
||||
'type' => 'boolean',
|
||||
'sanitize_callback' => array($this, 'sanitize_boolean'),
|
||||
'default' => 1
|
||||
@@ -201,74 +201,42 @@ class Igny8Admin {
|
||||
}
|
||||
}
|
||||
|
||||
// Handle webhook secret regeneration (use wp_verify_nonce)
|
||||
if (isset($_POST['igny8_regenerate_secret'])) {
|
||||
if (empty($_POST['_wpnonce']) || !wp_verify_nonce($_POST['_wpnonce'], 'igny8_regenerate_secret')) {
|
||||
add_settings_error(
|
||||
'igny8_settings',
|
||||
'igny8_nonce_regen',
|
||||
__('Security check failed. Could not regenerate secret.', 'igny8-bridge'),
|
||||
'error'
|
||||
);
|
||||
} else {
|
||||
$new_secret = igny8_regenerate_webhook_secret();
|
||||
add_settings_error(
|
||||
'igny8_settings',
|
||||
'igny8_secret_regenerated',
|
||||
__('Webhook secret regenerated. Update it in your IGNY8 SaaS app settings.', 'igny8-bridge'),
|
||||
'updated'
|
||||
);
|
||||
}
|
||||
}
|
||||
// Webhook secret regeneration removed - using API key only
|
||||
|
||||
// Include settings template
|
||||
include IGNY8_BRIDGE_PLUGIN_DIR . 'admin/settings.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle API connection
|
||||
* Handle API connection - API key only
|
||||
*/
|
||||
private function handle_connection() {
|
||||
$email = sanitize_email($_POST['igny8_email'] ?? '');
|
||||
$password = $_POST['igny8_password'] ?? '';
|
||||
$api_key = sanitize_text_field($_POST['igny8_api_key'] ?? '');
|
||||
|
||||
// Check if API key is the placeholder (asterisks) - if so, get the stored key
|
||||
$is_placeholder = (strpos($api_key, '***') !== false || $api_key === '********');
|
||||
if ($is_placeholder) {
|
||||
// Get the existing API key
|
||||
$api_key = function_exists('igny8_get_secure_option')
|
||||
? igny8_get_secure_option('igny8_api_key')
|
||||
: get_option('igny8_api_key');
|
||||
}
|
||||
|
||||
// Require email, password AND API key per updated policy
|
||||
if (empty($email) || empty($password) || empty($api_key)) {
|
||||
// API key is required
|
||||
if (empty($api_key)) {
|
||||
add_settings_error(
|
||||
'igny8_settings',
|
||||
'igny8_error',
|
||||
__('Email, password and API key are all required to establish the connection.', 'igny8-bridge'),
|
||||
__('API key is required to connect to IGNY8.', 'igny8-bridge'),
|
||||
'error'
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// First, attempt login with email/password
|
||||
// Connect using API key only
|
||||
$api = new Igny8API();
|
||||
|
||||
if (!$api->login($email, $password)) {
|
||||
if (!$api->connect($api_key)) {
|
||||
add_settings_error(
|
||||
'igny8_settings',
|
||||
'igny8_error',
|
||||
__('Failed to connect to IGNY8 API with provided credentials.', 'igny8-bridge'),
|
||||
__('Failed to connect to IGNY8 API. Please verify your API key is correct.', 'igny8-bridge'),
|
||||
'error'
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// Store email
|
||||
update_option('igny8_email', $email);
|
||||
|
||||
// Store API key securely and also set access token to the API key for subsequent calls
|
||||
// Only store if it's not the placeholder
|
||||
if (!$is_placeholder) {
|
||||
|
||||
@@ -76,60 +76,27 @@ $webhook_logs = igny8_get_webhook_logs(array('limit' => 10));
|
||||
<div class="igny8-settings-card">
|
||||
<h2><?php _e('API Connection', 'igny8-bridge'); ?></h2>
|
||||
|
||||
<?php if (!$is_connected) : ?>
|
||||
<form method="post" action="">
|
||||
<?php wp_nonce_field('igny8_settings_nonce'); ?>
|
||||
|
||||
<table class="form-table">
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<label for="igny8_email"><?php _e('Email', 'igny8-bridge'); ?></label>
|
||||
</th>
|
||||
<td>
|
||||
<input
|
||||
type="email"
|
||||
id="igny8_email"
|
||||
name="igny8_email"
|
||||
value="<?php echo esc_attr($email); ?>"
|
||||
class="regular-text"
|
||||
required
|
||||
/>
|
||||
<p class="description">
|
||||
<?php _e('Your IGNY8 account email address.', 'igny8-bridge'); ?>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<label for="igny8_api_key"><?php _e('API Key', 'igny8-bridge'); ?></label>
|
||||
</th>
|
||||
<td>
|
||||
<input
|
||||
type="password"
|
||||
type="text"
|
||||
id="igny8_api_key"
|
||||
name="igny8_api_key"
|
||||
value="<?php echo esc_attr($api_key ? '********' : ''); ?>"
|
||||
value=""
|
||||
class="regular-text"
|
||||
placeholder="<?php _e('Paste your IGNY8 API key here (optional)', 'igny8-bridge'); ?>"
|
||||
/>
|
||||
<p class="description">
|
||||
<?php _e('If you have an API key from the IGNY8 SaaS app, paste it here to authenticate the bridge. Leave blank to use email/password.', 'igny8-bridge'); ?>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<label for="igny8_password"><?php _e('Password', 'igny8-bridge'); ?></label>
|
||||
</th>
|
||||
<td>
|
||||
<input
|
||||
type="password"
|
||||
id="igny8_password"
|
||||
name="igny8_password"
|
||||
class="regular-text"
|
||||
placeholder="<?php _e('Paste your IGNY8 API key here', 'igny8-bridge'); ?>"
|
||||
required
|
||||
/>
|
||||
<p class="description">
|
||||
<?php _e('Your IGNY8 account password.', 'igny8-bridge'); ?>
|
||||
<?php _e('If you have an API key from the IGNY8 SaaS app, paste it here to authenticate the bridge. Leave blank to use email/password.', 'igny8-bridge'); ?>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -137,14 +104,36 @@ $webhook_logs = igny8_get_webhook_logs(array('limit' => 10));
|
||||
|
||||
<?php submit_button(__('Connect to IGNY8', 'igny8-bridge'), 'primary', 'igny8_connect'); ?>
|
||||
</form>
|
||||
<?php else : ?>
|
||||
<table class="form-table">
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<label for="igny8_api_key"><?php _e('API Key', 'igny8-bridge'); ?></label>
|
||||
</th>
|
||||
<td>
|
||||
<input
|
||||
type="password"
|
||||
id="igny8_api_key"
|
||||
value="<?php echo esc_attr(str_repeat('•', min(strlen($api_key), 40))); ?>"
|
||||
class="regular-text"
|
||||
disabled
|
||||
style="background-color: #f0f0f0;"
|
||||
/>
|
||||
<p class="description">
|
||||
<?php _e('Connected with API key. Use the revoke button below to disconnect.', 'igny8-bridge'); ?>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<?php if ($api_key) : ?>
|
||||
<form method="post" action="" style="margin-top:15px;">
|
||||
<div style="margin-top: 15px;">
|
||||
<form method="post" action="" style="display: inline-block;">
|
||||
<?php wp_nonce_field('igny8_revoke_api_key'); ?>
|
||||
<button type="submit" name="igny8_revoke_api_key" class="button button-secondary" onclick="return confirm('<?php _e('Revoke stored API key? This will remove the key from this site.', 'igny8-bridge'); ?>');">
|
||||
<button type="submit" name="igny8_revoke_api_key" class="button button-secondary" onclick="return confirm('<?php _e('Revoke API key? This will disconnect the plugin from IGNY8.', 'igny8-bridge'); ?>');">
|
||||
<?php _e('Revoke API Key', 'igny8-bridge'); ?>
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
@@ -156,72 +145,37 @@ $webhook_logs = igny8_get_webhook_logs(array('limit' => 10));
|
||||
<?php settings_fields('igny8_bridge_connection'); ?>
|
||||
|
||||
<table class="form-table">
|
||||
<tr>
|
||||
<th scope="row"><?php _e('Connection Status', 'igny8-bridge'); ?></th>
|
||||
<td>
|
||||
<?php if ($connection_enabled) : ?>
|
||||
<span class="igny8-status-connected">
|
||||
<?php _e('Connected & Active', 'igny8-bridge'); ?>
|
||||
</span>
|
||||
<?php else : ?>
|
||||
<span class="igny8-status-disconnected">
|
||||
<?php _e('Connected but Disabled', 'igny8-bridge'); ?>
|
||||
</span>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<label for="igny8_connection_enabled"><?php _e('Enable Sync Operations', 'igny8-bridge'); ?></label>
|
||||
<label for="igny8_connection_enabled"><?php _e('Enable Communication', 'igny8-bridge'); ?></label>
|
||||
</th>
|
||||
<td>
|
||||
<label>
|
||||
<label class="igny8-toggle-wrapper">
|
||||
<input
|
||||
type="checkbox"
|
||||
id="igny8_connection_enabled"
|
||||
name="igny8_connection_enabled"
|
||||
value="1"
|
||||
<?php checked($connection_enabled, 1); ?>
|
||||
class="igny8-toggle-input"
|
||||
/>
|
||||
<?php _e('Allow sending and receiving data from IGNY8 SaaS', 'igny8-bridge'); ?>
|
||||
<span class="igny8-toggle-slider"></span>
|
||||
<span class="igny8-toggle-label">
|
||||
<?php if ($connection_enabled) : ?>
|
||||
<strong style="color: #10B981;"><?php _e('Connected', 'igny8-bridge'); ?></strong>
|
||||
<?php else : ?>
|
||||
<strong style="color: #6B7280;"><?php _e('Disconnected', 'igny8-bridge'); ?></strong>
|
||||
<?php endif; ?>
|
||||
</span>
|
||||
</label>
|
||||
<p class="description">
|
||||
<?php _e('When disabled, all sync operations are stopped but your credentials and settings are preserved.', 'igny8-bridge'); ?>
|
||||
<?php _e('Controls whether the plugin can communicate with IGNY8. API key stays connected but no data is synced when disabled.', 'igny8-bridge'); ?>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<label for="igny8_enable_two_way_sync"><?php _e('Enable Two-Way Sync', 'igny8-bridge'); ?></label>
|
||||
</th>
|
||||
<td>
|
||||
<label>
|
||||
<input
|
||||
type="checkbox"
|
||||
id="igny8_enable_two_way_sync"
|
||||
name="igny8_enable_two_way_sync"
|
||||
value="1"
|
||||
<?php checked($two_way_sync, 1); ?>
|
||||
/>
|
||||
<?php _e('Allow bi-directional sync (IGNY8 ↔ WordPress). When disabled, outbound/inbound sync actions are suppressed but API endpoints remain accessible.', 'igny8-bridge'); ?>
|
||||
</label>
|
||||
</td>
|
||||
</tr>
|
||||
<?php if ($email) : ?>
|
||||
<tr>
|
||||
<th scope="row"><?php _e('Email', 'igny8-bridge'); ?></th>
|
||||
<td><?php echo esc_html($email); ?></td>
|
||||
</tr>
|
||||
<?php endif; ?>
|
||||
<?php if ($site_id) : ?>
|
||||
<tr>
|
||||
<th scope="row"><?php _e('Site ID', 'igny8-bridge'); ?></th>
|
||||
<td><?php echo esc_html($site_id); ?></td>
|
||||
</tr>
|
||||
<?php endif; ?>
|
||||
</table>
|
||||
|
||||
<?php submit_button(__('Save Connection Settings', 'igny8-bridge')); ?>
|
||||
<?php submit_button(__('Save Settings', 'igny8-bridge')); ?>
|
||||
</form>
|
||||
|
||||
<p>
|
||||
@@ -487,69 +441,6 @@ $webhook_logs = igny8_get_webhook_logs(array('limit' => 10));
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="igny8-settings-card">
|
||||
<h2><?php _e('Link Queue', 'igny8-bridge'); ?></h2>
|
||||
|
||||
<?php if (!empty($pending_links)) : ?>
|
||||
<p>
|
||||
<strong><?php echo count($pending_links); ?></strong> <?php _e('link(s) pending insertion', 'igny8-bridge'); ?>
|
||||
</p>
|
||||
<table class="wp-list-table widefat fixed striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><?php _e('Post ID', 'igny8-bridge'); ?></th>
|
||||
<th><?php _e('Anchor', 'igny8-bridge'); ?></th>
|
||||
<th><?php _e('Target URL', 'igny8-bridge'); ?></th>
|
||||
<th><?php _e('Status', 'igny8-bridge'); ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach (array_slice($pending_links, 0, 10) as $link) : ?>
|
||||
<tr>
|
||||
<td><?php echo esc_html($link['post_id']); ?></td>
|
||||
<td><?php echo esc_html($link['anchor']); ?></td>
|
||||
<td><code><?php echo esc_html($link['target_url']); ?></code></td>
|
||||
<td><?php echo esc_html($link['status']); ?></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
<?php else : ?>
|
||||
<p><?php _e('No pending links in queue.', 'igny8-bridge'); ?></p>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<div class="igny8-settings-card">
|
||||
<h2><?php _e('Recent Webhook Activity', 'igny8-bridge'); ?></h2>
|
||||
|
||||
<?php if (!empty($webhook_logs)) : ?>
|
||||
<table class="wp-list-table widefat fixed striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><?php _e('Event', 'igny8-bridge'); ?></th>
|
||||
<th><?php _e('Status', 'igny8-bridge'); ?></th>
|
||||
<th><?php _e('Time', 'igny8-bridge'); ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($webhook_logs as $log) : ?>
|
||||
<tr>
|
||||
<td><?php echo esc_html($log['event']); ?></td>
|
||||
<td>
|
||||
<span class="igny8-status-badge igny8-status-<?php echo esc_attr(strtolower($log['status'])); ?>">
|
||||
<?php echo esc_html($log['status']); ?>
|
||||
</span>
|
||||
</td>
|
||||
<td><?php echo esc_html(date_i18n(get_option('date_format') . ' ' . get_option('time_format'), strtotime($log['received_at']))); ?></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
<?php else : ?>
|
||||
<p><?php _e('No webhook activity yet.', 'igny8-bridge'); ?></p>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="igny8-settings-card">
|
||||
@@ -570,24 +461,134 @@ $webhook_logs = igny8_get_webhook_logs(array('limit' => 10));
|
||||
<div class="notice notice-warning inline">
|
||||
<p>
|
||||
<strong><?php _e('Connection Disabled', 'igny8-bridge'); ?></strong><br />
|
||||
<?php _e('Sync operations are currently disabled. Enable "Enable Sync Operations" above to use these features.', 'igny8-bridge'); ?>
|
||||
<?php _e('Sync operations are currently disabled. Enable "Enable Communication" above to use these features.', 'igny8-bridge'); ?>
|
||||
</p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="igny8-sync-actions">
|
||||
<button type="button" id="igny8-sync-posts" class="button button-secondary" <?php disabled(!$connection_enabled); ?>>
|
||||
<?php _e('Sync Posts to IGNY8', 'igny8-bridge'); ?>
|
||||
</button>
|
||||
<button type="button" id="igny8-sync-taxonomies" class="button button-secondary" <?php disabled(!$connection_enabled); ?>>
|
||||
<?php _e('Sync Taxonomies', 'igny8-bridge'); ?>
|
||||
</button>
|
||||
<button type="button" id="igny8-sync-from-igny8" class="button button-secondary" <?php disabled(!$connection_enabled); ?>>
|
||||
<?php _e('Sync from IGNY8', 'igny8-bridge'); ?>
|
||||
</button>
|
||||
<button type="button" id="igny8-collect-site-data" class="button button-primary" <?php disabled(!$connection_enabled); ?>>
|
||||
<?php _e('Collect & Send Site Data', 'igny8-bridge'); ?>
|
||||
</button>
|
||||
<?php
|
||||
// Get counts for sync operations
|
||||
$post_count = wp_count_posts('post');
|
||||
$page_count = wp_count_posts('page');
|
||||
$product_count = class_exists('WooCommerce') ? wp_count_posts('product') : null;
|
||||
$total_posts = $post_count->publish + $page_count->publish;
|
||||
if ($product_count) $total_posts += $product_count->publish;
|
||||
|
||||
$taxonomies = get_taxonomies(['public' => true], 'objects');
|
||||
$taxonomy_count = 0;
|
||||
foreach ($taxonomies as $taxonomy) {
|
||||
$taxonomy_count += wp_count_terms(['taxonomy' => $taxonomy->name, 'hide_empty' => false]);
|
||||
}
|
||||
?>
|
||||
|
||||
<div class="igny8-sync-grid">
|
||||
<div class="igny8-sync-card">
|
||||
<div class="igny8-sync-icon">
|
||||
<svg width="24" height="24" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"/>
|
||||
</svg>
|
||||
</div>
|
||||
<h3><?php _e('Sync Posts to IGNY8', 'igny8-bridge'); ?></h3>
|
||||
<p class="igny8-sync-description">
|
||||
<?php printf(
|
||||
__('Send %d posts, %d pages%s from WordPress to IGNY8', 'igny8-bridge'),
|
||||
$post_count->publish,
|
||||
$page_count->publish,
|
||||
$product_count ? sprintf(', %d products', $product_count->publish) : ''
|
||||
); ?>
|
||||
</p>
|
||||
<p class="igny8-sync-meta">
|
||||
<?php if ($last_site_sync) : ?>
|
||||
<span class="igny8-sync-time">⏱ <?php echo sprintf(__('Last sync: %s', 'igny8-bridge'), human_time_diff($last_site_sync, current_time('timestamp')) . ' ago'); ?></span>
|
||||
<?php else : ?>
|
||||
<span class="igny8-sync-time">⏱ <?php _e('Never synced', 'igny8-bridge'); ?></span>
|
||||
<?php endif; ?>
|
||||
</p>
|
||||
<button type="button" id="igny8-sync-posts" class="button button-primary igny8-sync-button" <?php disabled(!$connection_enabled); ?>>
|
||||
<span class="button-text"><?php _e('Sync Now', 'igny8-bridge'); ?></span>
|
||||
<span class="button-loading" style="display: none;">
|
||||
<span class="spinner is-active"></span> <?php _e('Syncing...', 'igny8-bridge'); ?>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="igny8-sync-card">
|
||||
<div class="igny8-sync-icon">
|
||||
<svg width="24" height="24" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M7 7h.01M7 3h5c.512 0 1.024.195 1.414.586l7 7a2 2 0 010 2.828l-7 7a2 2 0 01-2.828 0l-7-7A1.994 1.994 0 013 12V7a4 4 0 014-4z"/>
|
||||
</svg>
|
||||
</div>
|
||||
<h3><?php _e('Sync Taxonomies', 'igny8-bridge'); ?></h3>
|
||||
<p class="igny8-sync-description">
|
||||
<?php printf(
|
||||
__('Sync %d taxonomy terms (categories, tags, sectors, clusters) to IGNY8', 'igny8-bridge'),
|
||||
$taxonomy_count
|
||||
); ?>
|
||||
</p>
|
||||
<p class="igny8-sync-meta">
|
||||
<?php if ($last_taxonomy_sync) : ?>
|
||||
<span class="igny8-sync-time">⏱ <?php echo sprintf(__('Last sync: %s', 'igny8-bridge'), human_time_diff($last_taxonomy_sync, current_time('timestamp')) . ' ago'); ?></span>
|
||||
<?php else : ?>
|
||||
<span class="igny8-sync-time">⏱ <?php _e('Never synced', 'igny8-bridge'); ?></span>
|
||||
<?php endif; ?>
|
||||
</p>
|
||||
<button type="button" id="igny8-sync-taxonomies" class="button button-primary igny8-sync-button" <?php disabled(!$connection_enabled); ?>>
|
||||
<span class="button-text"><?php _e('Sync Now', 'igny8-bridge'); ?></span>
|
||||
<span class="button-loading" style="display: none;">
|
||||
<span class="spinner is-active"></span> <?php _e('Syncing...', 'igny8-bridge'); ?>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="igny8-sync-card">
|
||||
<div class="igny8-sync-icon">
|
||||
<svg width="24" height="24" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-8l-4-4m0 0L8 8m4-4v12"/>
|
||||
</svg>
|
||||
</div>
|
||||
<h3><?php _e('Sync from IGNY8', 'igny8-bridge'); ?></h3>
|
||||
<p class="igny8-sync-description">
|
||||
<?php _e('Import new content, tasks, and updates from IGNY8 AI OS to WordPress', 'igny8-bridge'); ?>
|
||||
</p>
|
||||
<p class="igny8-sync-meta">
|
||||
<?php if ($last_writer_sync) : ?>
|
||||
<span class="igny8-sync-time">⏱ <?php echo sprintf(__('Last sync: %s', 'igny8-bridge'), human_time_diff($last_writer_sync, current_time('timestamp')) . ' ago'); ?></span>
|
||||
<?php else : ?>
|
||||
<span class="igny8-sync-time">⏱ <?php _e('Never synced', 'igny8-bridge'); ?></span>
|
||||
<?php endif; ?>
|
||||
</p>
|
||||
<button type="button" id="igny8-sync-from-igny8" class="button button-primary igny8-sync-button" <?php disabled(!$connection_enabled); ?>>
|
||||
<span class="button-text"><?php _e('Sync Now', 'igny8-bridge'); ?></span>
|
||||
<span class="button-loading" style="display: none;">
|
||||
<span class="spinner is-active"></span> <?php _e('Syncing...', 'igny8-bridge'); ?>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="igny8-sync-card igny8-sync-card-highlight">
|
||||
<div class="igny8-sync-icon">
|
||||
<svg width="24" height="24" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M21 12a9 9 0 01-9 9m9-9a9 9 0 00-9-9m9 9H3m9 9a9 9 0 01-9-9m9 9c1.657 0 3-4.03 3-9s-1.343-9-3-9m0 18c-1.657 0-3-4.03-3-9s1.343-9 3-9m-9 9a9 9 0 019-9"/>
|
||||
</svg>
|
||||
</div>
|
||||
<h3><?php _e('Collect & Send Site Data', 'igny8-bridge'); ?></h3>
|
||||
<p class="igny8-sync-description">
|
||||
<?php _e('Perform full site scan: collect structure, links, SEO data, and send comprehensive report to IGNY8', 'igny8-bridge'); ?>
|
||||
</p>
|
||||
<p class="igny8-sync-meta">
|
||||
<?php if ($last_full_site_scan) : ?>
|
||||
<span class="igny8-sync-time">⏱ <?php echo sprintf(__('Last scan: %s', 'igny8-bridge'), human_time_diff($last_full_site_scan, current_time('timestamp')) . ' ago'); ?></span>
|
||||
<?php else : ?>
|
||||
<span class="igny8-sync-time">⏱ <?php _e('Never scanned', 'igny8-bridge'); ?></span>
|
||||
<?php endif; ?>
|
||||
</p>
|
||||
<button type="button" id="igny8-collect-site-data" class="button button-primary igny8-sync-button" <?php disabled(!$connection_enabled); ?>>
|
||||
<span class="button-text"><?php _e('Start Full Scan', 'igny8-bridge'); ?></span>
|
||||
<span class="button-loading" style="display: none;">
|
||||
<span class="spinner is-active"></span> <?php _e('Scanning...', 'igny8-bridge'); ?>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="igny8-sync-status" class="igny8-sync-status"></div>
|
||||
@@ -597,15 +598,102 @@ $webhook_logs = igny8_get_webhook_logs(array('limit' => 10));
|
||||
<h2><?php _e('Sync Statistics', 'igny8-bridge'); ?></h2>
|
||||
|
||||
<div class="igny8-stats-grid">
|
||||
<div class="igny8-stat-item">
|
||||
<div class="igny8-stat-label"><?php _e('Synced Posts', 'igny8-bridge'); ?></div>
|
||||
<div class="igny8-stat-value" id="igny8-stat-posts">-</div>
|
||||
<div class="igny8-stat-card">
|
||||
<div class="igny8-stat-icon" style="background-color: #3B82F6;">
|
||||
<svg width="20" height="20" fill="none" stroke="white" stroke-width="2" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="igny8-stat-content">
|
||||
<div class="igny8-stat-label"><?php _e('Synced Posts', 'igny8-bridge'); ?></div>
|
||||
<div class="igny8-stat-value" id="igny8-stat-posts"><?php echo number_format($total_posts); ?></div>
|
||||
<div class="igny8-stat-meta"><?php printf(__('%d posts · %d pages', 'igny8-bridge'), $post_count->publish, $page_count->publish); ?></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="igny8-stat-item">
|
||||
<div class="igny8-stat-label"><?php _e('Last Sync', 'igny8-bridge'); ?></div>
|
||||
<div class="igny8-stat-value" id="igny8-stat-last-sync">-</div>
|
||||
|
||||
<div class="igny8-stat-card">
|
||||
<div class="igny8-stat-icon" style="background-color: #10B981;">
|
||||
<svg width="20" height="20" fill="none" stroke="white" stroke-width="2" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M7 7h.01M7 3h5c.512 0 1.024.195 1.414.586l7 7a2 2 0 010 2.828l-7 7a2 2 0 01-2.828 0l-7-7A1.994 1.994 0 013 12V7a4 4 0 014-4z"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="igny8-stat-content">
|
||||
<div class="igny8-stat-label"><?php _e('Taxonomy Terms', 'igny8-bridge'); ?></div>
|
||||
<div class="igny8-stat-value" id="igny8-stat-taxonomies"><?php echo number_format($taxonomy_count); ?></div>
|
||||
<div class="igny8-stat-meta"><?php _e('Categories, tags, sectors', 'igny8-bridge'); ?></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="igny8-stat-card">
|
||||
<div class="igny8-stat-icon" style="background-color: #F59E0B;">
|
||||
<svg width="20" height="20" fill="none" stroke="white" stroke-width="2" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="igny8-stat-content">
|
||||
<div class="igny8-stat-label"><?php _e('Last Sync', 'igny8-bridge'); ?></div>
|
||||
<div class="igny8-stat-value" id="igny8-stat-last-sync">
|
||||
<?php if ($last_site_sync) : ?>
|
||||
<?php echo human_time_diff($last_site_sync, current_time('timestamp')); ?> <?php _e('ago', 'igny8-bridge'); ?>
|
||||
<?php else : ?>
|
||||
<?php _e('Never', 'igny8-bridge'); ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<div class="igny8-stat-meta">
|
||||
<?php if ($last_site_sync) : ?>
|
||||
<?php echo date_i18n(get_option('date_format') . ' ' . get_option('time_format'), $last_site_sync); ?>
|
||||
<?php else : ?>
|
||||
<?php _e('No sync performed yet', 'igny8-bridge'); ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="igny8-stat-card">
|
||||
<div class="igny8-stat-icon" style="background-color: #8B5CF6;">
|
||||
<svg width="20" height="20" fill="none" stroke="white" stroke-width="2" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M13 10V3L4 14h7v7l9-11h-7z"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="igny8-stat-content">
|
||||
<div class="igny8-stat-label"><?php _e('Connection Status', 'igny8-bridge'); ?></div>
|
||||
<div class="igny8-stat-value">
|
||||
<?php if ($connection_enabled) : ?>
|
||||
<span style="color: #10B981; font-size: 18px; font-weight: 600;"><?php _e('Active', 'igny8-bridge'); ?></span>
|
||||
<?php else : ?>
|
||||
<span style="color: #6B7280; font-size: 18px; font-weight: 600;"><?php _e('Disabled', 'igny8-bridge'); ?></span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<div class="igny8-stat-meta">
|
||||
<?php if ($last_health_check) : ?>
|
||||
<?php _e('Last checked:', 'igny8-bridge'); ?> <?php echo human_time_diff($last_health_check, current_time('timestamp')); ?> <?php _e('ago', 'igny8-bridge'); ?>
|
||||
<?php else : ?>
|
||||
<?php _e('Health check pending', 'igny8-bridge'); ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php if ($last_semantic_map && !empty($semantic_summary)) : ?>
|
||||
<div class="igny8-semantic-summary">
|
||||
<h3><?php _e('Latest Site Analysis', 'igny8-bridge'); ?></h3>
|
||||
<div class="igny8-semantic-stats">
|
||||
<div class="igny8-semantic-stat">
|
||||
<span class="value"><?php echo number_format($semantic_summary['sectors'] ?? 0); ?></span>
|
||||
<span class="label"><?php _e('Sectors', 'igny8-bridge'); ?></span>
|
||||
</div>
|
||||
<div class="igny8-semantic-stat">
|
||||
<span class="value"><?php echo number_format($semantic_summary['keywords'] ?? 0); ?></span>
|
||||
<span class="label"><?php _e('Keywords', 'igny8-bridge'); ?></span>
|
||||
</div>
|
||||
<div class="igny8-semantic-stat">
|
||||
<span class="value"><?php echo human_time_diff($last_semantic_map, current_time('timestamp')); ?></span>
|
||||
<span class="label"><?php _e('ago', 'igny8-bridge'); ?></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user