versioning and wp plugin updates

This commit is contained in:
IGNY8 VPS (Salman)
2026-01-10 00:26:00 +00:00
parent 0ea3a30909
commit a86524a6b1
24 changed files with 2011 additions and 101 deletions

View File

@@ -845,3 +845,9 @@
flex-direction: column;
}
}
/* ============================================
Hide 3rd party clutter (Sellvia banner)
============================================ */
.sellvia-banner.notice.notice-info {
display: none;
}

View File

@@ -0,0 +1,454 @@
/**
* IGNY8 WordPress Bridge - Modern Design System
* Based on main app design tokens
*/
/* ===================================================================
DESIGN TOKENS - Matching Main App
=================================================================== */
:root {
/* Primary Colors */
--igny8-primary: #3B82F6;
--igny8-success: #10B981;
--igny8-warning: #F59E0B;
--igny8-danger: #DC2626;
--igny8-purple: #F63B82;
--igny8-gray-base: #031D48;
/* Derived Colors */
--igny8-primary-dark: #2563EB;
--igny8-primary-light: #60A5FA;
--igny8-primary-subtle: #DBEAFE;
/* Background Colors */
--igny8-navy: #020617;
--igny8-navy-light: #0F172A;
--igny8-surface: #F8FAFC;
--igny8-panel: #FFFFFF;
--igny8-panel-alt: #F1F5F9;
/* Text Colors */
--igny8-text: #1E293B;
--igny8-text-dim: #475569;
--igny8-text-light: #94A3B8;
--igny8-stroke: #E2E8F0;
/* Border Radius */
--igny8-radius-sm: 4px;
--igny8-radius-base: 6px;
--igny8-radius-md: 8px;
--igny8-radius-lg: 12px;
/* Shadows */
--igny8-shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
--igny8-shadow-base: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06);
--igny8-shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
--igny8-shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
/* Gradients */
--igny8-gradient-primary: linear-gradient(135deg, var(--igny8-primary) 0%, var(--igny8-primary-dark) 100%);
}
/* ===================================================================
LAYOUT - New Sidebar Structure
=================================================================== */
.igny8-admin-wrapper {
display: flex;
min-height: 100vh;
background: var(--igny8-surface);
margin-left: -20px;
margin-top: -10px;
}
.igny8-sidebar {
width: 260px;
background: var(--igny8-panel);
border-right: 1px solid var(--igny8-stroke);
padding: 24px 0;
position: fixed;
height: 100vh;
overflow-y: auto;
}
.igny8-sidebar-logo {
padding: 0 24px 24px;
border-bottom: 1px solid var(--igny8-stroke);
margin-bottom: 24px;
}
.igny8-sidebar-logo img {
height: 32px;
width: auto;
}
.igny8-sidebar-nav {
list-style: none;
margin: 0;
padding: 0 12px;
}
.igny8-sidebar-nav li {
margin-bottom: 4px;
}
.igny8-sidebar-nav a {
display: flex;
align-items: center;
padding: 10px 12px;
color: var(--igny8-text-dim);
text-decoration: none;
border-radius: var(--igny8-radius-base);
font-size: 14px;
font-weight: 500;
transition: all 0.2s ease;
}
.igny8-sidebar-nav a:hover {
background: var(--igny8-surface);
color: var(--igny8-text);
}
.igny8-sidebar-nav a.active {
background: var(--igny8-primary-subtle);
color: var(--igny8-primary);
}
.igny8-sidebar-nav svg {
width: 18px;
height: 18px;
margin-right: 12px;
flex-shrink: 0;
}
.igny8-main-content {
margin-left: 260px;
flex: 1;
padding: 32px 40px;
max-width: 1400px;
}
/* ===================================================================
HEADER - Minimal Design
=================================================================== */
.igny8-page-header {
margin-bottom: 32px;
}
.igny8-page-header h1 {
font-size: 28px;
font-weight: 600;
color: var(--igny8-text);
margin: 0 0 8px 0;
}
.igny8-page-header p {
color: var(--igny8-text-dim);
font-size: 14px;
margin: 0;
}
/* ===================================================================
CARDS - Modern Panel Design
=================================================================== */
.igny8-card {
background: var(--igny8-panel);
border-radius: var(--igny8-radius-md);
padding: 24px;
box-shadow: var(--igny8-shadow-base);
margin-bottom: 24px;
border: 1px solid var(--igny8-stroke);
}
.igny8-card-header {
display: flex;
align-items: center;
margin-bottom: 20px;
padding-bottom: 16px;
border-bottom: 1px solid var(--igny8-stroke);
}
.igny8-card-header h2 {
font-size: 18px;
font-weight: 600;
color: var(--igny8-text);
margin: 0;
display: flex;
align-items: center;
}
.igny8-card-header svg {
width: 20px;
height: 20px;
margin-right: 10px;
color: var(--igny8-primary);
}
/* ===================================================================
FORM ELEMENTS - Modern Inputs
=================================================================== */
.igny8-form-group {
margin-bottom: 20px;
}
.igny8-form-group label {
display: block;
font-size: 14px;
font-weight: 500;
color: var(--igny8-text);
margin-bottom: 8px;
}
.igny8-form-group input[type="text"],
.igny8-form-group input[type="password"],
.igny8-form-group input[type="number"],
.igny8-form-group textarea,
.igny8-form-group select {
width: 100%;
padding: 10px 12px;
font-size: 14px;
border: 1px solid var(--igny8-stroke);
border-radius: var(--igny8-radius-base);
background: var(--igny8-panel);
color: var(--igny8-text);
transition: all 0.2s ease;
}
.igny8-form-group input:focus,
.igny8-form-group textarea:focus,
.igny8-form-group select:focus {
outline: none;
border-color: var(--igny8-primary);
box-shadow: 0 0 0 3px var(--igny8-primary-subtle);
}
.igny8-form-help {
font-size: 13px;
color: var(--igny8-text-light);
margin-top: 6px;
}
/* ===================================================================
BUTTONS - Modern Button System
=================================================================== */
.igny8-btn {
display: inline-flex;
align-items: center;
justify-content: center;
padding: 10px 16px;
font-size: 14px;
font-weight: 500;
border-radius: var(--igny8-radius-base);
border: none;
cursor: pointer;
transition: all 0.2s ease;
text-decoration: none;
}
.igny8-btn-primary {
background: var(--igny8-primary);
color: white;
}
.igny8-btn-primary:hover {
background: var(--igny8-primary-dark);
transform: translateY(-1px);
box-shadow: var(--igny8-shadow-md);
}
.igny8-btn-secondary {
background: var(--igny8-surface);
color: var(--igny8-text);
border: 1px solid var(--igny8-stroke);
}
.igny8-btn-secondary:hover {
background: var(--igny8-panel-alt);
}
.igny8-btn-danger {
background: var(--igny8-danger);
color: white;
}
.igny8-btn-danger:hover {
background: #B91C1C;
}
.igny8-btn svg {
width: 16px;
height: 16px;
margin-right: 8px;
}
/* ===================================================================
STATUS INDICATORS
=================================================================== */
.igny8-status {
display: inline-flex;
align-items: center;
padding: 4px 12px;
border-radius: 12px;
font-size: 13px;
font-weight: 500;
}
.igny8-status-connected {
background: rgba(16, 185, 129, 0.1);
color: var(--igny8-success);
}
.igny8-status-disconnected {
background: rgba(220, 38, 38, 0.1);
color: var(--igny8-danger);
}
.igny8-status-indicator {
width: 8px;
height: 8px;
border-radius: 50%;
margin-right: 8px;
}
.igny8-status-connected .igny8-status-indicator {
background: var(--igny8-success);
box-shadow: 0 0 0 3px rgba(16, 185, 129, 0.2);
}
.igny8-status-disconnected .igny8-status-indicator {
background: var(--igny8-danger);
box-shadow: 0 0 0 3px rgba(220, 38, 38, 0.2);
}
/* ===================================================================
GRID SYSTEM
=================================================================== */
.igny8-grid {
display: grid;
gap: 24px;
}
.igny8-grid-2 {
grid-template-columns: repeat(2, 1fr);
}
.igny8-grid-3 {
grid-template-columns: repeat(3, 1fr);
}
@media (max-width: 1024px) {
.igny8-grid-2,
.igny8-grid-3 {
grid-template-columns: 1fr;
}
.igny8-sidebar {
width: 220px;
}
.igny8-main-content {
margin-left: 220px;
}
}
/* ===================================================================
TABLES
=================================================================== */
.igny8-table {
width: 100%;
border-collapse: collapse;
}
.igny8-table th {
text-align: left;
padding: 12px;
font-size: 13px;
font-weight: 600;
color: var(--igny8-text-dim);
text-transform: uppercase;
letter-spacing: 0.5px;
border-bottom: 2px solid var(--igny8-stroke);
}
.igny8-table td {
padding: 12px;
border-bottom: 1px solid var(--igny8-stroke);
color: var(--igny8-text);
}
.igny8-table tr:last-child td {
border-bottom: none;
}
/* ===================================================================
ALERTS & MESSAGES
=================================================================== */
.igny8-alert {
padding: 16px;
border-radius: var(--igny8-radius-base);
margin-bottom: 20px;
display: flex;
align-items: flex-start;
}
.igny8-alert svg {
width: 20px;
height: 20px;
margin-right: 12px;
flex-shrink: 0;
margin-top: 2px;
}
.igny8-alert-success {
background: rgba(16, 185, 129, 0.1);
border: 1px solid rgba(16, 185, 129, 0.3);
color: #065F46;
}
.igny8-alert-warning {
background: rgba(245, 158, 11, 0.1);
border: 1px solid rgba(245, 158, 11, 0.3);
color: #92400E;
}
.igny8-alert-danger {
background: rgba(220, 38, 38, 0.1);
border: 1px solid rgba(220, 38, 38, 0.3);
color: #991B1B;
}
/* ===================================================================
LOADING & SPINNERS
=================================================================== */
.igny8-spinner {
display: inline-block;
width: 20px;
height: 20px;
border: 2px solid var(--igny8-stroke);
border-top-color: var(--igny8-primary);
border-radius: 50%;
animation: igny8-spin 0.6s linear infinite;
}
@keyframes igny8-spin {
to { transform: rotate(360deg); }
}
/* ===================================================================
OVERRIDE WORDPRESS ADMIN STYLES
=================================================================== */
.igny8-admin-page .wrap {
margin: 0;
padding: 0;
}
.igny8-admin-page .wrap > h1 {
display: none;
}
/* Hide WordPress notices on our pages */
.igny8-admin-page .notice,
.igny8-admin-page .updated,
.igny8-admin-page .error {
margin-left: 260px;
margin-top: 20px;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 320 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

View File

@@ -49,12 +49,70 @@ class Igny8Admin {
* Add admin menu pages
*/
public function add_menu_pages() {
add_options_page(
__('IGNY8 API Settings', 'igny8-bridge'),
__('IGNY8 API', 'igny8-bridge'),
// Add main menu page
add_menu_page(
__('IGNY8', 'igny8-bridge'),
__('IGNY8', 'igny8-bridge'),
'manage_options',
'igny8-settings',
array($this, 'render_settings_page')
'igny8-dashboard',
array($this, 'render_page'),
plugins_url('admin/assets/images/logo-icon.png', IGNY8_BRIDGE_PLUGIN_FILE),
58
);
// Add submenu pages
add_submenu_page(
'igny8-dashboard',
__('Dashboard', 'igny8-bridge'),
__('Dashboard', 'igny8-bridge'),
'manage_options',
'igny8-dashboard',
array($this, 'render_page')
);
add_submenu_page(
'igny8-dashboard',
__('Connection', 'igny8-bridge'),
__('Connection', 'igny8-bridge'),
'manage_options',
'igny8-connection',
array($this, 'render_page')
);
add_submenu_page(
'igny8-dashboard',
__('Controls', 'igny8-bridge'),
__('Controls', 'igny8-bridge'),
'manage_options',
'igny8-controls',
array($this, 'render_page')
);
add_submenu_page(
'igny8-dashboard',
__('Sync', 'igny8-bridge'),
__('Sync', 'igny8-bridge'),
'manage_options',
'igny8-sync',
array($this, 'render_page')
);
add_submenu_page(
'igny8-dashboard',
__('Data', 'igny8-bridge'),
__('Data', 'igny8-bridge'),
'manage_options',
'igny8-data',
array($this, 'render_page')
);
add_submenu_page(
'igny8-dashboard',
__('Logs', 'igny8-bridge'),
__('Logs', 'igny8-bridge'),
'manage_options',
'igny8-logs',
array($this, 'render_page')
);
}
@@ -120,8 +178,17 @@ class Igny8Admin {
* @param string $hook Current admin page hook
*/
public function enqueue_scripts($hook) {
// Enqueue on settings page
if ($hook === 'settings_page_igny8-settings') {
// Enqueue on IGNY8 pages
if (strpos($hook, 'igny8-') !== false || strpos($hook, 'toplevel_page_igny8') !== false) {
// Load modern design system CSS
wp_enqueue_style(
'igny8-modern-style',
IGNY8_BRIDGE_PLUGIN_URL . 'admin/assets/css/igny8-modern.css',
array(),
IGNY8_BRIDGE_VERSION
);
// Load legacy admin CSS for backwards compatibility
wp_enqueue_style(
'igny8-admin-style',
IGNY8_BRIDGE_PLUGIN_URL . 'admin/assets/css/admin.css',
@@ -171,10 +238,10 @@ class Igny8Admin {
}
/**
* Render settings page
* Render page based on current menu slug
*/
public function render_settings_page() {
// Handle form submission (use wp_verify_nonce to avoid wp_die on failure)
public function render_page() {
// Handle form submissions for connection page
if (isset($_POST['igny8_connect'])) {
if (empty($_POST['_wpnonce']) || !wp_verify_nonce($_POST['_wpnonce'], 'igny8_settings_nonce')) {
add_settings_error(
@@ -188,7 +255,7 @@ class Igny8Admin {
}
}
// Handle revoke API key (use wp_verify_nonce)
// Handle revoke API key
if (isset($_POST['igny8_revoke_api_key'])) {
if (empty($_POST['_wpnonce']) || !wp_verify_nonce($_POST['_wpnonce'], 'igny8_revoke_api_key')) {
add_settings_error(
@@ -207,11 +274,55 @@ class Igny8Admin {
);
}
}
// Webhook secret regeneration removed - using API key only
// Include settings template
include IGNY8_BRIDGE_PLUGIN_DIR . 'admin/settings.php';
// Determine which page to render
$page = isset($_GET['page']) ? sanitize_text_field($_GET['page']) : 'igny8-dashboard';
// Add wrapper class for modern design
echo '<div class="igny8-admin-page">';
// Include the appropriate page template
$template_file = '';
switch ($page) {
case 'igny8-dashboard':
$template_file = IGNY8_BRIDGE_PLUGIN_DIR . 'admin/pages/dashboard.php';
break;
case 'igny8-connection':
$template_file = IGNY8_BRIDGE_PLUGIN_DIR . 'admin/pages/connection.php';
break;
case 'igny8-controls':
$template_file = IGNY8_BRIDGE_PLUGIN_DIR . 'admin/pages/controls.php';
break;
case 'igny8-sync':
$template_file = IGNY8_BRIDGE_PLUGIN_DIR . 'admin/pages/sync.php';
break;
case 'igny8-data':
$template_file = IGNY8_BRIDGE_PLUGIN_DIR . 'admin/pages/data.php';
break;
case 'igny8-logs':
$template_file = IGNY8_BRIDGE_PLUGIN_DIR . 'admin/pages/logs.php';
break;
default:
$template_file = IGNY8_BRIDGE_PLUGIN_DIR . 'admin/pages/dashboard.php';
}
// If the template file doesn't exist, fall back to the old settings page
if (file_exists($template_file)) {
include $template_file;
} else {
// Fallback to old settings page during transition
include IGNY8_BRIDGE_PLUGIN_DIR . 'admin/settings.php';
}
echo '</div>';
}
/**
* Render settings page - DEPRECATED, keeping for backwards compatibility
*/
public function render_settings_page() {
// Redirect to new render_page method
$this->render_page();
}
/**

View File

@@ -0,0 +1,2 @@
</main>
</div>

View File

@@ -0,0 +1,111 @@
<?php
/**
* Modern Layout Wrapper
*
* This template provides the sidebar navigation and layout structure for all IGNY8 admin pages.
* Each page template should start by including this file.
*
* @package Igny8Bridge
*/
// Prevent direct access
if (!defined('ABSPATH')) {
exit;
}
// Get current page
$current_page = isset($_GET['page']) ? sanitize_text_field($_GET['page']) : 'igny8-dashboard';
$api_key = get_option('igny8_api_key');
$is_connected = !empty($api_key);
?>
<div class="igny8-admin-wrapper">
<!-- Sidebar Navigation -->
<aside class="igny8-sidebar">
<div class="igny8-sidebar-logo">
<img src="<?php echo esc_url(plugins_url('assets/images/IGNY8_DARK_LOGO.png', __FILE__)); ?>" alt="IGNY8" />
</div>
<nav>
<ul class="igny8-sidebar-nav">
<li>
<a href="<?php echo esc_url(admin_url('admin.php?page=igny8-dashboard')); ?>"
class="<?php echo ($current_page === 'igny8-dashboard') ? 'active' : ''; ?>">
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6"/>
</svg>
<?php _e('Dashboard', 'igny8-bridge'); ?>
</a>
</li>
<li>
<a href="<?php echo esc_url(admin_url('admin.php?page=igny8-connection')); ?>"
class="<?php echo ($current_page === 'igny8-connection') ? 'active' : ''; ?>">
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1"/>
</svg>
<?php _e('Connection', 'igny8-bridge'); ?>
</a>
</li>
<li>
<a href="<?php echo esc_url(admin_url('admin.php?page=igny8-controls')); ?>"
class="<?php echo ($current_page === 'igny8-controls') ? 'active' : ''; ?>">
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6V4m0 2a2 2 0 100 4m0-4a2 2 0 110 4m-6 8a2 2 0 100-4m0 4a2 2 0 110-4m0 4v2m0-6V4m6 6v10m6-2a2 2 0 100-4m0 4a2 2 0 110-4m0 4v2m0-6V4"/>
</svg>
<?php _e('Controls', 'igny8-bridge'); ?>
</a>
</li>
<li>
<a href="<?php echo esc_url(admin_url('admin.php?page=igny8-sync')); ?>"
class="<?php echo ($current_page === 'igny8-sync') ? 'active' : ''; ?>">
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"/>
</svg>
<?php _e('Sync', 'igny8-bridge'); ?>
</a>
</li>
<li>
<a href="<?php echo esc_url(admin_url('admin.php?page=igny8-data')); ?>"
class="<?php echo ($current_page === 'igny8-data') ? 'active' : ''; ?>">
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 7v10c0 2.21 3.582 4 8 4s8-1.79 8-4V7M4 7c0 2.21 3.582 4 8 4s8-1.79 8-4M4 7c0-2.21 3.582-4 8-4s8 1.79 8 4m0 5c0 2.21-3.582 4-8 4s-8-1.79-8-4"/>
</svg>
<?php _e('Data', 'igny8-bridge'); ?>
</a>
</li>
<li>
<a href="<?php echo esc_url(admin_url('admin.php?page=igny8-logs')); ?>"
class="<?php echo ($current_page === 'igny8-logs') ? 'active' : ''; ?>">
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 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>
<?php _e('Logs', 'igny8-bridge'); ?>
</a>
</li>
</ul>
</nav>
<!-- Connection Status in Sidebar -->
<div style="padding: 16px 24px; margin-top: auto; border-top: 1px solid var(--igny8-stroke);">
<?php if ($is_connected): ?>
<div class="igny8-status igny8-status-connected">
<span class="igny8-status-indicator"></span>
<?php _e('Connected', 'igny8-bridge'); ?>
</div>
<?php else: ?>
<div class="igny8-status igny8-status-disconnected">
<span class="igny8-status-indicator"></span>
<?php _e('Not Connected', 'igny8-bridge'); ?>
</div>
<?php endif; ?>
</div>
</aside>
<!-- Main Content Area -->
<main class="igny8-main-content">
<?php settings_errors('igny8_settings'); ?>

View File

@@ -0,0 +1,227 @@
<?php
/**
* Connection Page
*
* @package Igny8Bridge
*/
// Prevent direct access
if (!defined('ABSPATH')) {
exit;
}
// Include layout header
include IGNY8_BRIDGE_PLUGIN_DIR . 'admin/layout-header.php';
// Get connection settings
$api_key = function_exists('igny8_get_secure_option') ? igny8_get_secure_option('igny8_api_key') : get_option('igny8_api_key');
$site_id = get_option('igny8_site_id', '');
$integration_id = get_option('igny8_integration_id', '');
$access_token = function_exists('igny8_get_secure_option') ? igny8_get_secure_option('igny8_access_token') : get_option('igny8_access_token');
$last_structure_sync = get_option('igny8_last_structure_sync', 0);
$is_connected = !empty($access_token) && !empty($integration_id) && !empty($last_structure_sync);
$date_format = get_option('date_format');
$time_format = get_option('time_format');
$now = current_time('timestamp');
$token_issued = intval(get_option('igny8_access_token_issued', 0));
$token_age_text = $token_issued ? sprintf(__('%s ago', 'igny8-bridge'), human_time_diff($token_issued, $now)) : __('Not generated yet', 'igny8-bridge');
$token_issued_formatted = $token_issued ? date_i18n($date_format . ' ' . $time_format, $token_issued) : __('—', 'igny8-bridge');
$last_health_check = intval(get_option('igny8_last_api_health_check', 0));
$last_health_check_formatted = $last_health_check ? date_i18n($date_format . ' ' . $time_format, $last_health_check) : __('Never', 'igny8-bridge');
?>
<div class="igny8-page-header">
<h1><?php _e('Connection', 'igny8-bridge'); ?></h1>
<p><?php _e('Manage your IGNY8 API connection and authentication', 'igny8-bridge'); ?></p>
</div>
<?php if (!$is_connected): ?>
<!-- Not Connected - Show Connection Form -->
<div class="igny8-card">
<div class="igny8-card-header">
<h2>
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1"/>
</svg>
<?php _e('Connect to IGNY8', 'igny8-bridge'); ?>
</h2>
</div>
<div class="igny8-status igny8-status-disconnected" style="margin-bottom: 24px;">
<span class="igny8-status-indicator"></span>
<?php _e('Not Connected', 'igny8-bridge'); ?>
</div>
<form method="post" action="">
<?php wp_nonce_field('igny8_settings_nonce'); ?>
<div class="igny8-form-group">
<label for="igny8_api_key">
<?php _e('API Key', 'igny8-bridge'); ?>
<span style="color: var(--igny8-danger);">*</span>
</label>
<input
type="text"
id="igny8_api_key"
name="igny8_api_key"
value=""
placeholder="<?php _e('igny8_site_5_1764575388582_u671q2e2mv', 'igny8-bridge'); ?>"
required
/>
<p class="igny8-form-help">
<?php printf(
__('Get your API key from the <a href="%s" target="_blank">IGNY8 app integrations page</a>. The API key format includes your site ID.', 'igny8-bridge'),
'https://app.igny8.com'
); ?>
</p>
</div>
<button type="submit" name="igny8_connect" class="igny8-btn igny8-btn-primary">
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1"/>
</svg>
<?php _e('Connect to IGNY8', 'igny8-bridge'); ?>
</button>
</form>
</div>
<!-- Connection Instructions -->
<div class="igny8-card">
<div class="igny8-card-header">
<h2>
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/>
</svg>
<?php _e('How to Connect', 'igny8-bridge'); ?>
</h2>
</div>
<ol style="padding-left: 20px; line-height: 1.8;">
<li><?php _e('Log in to your IGNY8 account', 'igny8-bridge'); ?></li>
<li><?php _e('Navigate to Settings → Integrations', 'igny8-bridge'); ?></li>
<li><?php _e('Find WordPress in the integrations list', 'igny8-bridge'); ?></li>
<li><?php _e('Click "Add Site" to generate a new API key', 'igny8-bridge'); ?></li>
<li><?php _e('Copy the API key and paste it in the field above', 'igny8-bridge'); ?></li>
<li><?php _e('Click "Connect to IGNY8" to establish the connection', 'igny8-bridge'); ?></li>
</ol>
</div>
<?php else: ?>
<!-- Connected - Show Connection Details -->
<div class="igny8-alert igny8-alert-success">
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"/>
</svg>
<div>
<strong><?php _e('Connected Successfully', 'igny8-bridge'); ?></strong>
<p><?php _e('Your WordPress site is connected to IGNY8 and ready to sync content.', 'igny8-bridge'); ?></p>
</div>
</div>
<div class="igny8-grid igny8-grid-2">
<!-- Connection Status -->
<div class="igny8-card">
<div class="igny8-card-header">
<h2>
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"/>
</svg>
<?php _e('Connection Status', 'igny8-bridge'); ?>
</h2>
</div>
<div class="igny8-status igny8-status-connected" style="margin-bottom: 20px;">
<span class="igny8-status-indicator"></span>
<?php _e('Connected & Active', 'igny8-bridge'); ?>
</div>
<div class="igny8-form-group">
<label><?php _e('Site ID', 'igny8-bridge'); ?></label>
<code style="display: block; padding: 10px; background: var(--igny8-surface); border-radius: var(--igny8-radius-base);">
<?php echo esc_html($site_id ?: __('Not set', 'igny8-bridge')); ?>
</code>
</div>
<div class="igny8-form-group">
<label><?php _e('Integration ID', 'igny8-bridge'); ?></label>
<code style="display: block; padding: 10px; background: var(--igny8-surface); border-radius: var(--igny8-radius-base);">
<?php echo esc_html($integration_id ?: __('Not set', 'igny8-bridge')); ?>
</code>
</div>
</div>
<!-- API Key Details -->
<div class="igny8-card">
<div class="igny8-card-header">
<h2>
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 7a2 2 0 012 2m4 0a6 6 0 01-7.743 5.743L11 17H9v2H7v2H4a1 1 0 01-1-1v-2.586a1 1 0 01.293-.707l5.964-5.964A6 6 0 1121 9z"/>
</svg>
<?php _e('API Key', 'igny8-bridge'); ?>
</h2>
</div>
<div class="igny8-form-group">
<label><?php _e('Active API Key', 'igny8-bridge'); ?></label>
<div style="padding: 10px 12px; background: var(--igny8-surface); border: 1px solid var(--igny8-stroke); border-radius: var(--igny8-radius-base); font-family: monospace;">
<?php echo esc_html(substr($api_key, 0, 7) . '••••••••••••' . substr($api_key, -7)); ?>
<span style="color: var(--igny8-success); font-weight: 600; margin-left: 12px;">✓ Verified</span>
</div>
</div>
<?php if ($token_issued): ?>
<div class="igny8-form-group">
<label><?php _e('Token Issued', 'igny8-bridge'); ?></label>
<p style="margin: 0; font-size: 14px;">
<?php echo esc_html($token_age_text); ?>
<span style="color: var(--igny8-text-dim); display: block; font-size: 13px; margin-top: 4px;">
<?php echo esc_html($token_issued_formatted); ?>
</span>
</p>
</div>
<?php endif; ?>
<?php if ($last_health_check): ?>
<div class="igny8-form-group">
<label><?php _e('Last Health Check', 'igny8-bridge'); ?></label>
<p style="margin: 0; font-size: 14px;">
<?php echo esc_html($last_health_check_formatted); ?>
</p>
</div>
<?php endif; ?>
</div>
</div>
<!-- Disconnect Section -->
<div class="igny8-card">
<div class="igny8-card-header">
<h2>
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"/>
</svg>
<?php _e('Danger Zone', 'igny8-bridge'); ?>
</h2>
</div>
<p style="margin-bottom: 16px; color: var(--igny8-text-dim);">
<?php _e('Disconnecting will stop all syncing with IGNY8. Your content in WordPress will remain unchanged, but no new updates will be received from IGNY8.', 'igny8-bridge'); ?>
</p>
<form method="post" action="">
<?php wp_nonce_field('igny8_revoke_api_key'); ?>
<button type="submit" name="igny8_revoke_api_key" class="igny8-btn igny8-btn-danger"
onclick="return confirm('<?php _e('Are you sure you want to disconnect? This will stop all syncing with IGNY8.', 'igny8-bridge'); ?>');">
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M18.364 18.364A9 9 0 005.636 5.636m12.728 12.728A9 9 0 015.636 5.636m12.728 12.728L5.636 5.636"/>
</svg>
<?php _e('Disconnect from IGNY8', 'igny8-bridge'); ?>
</button>
</form>
</div>
<?php endif; ?>
<?php
// Include layout footer
include IGNY8_BRIDGE_PLUGIN_DIR . 'admin/layout-footer.php';
?>

View File

@@ -0,0 +1,276 @@
<?php
/**
* Controls Page
*
* @package Igny8Bridge
*/
// Prevent direct access
if (!defined('ABSPATH')) {
exit;
}
// Include layout header
include IGNY8_BRIDGE_PLUGIN_DIR . 'admin/layout-header.php';
// Get settings
$available_post_types = igny8_get_supported_post_types();
$enabled_post_types = igny8_get_enabled_post_types();
$available_taxonomies = igny8_get_supported_taxonomies();
$enabled_taxonomies = igny8_get_enabled_taxonomies();
$control_mode = igny8_get_control_mode();
$woocommerce_enabled = (int) get_option('igny8_enable_woocommerce', class_exists('WooCommerce') ? 1 : 0);
$woocommerce_detected = class_exists('WooCommerce');
$available_modules = igny8_get_available_modules();
$enabled_modules = igny8_get_enabled_modules();
$default_post_status = get_option('igny8_default_post_status', 'draft');
?>
<div class="igny8-page-header">
<h1><?php _e('Controls', 'igny8-bridge'); ?></h1>
<p><?php _e('Configure which content types to sync and how IGNY8 manages your content', 'igny8-bridge'); ?></p>
</div>
<form method="post" action="options.php">
<?php settings_fields('igny8_bridge_controls'); ?>
<div class="igny8-grid igny8-grid-2">
<!-- Post Types -->
<div class="igny8-card">
<div class="igny8-card-header">
<h2>
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 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>
<?php _e('Post Types to Sync', 'igny8-bridge'); ?>
</h2>
</div>
<?php foreach ($available_post_types as $slug => $label) : ?>
<div class="igny8-form-group" style="margin-bottom: 12px;">
<label style="display: flex; align-items: center; cursor: pointer;">
<input
type="checkbox"
name="igny8_enabled_post_types[]"
value="<?php echo esc_attr($slug); ?>"
<?php checked(in_array($slug, $enabled_post_types, true)); ?>
style="margin-right: 8px;"
/>
<?php echo esc_html($label); ?>
</label>
</div>
<?php endforeach; ?>
<p class="igny8-form-help">
<?php _e('Select the content types IGNY8 should manage automatically.', 'igny8-bridge'); ?>
</p>
</div>
<!-- Taxonomies -->
<div class="igny8-card">
<div class="igny8-card-header">
<h2>
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 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>
<?php _e('Taxonomies to Sync', 'igny8-bridge'); ?>
</h2>
</div>
<?php foreach ($available_taxonomies as $slug => $label) : ?>
<div class="igny8-form-group" style="margin-bottom: 12px;">
<label style="display: flex; align-items: center; cursor: pointer;">
<input
type="checkbox"
name="igny8_enabled_taxonomies[]"
value="<?php echo esc_attr($slug); ?>"
<?php checked(in_array($slug, $enabled_taxonomies, true)); ?>
style="margin-right: 8px;"
/>
<?php echo esc_html($label); ?>
</label>
</div>
<?php endforeach; ?>
<p class="igny8-form-help">
<?php _e('Select which taxonomies to sync with IGNY8.', 'igny8-bridge'); ?>
</p>
</div>
</div>
<!-- Control Mode -->
<div class="igny8-card">
<div class="igny8-card-header">
<h2>
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6V4m0 2a2 2 0 100 4m0-4a2 2 0 110 4m-6 8a2 2 0 100-4m0 4a2 2 0 110-4m0 4v2m0-6V4m6 6v10m6-2a2 2 0 100-4m0 4a2 2 0 110-4m0 4v2m0-6V4"/>
</svg>
<?php _e('Control Mode', 'igny8-bridge'); ?>
</h2>
</div>
<div style="display: grid; gap: 16px;">
<label style="display: flex; align-items: flex-start; cursor: pointer; padding: 16px; border: 2px solid var(--igny8-stroke); border-radius: var(--igny8-radius-base); transition: all 0.2s;"
class="<?php echo $control_mode === 'mirror' ? 'igny8-control-mode-selected' : ''; ?>">
<input
type="radio"
name="igny8_control_mode"
value="mirror"
<?php checked($control_mode, 'mirror'); ?>
style="margin-right: 12px; margin-top: 4px;"
/>
<div>
<strong style="font-size: 16px; display: block; margin-bottom: 4px;">
<?php _e('Mirror Mode', 'igny8-bridge'); ?>
</strong>
<span style="color: var(--igny8-text-dim); font-size: 14px;">
<?php _e('IGNY8 is the source of truth; WordPress reflects changes only. Content is read-only in WordPress.', 'igny8-bridge'); ?>
</span>
</div>
</label>
<label style="display: flex; align-items: flex-start; cursor: pointer; padding: 16px; border: 2px solid var(--igny8-stroke); border-radius: var(--igny8-radius-base); transition: all 0.2s;"
class="<?php echo $control_mode === 'hybrid' ? 'igny8-control-mode-selected' : ''; ?>">
<input
type="radio"
name="igny8_control_mode"
value="hybrid"
<?php checked($control_mode, 'hybrid'); ?>
style="margin-right: 12px; margin-top: 4px;"
/>
<div>
<strong style="font-size: 16px; display: block; margin-bottom: 4px;">
<?php _e('Hybrid Mode', 'igny8-bridge'); ?>
</strong>
<span style="color: var(--igny8-text-dim); font-size: 14px;">
<?php _e('Allow editors to update content in WordPress and sync changes back to IGNY8. Two-way synchronization.', 'igny8-bridge'); ?>
</span>
</div>
</label>
</div>
</div>
<div class="igny8-grid igny8-grid-2">
<!-- Modules -->
<div class="igny8-card">
<div class="igny8-card-header">
<h2>
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10"/>
</svg>
<?php _e('IGNY8 Modules', 'igny8-bridge'); ?>
</h2>
</div>
<?php foreach ($available_modules as $module_key => $module_label) : ?>
<div class="igny8-form-group" style="margin-bottom: 12px;">
<label style="display: flex; align-items: center; cursor: pointer;">
<input
type="checkbox"
name="igny8_enabled_modules[]"
value="<?php echo esc_attr($module_key); ?>"
<?php checked(in_array($module_key, $enabled_modules, true)); ?>
style="margin-right: 8px;"
/>
<?php echo esc_html($module_label); ?>
</label>
</div>
<?php endforeach; ?>
<p class="igny8-form-help">
<?php _e('Disable modules temporarily if a feature is not ready in the SaaS app.', 'igny8-bridge'); ?>
</p>
</div>
<!-- Default Post Status -->
<div class="igny8-card">
<div class="igny8-card-header">
<h2>
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"/>
</svg>
<?php _e('Default Post Status', 'igny8-bridge'); ?>
</h2>
</div>
<div style="display: grid; gap: 12px; margin-bottom: 16px;">
<label style="display: flex; align-items: flex-start; cursor: pointer;">
<input
type="radio"
name="igny8_default_post_status"
value="draft"
<?php checked($default_post_status, 'draft'); ?>
style="margin-right: 8px; margin-top: 4px;"
/>
<div>
<strong><?php _e('Draft', 'igny8-bridge'); ?></strong>
<span style="display: block; color: var(--igny8-text-dim); font-size: 13px;">
<?php _e('Save content as draft for review before publishing.', 'igny8-bridge'); ?>
</span>
</div>
</label>
<label style="display: flex; align-items: flex-start; cursor: pointer;">
<input
type="radio"
name="igny8_default_post_status"
value="publish"
<?php checked($default_post_status, 'publish'); ?>
style="margin-right: 8px; margin-top: 4px;"
/>
<div>
<strong><?php _e('Publish', 'igny8-bridge'); ?></strong>
<span style="display: block; color: var(--igny8-text-dim); font-size: 13px;">
<?php _e('Publish content immediately when received from IGNY8.', 'igny8-bridge'); ?>
</span>
</div>
</label>
</div>
<p class="igny8-form-help">
<?php _e('Choose whether content published from IGNY8 should be saved as draft or published immediately in WordPress.', 'igny8-bridge'); ?>
</p>
<?php if ($woocommerce_detected): ?>
<div style="margin-top: 20px; padding-top: 20px; border-top: 1px solid var(--igny8-stroke);">
<label style="display: flex; align-items: center; cursor: pointer;">
<input
type="checkbox"
name="igny8_enable_woocommerce"
value="1"
<?php checked($woocommerce_enabled, 1); ?>
style="margin-right: 8px;"
/>
<strong><?php _e('Sync WooCommerce products and categories', 'igny8-bridge'); ?></strong>
</label>
</div>
<?php else: ?>
<div class="igny8-alert igny8-alert-warning" style="margin-top: 20px;">
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/>
</svg>
<span><?php _e('WooCommerce is not installed. Install WooCommerce to sync products.', 'igny8-bridge'); ?></span>
</div>
<?php endif; ?>
</div>
</div>
<button type="submit" class="igny8-btn igny8-btn-primary">
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/>
</svg>
<?php _e('Save Controls', 'igny8-bridge'); ?>
</button>
</form>
<style>
.igny8-control-mode-selected {
border-color: var(--igny8-primary) !important;
background: var(--igny8-primary-subtle) !important;
}
</style>
<?php
// Include layout footer
include IGNY8_BRIDGE_PLUGIN_DIR . 'admin/layout-footer.php';
?>

View File

@@ -0,0 +1,182 @@
<?php
/**
* Dashboard Page
*
* @package Igny8Bridge
*/
// Prevent direct access
if (!defined('ABSPATH')) {
exit;
}
// Include layout header
include IGNY8_BRIDGE_PLUGIN_DIR . 'admin/layout-header.php';
// Get connection status
$api_key = get_option('igny8_api_key');
$is_connected = !empty($api_key);
$site_id = get_option('igny8_site_id');
$last_sync = get_option('igny8_last_sync_time');
?>
<div class="igny8-page-header">
<h1><?php _e('Dashboard', 'igny8-bridge'); ?></h1>
<p><?php _e('Overview of your IGNY8 integration', 'igny8-bridge'); ?></p>
</div>
<?php if (!$is_connected): ?>
<div class="igny8-alert igny8-alert-warning">
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"/>
</svg>
<div>
<strong><?php _e('Not Connected', 'igny8-bridge'); ?></strong>
<p><?php _e('You need to connect to IGNY8 to start syncing content.', 'igny8-bridge'); ?>
<a href="<?php echo esc_url(admin_url('admin.php?page=igny8-connection')); ?>"><?php _e('Connect now', 'igny8-bridge'); ?></a>
</p>
</div>
</div>
<?php endif; ?>
<div class="igny8-grid igny8-grid-3">
<!-- Connection Status Card -->
<div class="igny8-card">
<div class="igny8-card-header">
<h2>
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1"/>
</svg>
<?php _e('Connection', 'igny8-bridge'); ?>
</h2>
</div>
<div style="padding: 16px 0;">
<?php if ($is_connected): ?>
<div class="igny8-status igny8-status-connected" style="font-size: 16px; padding: 8px 16px;">
<span class="igny8-status-indicator"></span>
<?php _e('Connected', 'igny8-bridge'); ?>
</div>
<?php if ($site_id): ?>
<p style="margin-top: 12px; font-size: 13px; color: var(--igny8-text-dim);">
<?php _e('Site ID:', 'igny8-bridge'); ?> <code><?php echo esc_html($site_id); ?></code>
</p>
<?php endif; ?>
<?php else: ?>
<div class="igny8-status igny8-status-disconnected" style="font-size: 16px; padding: 8px 16px;">
<span class="igny8-status-indicator"></span>
<?php _e('Not Connected', 'igny8-bridge'); ?>
</div>
<p style="margin-top: 12px;">
<a href="<?php echo esc_url(admin_url('admin.php?page=igny8-connection')); ?>" class="igny8-btn igny8-btn-primary">
<?php _e('Connect Now', 'igny8-bridge'); ?>
</a>
</p>
<?php endif; ?>
</div>
</div>
<!-- Sync Status Card -->
<div class="igny8-card">
<div class="igny8-card-header">
<h2>
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"/>
</svg>
<?php _e('Last Sync', 'igny8-bridge'); ?>
</h2>
</div>
<div style="padding: 16px 0;">
<?php if ($last_sync): ?>
<p style="font-size: 14px; margin: 0;">
<?php echo esc_html(human_time_diff($last_sync, current_time('timestamp'))) . ' ' . __('ago', 'igny8-bridge'); ?>
</p>
<p style="font-size: 13px; color: var(--igny8-text-dim); margin: 8px 0 0 0;">
<?php echo esc_html(date_i18n(get_option('date_format') . ' ' . get_option('time_format'), $last_sync)); ?>
</p>
<?php else: ?>
<p style="font-size: 14px; color: var(--igny8-text-dim); margin: 0;">
<?php _e('No sync performed yet', 'igny8-bridge'); ?>
</p>
<?php endif; ?>
</div>
</div>
<!-- Plugin Info Card -->
<div class="igny8-card">
<div class="igny8-card-header">
<h2>
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/>
</svg>
<?php _e('Plugin Info', 'igny8-bridge'); ?>
</h2>
</div>
<div style="padding: 16px 0;">
<p style="font-size: 14px; margin: 0 0 8px 0;">
<strong><?php _e('Version:', 'igny8-bridge'); ?></strong> <?php echo esc_html(IGNY8_BRIDGE_VERSION); ?>
</p>
<p style="font-size: 14px; margin: 0;">
<strong><?php _e('PHP:', 'igny8-bridge'); ?></strong> <?php echo esc_html(PHP_VERSION); ?>
</p>
</div>
</div>
</div>
<!-- Quick Actions -->
<div class="igny8-card">
<div class="igny8-card-header">
<h2>
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z"/>
</svg>
<?php _e('Quick Actions', 'igny8-bridge'); ?>
</h2>
</div>
<div class="igny8-grid igny8-grid-2" style="padding: 16px 0;">
<div>
<h3 style="font-size: 16px; margin: 0 0 12px 0;"><?php _e('Connection', 'igny8-bridge'); ?></h3>
<p style="font-size: 14px; color: var(--igny8-text-dim); margin-bottom: 16px;">
<?php _e('Manage your API connection and authentication', 'igny8-bridge'); ?>
</p>
<a href="<?php echo esc_url(admin_url('admin.php?page=igny8-connection')); ?>" class="igny8-btn igny8-btn-secondary">
<?php _e('Manage Connection', 'igny8-bridge'); ?>
</a>
</div>
<div>
<h3 style="font-size: 16px; margin: 0 0 12px 0;"><?php _e('Controls', 'igny8-bridge'); ?></h3>
<p style="font-size: 14px; color: var(--igny8-text-dim); margin-bottom: 16px;">
<?php _e('Configure which content types to sync', 'igny8-bridge'); ?>
</p>
<a href="<?php echo esc_url(admin_url('admin.php?page=igny8-controls')); ?>" class="igny8-btn igny8-btn-secondary">
<?php _e('Configure Controls', 'igny8-bridge'); ?>
</a>
</div>
<div>
<h3 style="font-size: 16px; margin: 0 0 12px 0;"><?php _e('Sync Settings', 'igny8-bridge'); ?></h3>
<p style="font-size: 14px; color: var(--igny8-text-dim); margin-bottom: 16px;">
<?php _e('Configure automatic sync and content updates', 'igny8-bridge'); ?>
</p>
<a href="<?php echo esc_url(admin_url('admin.php?page=igny8-sync')); ?>" class="igny8-btn igny8-btn-secondary">
<?php _e('Sync Settings', 'igny8-bridge'); ?>
</a>
</div>
<div>
<h3 style="font-size: 16px; margin: 0 0 12px 0;"><?php _e('View Logs', 'igny8-bridge'); ?></h3>
<p style="font-size: 14px; color: var(--igny8-text-dim); margin-bottom: 16px;">
<?php _e('Review sync history and troubleshoot issues', 'igny8-bridge'); ?>
</p>
<a href="<?php echo esc_url(admin_url('admin.php?page=igny8-logs')); ?>" class="igny8-btn igny8-btn-secondary">
<?php _e('View Logs', 'igny8-bridge'); ?>
</a>
</div>
</div>
</div>
<?php
// Include layout footer
include IGNY8_BRIDGE_PLUGIN_DIR . 'admin/layout-footer.php';
?>

View File

@@ -0,0 +1,148 @@
<?php
/**
* Data Page
*
* @package Igny8Bridge
*/
// Prevent direct access
if (!defined('ABSPATH')) {
exit;
}
// Include layout header
include IGNY8_BRIDGE_PLUGIN_DIR . 'admin/layout-header.php';
// Get data statistics
$link_queue = get_option('igny8_link_queue', array());
$pending_links = array_filter($link_queue, function($item) {
return isset($item['status']) && $item['status'] === 'pending';
});
$total_links = count($link_queue);
$pending_count = count($pending_links);
$processed_count = $total_links - $pending_count;
?>
<div class="igny8-page-header">
<h1><?php _e('Data', 'igny8-bridge'); ?></h1>
<p><?php _e('View synced data, queues, and content status', 'igny8-bridge'); ?></p>
</div>
<!-- Statistics -->
<div class="igny8-grid igny8-grid-3">
<div class="igny8-card">
<div class="igny8-card-header">
<h2>
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1"/>
</svg>
<?php _e('Total Links', 'igny8-bridge'); ?>
</h2>
</div>
<div style="padding: 16px 0;">
<p style="font-size: 32px; font-weight: 700; margin: 0; color: var(--igny8-primary);">
<?php echo esc_html($total_links); ?>
</p>
</div>
</div>
<div class="igny8-card">
<div class="igny8-card-header">
<h2>
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"/>
</svg>
<?php _e('Pending', 'igny8-bridge'); ?>
</h2>
</div>
<div style="padding: 16px 0;">
<p style="font-size: 32px; font-weight: 700; margin: 0; color: var(--igny8-warning);">
<?php echo esc_html($pending_count); ?>
</p>
</div>
</div>
<div class="igny8-card">
<div class="igny8-card-header">
<h2>
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"/>
</svg>
<?php _e('Processed', 'igny8-bridge'); ?>
</h2>
</div>
<div style="padding: 16px 0;">
<p style="font-size: 32px; font-weight: 700; margin: 0; color: var(--igny8-success);">
<?php echo esc_html($processed_count); ?>
</p>
</div>
</div>
</div>
<!-- Link Queue -->
<?php if (!empty($link_queue)): ?>
<div class="igny8-card">
<div class="igny8-card-header">
<h2>
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 10h16M4 14h16M4 18h16"/>
</svg>
<?php _e('Link Queue', 'igny8-bridge'); ?>
</h2>
</div>
<table class="igny8-table">
<thead>
<tr>
<th><?php _e('Post Title', 'igny8-bridge'); ?></th>
<th><?php _e('Target URL', 'igny8-bridge'); ?></th>
<th><?php _e('Anchor', 'igny8-bridge'); ?></th>
<th><?php _e('Status', 'igny8-bridge'); ?></th>
</tr>
</thead>
<tbody>
<?php foreach (array_slice($link_queue, 0, 10) as $item): ?>
<tr>
<td>
<?php
$post = get_post($item['post_id'] ?? 0);
echo $post ? esc_html($post->post_title) : __('Unknown Post', 'igny8-bridge');
?>
</td>
<td>
<a href="<?php echo esc_url($item['target_url'] ?? '#'); ?>" target="_blank" style="color: var(--igny8-primary);">
<?php echo esc_html(isset($item['target_url']) ? parse_url($item['target_url'], PHP_URL_HOST) : '—'); ?>
</a>
</td>
<td><?php echo esc_html($item['anchor'] ?? '—'); ?></td>
<td>
<?php if (($item['status'] ?? '') === 'pending'): ?>
<span class="igny8-status igny8-status-disconnected"><?php _e('Pending', 'igny8-bridge'); ?></span>
<?php else: ?>
<span class="igny8-status igny8-status-connected"><?php _e('Processed', 'igny8-bridge'); ?></span>
<?php endif; ?>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php if (count($link_queue) > 10): ?>
<p style="margin-top: 16px; color: var(--igny8-text-dim); font-size: 14px;">
<?php printf(__('Showing 10 of %d total items', 'igny8-bridge'), count($link_queue)); ?>
</p>
<?php endif; ?>
</div>
<?php else: ?>
<div class="igny8-alert igny8-alert-success">
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"/>
</svg>
<span><?php _e('No items in link queue. All links have been processed.', 'igny8-bridge'); ?></span>
</div>
<?php endif; ?>
<?php
// Include layout footer
include IGNY8_BRIDGE_PLUGIN_DIR . 'admin/layout-footer.php';
?>

View File

@@ -0,0 +1,100 @@
<?php
/**
* Logs Page
*
* @package Igny8Bridge
*/
// Prevent direct access
if (!defined('ABSPATH')) {
exit;
}
// Include layout header
include IGNY8_BRIDGE_PLUGIN_DIR . 'admin/layout-header.php';
// Get logs
$webhook_logs = igny8_get_webhook_logs(array('limit' => 20));
?>
<div class="igny8-page-header">
<h1><?php _e('Logs', 'igny8-bridge'); ?></h1>
<p><?php _e('Review webhook activity and troubleshoot sync issues', 'igny8-bridge'); ?></p>
</div>
<?php if (!empty($webhook_logs)): ?>
<div class="igny8-card">
<div class="igny8-card-header">
<h2>
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 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>
<?php _e('Webhook Logs', 'igny8-bridge'); ?>
</h2>
</div>
<table class="igny8-table">
<thead>
<tr>
<th><?php _e('Timestamp', 'igny8-bridge'); ?></th>
<th><?php _e('Event', 'igny8-bridge'); ?></th>
<th><?php _e('Status', 'igny8-bridge'); ?></th>
<th><?php _e('Response Time', 'igny8-bridge'); ?></th>
</tr>
</thead>
<tbody>
<?php foreach ($webhook_logs as $log): ?>
<tr>
<td>
<?php
$timestamp = isset($log['timestamp']) ? $log['timestamp'] : 0;
echo esc_html(date_i18n(get_option('date_format') . ' ' . get_option('time_format'), $timestamp));
?>
</td>
<td>
<strong><?php echo esc_html($log['event'] ?? __('Unknown', 'igny8-bridge')); ?></strong>
</td>
<td>
<?php if (($log['status'] ?? '') === 'success'): ?>
<span class="igny8-status igny8-status-connected">✓ <?php _e('Success', 'igny8-bridge'); ?></span>
<?php else: ?>
<span class="igny8-status igny8-status-disconnected">✗ <?php _e('Failed', 'igny8-bridge'); ?></span>
<?php endif; ?>
</td>
<td>
<?php
$response_time = isset($log['response_time']) ? $log['response_time'] : 0;
echo esc_html(number_format($response_time, 2)) . 'ms';
?>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<div class="igny8-alert igny8-alert-success" style="margin-top: 24px;">
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/>
</svg>
<span>
<?php _e('For detailed API request/response logs, check', 'igny8-bridge'); ?>
<code>wp-content/debug.log</code>
</span>
</div>
<?php else: ?>
<div class="igny8-alert igny8-alert-warning">
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/>
</svg>
<div>
<strong><?php _e('No Logs Available', 'igny8-bridge'); ?></strong>
<p><?php _e('No webhook activity has been recorded yet. Logs will appear here once IGNY8 starts sending content to your site.', 'igny8-bridge'); ?></p>
</div>
</div>
<?php endif; ?>
<?php
// Include layout footer
include IGNY8_BRIDGE_PLUGIN_DIR . 'admin/layout-footer.php';
?>

View File

@@ -0,0 +1,169 @@
<?php
/**
* Sync Page
*
* @package Igny8Bridge
*/
// Prevent direct access
if (!defined('ABSPATH')) {
exit;
}
// Include layout header
include IGNY8_BRIDGE_PLUGIN_DIR . 'admin/layout-header.php';
// Get sync settings
$connection_enabled = igny8_is_connection_enabled();
$last_site_sync = intval(get_option('igny8_last_site_sync', 0));
$last_taxonomy_sync = intval(get_option('igny8_last_taxonomy_sync', 0));
$last_keyword_sync = intval(get_option('igny8_last_keyword_sync', 0));
$last_writer_sync = intval(get_option('igny8_last_writer_sync', 0));
$next_site_sync = wp_next_scheduled('igny8_sync_site_data');
$date_format = get_option('date_format');
$time_format = get_option('time_format');
$last_site_sync_formatted = $last_site_sync ? date_i18n($date_format . ' ' . $time_format, $last_site_sync) : __('Never', 'igny8-bridge');
$last_taxonomy_sync_formatted = $last_taxonomy_sync ? date_i18n($date_format . ' ' . $time_format, $last_taxonomy_sync) : __('Never', 'igny8-bridge');
$last_keyword_sync_formatted = $last_keyword_sync ? date_i18n($date_format . ' ' . $time_format, $last_keyword_sync) : __('Never', 'igny8-bridge');
$last_writer_sync_formatted = $last_writer_sync ? date_i18n($date_format . ' ' . $time_format, $last_writer_sync) : __('Never', 'igny8-bridge');
$next_site_sync_formatted = $next_site_sync ? date_i18n($date_format . ' ' . $time_format, $next_site_sync) : __('Not scheduled', 'igny8-bridge');
?>
<div class="igny8-page-header">
<h1><?php _e('Sync', 'igny8-bridge'); ?></h1>
<p><?php _e('Configure automatic sync and monitor synchronization status', 'igny8-bridge'); ?></p>
</div>
<form method="post" action="options.php">
<?php settings_fields('igny8_bridge_connection'); ?>
<!-- Connection Enable/Disable -->
<div class="igny8-card">
<div class="igny8-card-header">
<h2>
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7h12m0 0l-4-4m4 4l-4 4m0 6H4m0 0l4 4m-4-4l4-4"/>
</svg>
<?php _e('Sync Status', 'igny8-bridge'); ?>
</h2>
</div>
<label style="display: flex; align-items: center; cursor: pointer; padding: 16px; background: var(--igny8-surface); border-radius: var(--igny8-radius-base);">
<input
type="checkbox"
name="igny8_connection_enabled"
value="1"
<?php checked($connection_enabled, 1); ?>
style="margin-right: 12px;"
/>
<div>
<strong style="font-size: 16px; display: block; margin-bottom: 4px;">
<?php _e('Enable IGNY8 Sync', 'igny8-bridge'); ?>
</strong>
<span style="color: var(--igny8-text-dim); font-size: 14px;">
<?php _e('Allow IGNY8 to sync content to this WordPress site. Disable this to pause syncing temporarily.', 'igny8-bridge'); ?>
</span>
</div>
</label>
</div>
<button type="submit" class="igny8-btn igny8-btn-primary">
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/>
</svg>
<?php _e('Save Sync Settings', 'igny8-bridge'); ?>
</button>
</form>
<!-- Sync History -->
<div class="igny8-card">
<div class="igny8-card-header">
<h2>
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"/>
</svg>
<?php _e('Sync History', 'igny8-bridge'); ?>
</h2>
</div>
<table class="igny8-table">
<thead>
<tr>
<th><?php _e('Sync Type', 'igny8-bridge'); ?></th>
<th><?php _e('Last Sync', 'igny8-bridge'); ?></th>
<th><?php _e('Status', 'igny8-bridge'); ?></th>
</tr>
</thead>
<tbody>
<tr>
<td><strong><?php _e('Site Data', 'igny8-bridge'); ?></strong></td>
<td><?php echo esc_html($last_site_sync_formatted); ?></td>
<td>
<?php if ($last_site_sync): ?>
<span class="igny8-status igny8-status-connected">✓ <?php _e('Synced', 'igny8-bridge'); ?></span>
<?php else: ?>
<span class="igny8-status igny8-status-disconnected">— <?php _e('Never', 'igny8-bridge'); ?></span>
<?php endif; ?>
</td>
</tr>
<tr>
<td><strong><?php _e('Taxonomies', 'igny8-bridge'); ?></strong></td>
<td><?php echo esc_html($last_taxonomy_sync_formatted); ?></td>
<td>
<?php if ($last_taxonomy_sync): ?>
<span class="igny8-status igny8-status-connected">✓ <?php _e('Synced', 'igny8-bridge'); ?></span>
<?php else: ?>
<span class="igny8-status igny8-status-disconnected">— <?php _e('Never', 'igny8-bridge'); ?></span>
<?php endif; ?>
</td>
</tr>
<tr>
<td><strong><?php _e('Keywords', 'igny8-bridge'); ?></strong></td>
<td><?php echo esc_html($last_keyword_sync_formatted); ?></td>
<td>
<?php if ($last_keyword_sync): ?>
<span class="igny8-status igny8-status-connected">✓ <?php _e('Synced', 'igny8-bridge'); ?></span>
<?php else: ?>
<span class="igny8-status igny8-status-disconnected">— <?php _e('Never', 'igny8-bridge'); ?></span>
<?php endif; ?>
</td>
</tr>
<tr>
<td><strong><?php _e('Writers', 'igny8-bridge'); ?></strong></td>
<td><?php echo esc_html($last_writer_sync_formatted); ?></td>
<td>
<?php if ($last_writer_sync): ?>
<span class="igny8-status igny8-status-connected">✓ <?php _e('Synced', 'igny8-bridge'); ?></span>
<?php else: ?>
<span class="igny8-status igny8-status-disconnected">— <?php _e('Never', 'igny8-bridge'); ?></span>
<?php endif; ?>
</td>
</tr>
</tbody>
</table>
</div>
<!-- Next Scheduled Sync -->
<div class="igny8-card">
<div class="igny8-card-header">
<h2>
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"/>
</svg>
<?php _e('Scheduled Syncs', 'igny8-bridge'); ?>
</h2>
</div>
<div class="igny8-form-group">
<label><?php _e('Next Site Data Sync', 'igny8-bridge'); ?></label>
<p style="margin: 0; font-size: 15px; font-weight: 600;">
<?php echo esc_html($next_site_sync_formatted); ?>
</p>
</div>
</div>
<?php
// Include layout footer
include IGNY8_BRIDGE_PLUGIN_DIR . 'admin/layout-footer.php';
?>