This commit is contained in:
alorig
2025-12-01 04:55:27 +05:00
parent 34d2b3abf9
commit 90b532d13b
8 changed files with 1637 additions and 226 deletions

View File

@@ -24,7 +24,227 @@
============================================ */
.igny8-settings-container {
max-width: 1400px;
width: 95%;
margin: 0 auto;
max-width: none;
box-sizing: border-box;
}
/* On somewhat smaller screens cap at 1200px */
@media (max-width: 1440px) {
.igny8-settings-container {
width: 1200px;
max-width: 100%;
}
}
/* Very small screens: use full width with side padding */
@media (max-width: 1200px) {
.igny8-settings-container {
width: 100%;
padding: 0 16px;
}
}
/* Page header */
.igny8-page-header {
height: 100px;
display: flex;
align-items: center;
border-radius: 8px;
margin: 12px 0 24px 0;
}
.igny8-page-header h1 {
margin: 0;
font-size: 20px;
font-weight: 700;
color: #111827;
}
.igny8-module-title h2 {
margin: 0;
font-size: 18px;
font-weight: 700;
color: #0f172a;
}
/* Ensure top cards equal height */
.igny8-top-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 20px;
align-items: stretch;
margin-bottom: 32px;
}
.igny8-top-grid > .igny8-settings-card {
display: flex;
flex-direction: column;
justify-content: flex-start;
height: 100%;
}
/* Make communication primary buttons match API connection buttons */
.igny8-settings-card .button-primary,
.igny8-connection-actions .button-primary {
background: var(--igny8-primary) !important;
border-color: var(--igny8-primary) !important;
color: #fff !important;
border-radius: 8px !important;
padding: 10px 18px !important;
box-shadow: 0 6px 12px rgba(59,130,246,0.08);
}
/* Automation settings UI improvements */
.automation-block label,
.automation-block .description,
.automation-block h3 {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial;
}
.automation-block label {
display: flex;
align-items: center;
gap: 10px;
color: #111827;
font-size: 14px;
line-height: 1.7;
margin-bottom: 6px;
}
.automation-block input[type="checkbox"] {
width: 18px;
height: 18px;
accent-color: var(--igny8-primary);
}
/* Taxonomies list split into two columns inside right automation column */
.taxonomy-list {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 6px 18px;
align-items: start;
}
.taxonomy-item {
display: flex;
align-items: center;
gap: 8px;
font-size: 14px;
color: #111827;
}
.taxonomy-slug {
color: #6B7280;
font-size: 12px;
margin-left: 6px;
}
/* Module header gradient (left-to-right) */
.igny8-module-title {
background: linear-gradient(90deg, #9810fa 0%, #0693e3 100%);
border-radius: 10px;
padding: 22px 26px;
color: #fff;
margin-bottom: 18px;
box-shadow: 0 6px 18px rgba(9,10,33,0.06);
}
.igny8-module-title h2 {
color: #fff;
font-size: 20px;
margin: 0;
font-weight: 700;
}
.igny8-module-title p {
margin: 6px 0 0 0;
color: rgba(255,255,255,0.9);
font-size: 14px;
}
/* Prevent top-grid cards from visually bleeding into the next panels */
.igny8-top-grid + .igny8-settings-card,
.igny8-top-grid + .automation-block {
margin-top: 32px;
}
/* Connection status single-row layout */
.igny8-connection-status-display {
display: flex;
justify-content: space-between;
align-items: center;
padding: 20px;
background: linear-gradient(135deg, #F9FAFB 0%, #F3F4F6 100%);
border: 1px solid #E5E7EB;
border-radius: 12px;
margin-bottom: 20px;
}
.igny8-connection-status-display .igny8-status-label {
font-size: 12px;
text-transform: uppercase;
letter-spacing: 0.05em;
color: #6B7280;
margin: 0;
font-weight: 600;
}
.igny8-connection-status-display .igny8-status-value {
font-size: 18px;
font-weight: 700;
color: #111827;
display: flex;
align-items: center;
gap: 10px;
}
.igny8-connection-status-display .igny8-status-value span {
margin: 0;
}
@media (max-width: 900px) {
.igny8-connection-status-display {
flex-direction: column;
align-items: flex-start;
gap: 8px;
}
.igny8-module-title {
padding: 16px;
}
}
/* Top two-column layout for API Connection / Communication */
.igny8-top-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 24px;
align-items: start;
margin-bottom: 32px; /* ensure separation from subsequent sections */
}
@media (max-width: 900px) {
.igny8-top-grid {
grid-template-columns: 1fr;
}
}
/* Automation settings split into two columns */
.igny8-automation-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 20px;
align-items: start;
}
.igny8-top-grid > .igny8-settings-card {
margin: 0; /* grid handles spacing */
position: relative;
z-index: 1; /* prevent visual stacking/bleeding */
min-height: 160px; /* ensure cards don't collapse and overlap following content */
box-sizing: border-box;
}
.igny8-settings-card {
position: relative; /* ensure proper stacking context */
z-index: 0;
}
.automation-column-left,
.automation-column-right {
background: transparent;
}
@media (max-width: 900px) {
.igny8-automation-grid {
grid-template-columns: 1fr;
}
}
.igny8-settings-card {

View File

@@ -49,40 +49,6 @@ class Igny8AdminColumns {
add_action('wp_ajax_igny8_send_to_igny8', array($this, 'send_to_igny8'));
}
/**
* Render taxonomy column
*
* @param int $post_id Post ID
*/
private function render_taxonomy_column($post_id) {
$taxonomy = get_post_meta($post_id, '_igny8_taxonomy_id', true);
if ($taxonomy) {
echo '<span class="igny8-badge igny8-badge-igny8" title="' . esc_attr__('Synced Taxonomy', 'igny8-bridge') . '">';
echo esc_html($taxonomy);
echo '</span>';
} else {
echo '<span class="igny8-empty">—</span>';
}
}
/**
* Render attribute column
*
* @param int $post_id Post ID
*/
private function render_attribute_column($post_id) {
$attribute = get_post_meta($post_id, '_igny8_attribute_id', true);
if ($attribute) {
echo '<span class="igny8-badge igny8-badge-igny8" title="' . esc_attr__('Synced Attribute', 'igny8-bridge') . '">';
echo esc_html($attribute);
echo '</span>';
} else {
echo '<span class="igny8-empty">—</span>';
}
}
/**
* Add custom columns
*
@@ -90,18 +56,8 @@ class Igny8AdminColumns {
* @return array Modified columns
*/
public function add_columns($columns) {
$new_columns = array();
foreach ($columns as $key => $value) {
$new_columns[$key] = $value;
if ($key === 'title') {
$new_columns['igny8_taxonomy'] = __('Taxonomy', 'igny8-bridge');
$new_columns['igny8_attribute'] = __('Attribute', 'igny8-bridge');
}
}
return $new_columns;
// Removed custom taxonomy and attribute columns - posts now use native WordPress taxonomies (categories, tags, etc.)
return $columns;
}
/**
@@ -111,15 +67,8 @@ class Igny8AdminColumns {
* @param int $post_id Post ID
*/
public function render_column_content($column_name, $post_id) {
switch ($column_name) {
case 'igny8_taxonomy':
$this->render_taxonomy_column($post_id);
break;
case 'igny8_attribute':
$this->render_attribute_column($post_id);
break;
}
// Removed custom column rendering - posts now use native WP taxonomies
return;
}
/**

View File

@@ -63,10 +63,14 @@ $webhook_logs = igny8_get_webhook_logs(array('limit' => 10));
<div class="wrap">
<h1><?php echo esc_html(get_admin_page_title()); ?></h1>
<?php settings_errors('igny8_settings'); ?>
<div class="igny8-settings-container">
<div class="igny8-module-title igny8-page-header">
<h2>Igny8 Wordpress Bridge</h2>
</div>
<div class="igny8-top-grid">
<div class="igny8-settings-card">
<h2>
<svg width="20" height="20" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24" style="vertical-align: middle; margin-right: 8px; display: inline;">
@@ -230,87 +234,8 @@ $webhook_logs = igny8_get_webhook_logs(array('limit' => 10));
</p>
<?php endif; ?>
</div>
<div class="igny8-settings-card">
<h2>
<svg width="20" height="20" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24" style="vertical-align: middle; margin-right: 8px; display: inline;">
<path stroke-linecap="round" stroke-linejoin="round" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/>
</svg>
<?php _e('Diagnostics', 'igny8-bridge'); ?>
</h2>
<div class="igny8-diagnostics-grid">
<div class="igny8-diagnostic-item">
<div class="igny8-diagnostic-label"><?php _e('Access Token Age', 'igny8-bridge'); ?></div>
<div class="igny8-diagnostic-value"><?php echo esc_html($token_age_text); ?></div>
<p class="description">
<?php echo esc_html($token_issued_formatted); ?>
</p>
</div>
<div class="igny8-diagnostic-item">
<div class="igny8-diagnostic-label"><?php _e('Last API Health Check', 'igny8-bridge'); ?></div>
<div class="igny8-diagnostic-value"><?php echo esc_html($last_health_check_formatted); ?></div>
<p class="description">
<?php _e('Updated when tests succeed', 'igny8-bridge'); ?>
</p>
</div>
<div class="igny8-diagnostic-item">
<div class="igny8-diagnostic-label"><?php _e('Last Site Data Sync', 'igny8-bridge'); ?></div>
<div class="igny8-diagnostic-value"><?php echo esc_html($last_site_sync_formatted); ?></div>
<p class="description">
<?php _e('Triggered automatically after setup', 'igny8-bridge'); ?>
</p>
</div>
<div class="igny8-diagnostic-item">
<div class="igny8-diagnostic-label"><?php _e('Last Full Site Scan', 'igny8-bridge'); ?></div>
<div class="igny8-diagnostic-value"><?php echo esc_html($last_full_site_scan_formatted); ?></div>
<p class="description">
<?php _e('Runs weekly or when requested manually', 'igny8-bridge'); ?>
</p>
</div>
<div class="igny8-diagnostic-item">
<div class="igny8-diagnostic-label"><?php _e('Last Semantic Map', 'igny8-bridge'); ?></div>
<div class="igny8-diagnostic-value"><?php echo esc_html($last_semantic_map_formatted); ?></div>
<p class="description">
<?php
if (!empty($semantic_summary)) {
printf(
/* translators: %1$d: sectors count, %2$d: keywords count */
esc_html__('Sectors: %1$d · Keywords: %2$d', 'igny8-bridge'),
intval($semantic_summary['sectors'] ?? 0),
intval($semantic_summary['keywords'] ?? 0)
);
} else {
_e('Planner semantic map generated after full scan', 'igny8-bridge');
}
?>
</p>
</div>
<div class="igny8-diagnostic-item">
<div class="igny8-diagnostic-label"><?php _e('Last Taxonomy Sync', 'igny8-bridge'); ?></div>
<div class="igny8-diagnostic-value"><?php echo esc_html($last_taxonomy_sync_formatted); ?></div>
<p class="description">
<?php _e('Sectors & clusters imported from Planner', 'igny8-bridge'); ?>
</p>
</div>
<div class="igny8-diagnostic-item">
<div class="igny8-diagnostic-label"><?php _e('Last Keyword Sync', 'igny8-bridge'); ?></div>
<div class="igny8-diagnostic-value"><?php echo esc_html($last_keyword_sync_formatted); ?></div>
<p class="description">
<?php _e('Planner keywords cached to WordPress posts', 'igny8-bridge'); ?>
</p>
</div>
<div class="igny8-diagnostic-item">
<div class="igny8-diagnostic-label"><?php _e('Last Writer Sync', 'igny8-bridge'); ?></div>
<div class="igny8-diagnostic-value"><?php echo esc_html($last_writer_sync_formatted); ?></div>
<p class="description">
<?php _e('New IGNY8 tasks imported automatically', 'igny8-bridge'); ?>
</p>
</div>
<div class="igny8-diagnostic-item">
<div class="igny8-diagnostic-label"><?php _e('Next Scheduled Site Scan', 'igny8-bridge'); ?></div>
<div class="igny8-diagnostic-value"><?php echo esc_html($next_site_sync_formatted); ?></div>
</div>
</div>
</div>
<?php else : ?>
<div class="igny8-settings-card">
<h2><?php _e('Connection Status', 'igny8-bridge'); ?></h2>
@@ -336,10 +261,10 @@ $webhook_logs = igny8_get_webhook_logs(array('limit' => 10));
<form method="post" action="options.php">
<?php settings_fields('igny8_bridge_controls'); ?>
<table class="form-table">
<tr>
<th scope="row"><?php _e('Post Types to Sync', 'igny8-bridge'); ?></th>
<td>
<div class="igny8-automation-grid">
<div class="automation-column-left">
<div class="automation-block">
<h3><?php _e('Post Types to Sync', 'igny8-bridge'); ?></h3>
<?php foreach ($available_post_types as $slug => $label) : ?>
<label>
<input
@@ -355,11 +280,10 @@ $webhook_logs = igny8_get_webhook_logs(array('limit' => 10));
<p class="description">
<?php _e('Select the content types IGNY8 should manage automatically.', 'igny8-bridge'); ?>
</p>
</td>
</tr>
<tr>
<th scope="row"><?php _e('IGNY8 Modules', 'igny8-bridge'); ?></th>
<td>
</div>
<div class="automation-block">
<h3><?php _e('IGNY8 Modules', 'igny8-bridge'); ?></h3>
<?php foreach ($available_modules as $module_key => $module_label) : ?>
<label>
<input
@@ -375,11 +299,10 @@ $webhook_logs = igny8_get_webhook_logs(array('limit' => 10));
<p class="description">
<?php _e('Disable modules temporarily if a feature is not ready in the SaaS app.', 'igny8-bridge'); ?>
</p>
</td>
</tr>
<tr>
<th scope="row"><?php _e('Control Mode', 'igny8-bridge'); ?></th>
<td>
</div>
<div class="automation-block">
<h3><?php _e('Control Mode', 'igny8-bridge'); ?></h3>
<label>
<input
type="radio"
@@ -401,11 +324,12 @@ $webhook_logs = igny8_get_webhook_logs(array('limit' => 10));
<strong><?php _e('Hybrid', 'igny8-bridge'); ?></strong>
<span class="description"><?php _e('Allow editors to update content in WordPress and sync back to IGNY8.', 'igny8-bridge'); ?></span>
</label>
</td>
</tr>
<tr>
<th scope="row"><?php _e('WooCommerce Products', 'igny8-bridge'); ?></th>
<td>
</div>
</div>
<div class="automation-column-right">
<div class="automation-block">
<h3><?php _e('WooCommerce Products', 'igny8-bridge'); ?></h3>
<label>
<input
type="checkbox"
@@ -421,31 +345,33 @@ $webhook_logs = igny8_get_webhook_logs(array('limit' => 10));
<?php _e('WooCommerce is not active on this site. Enable the plugin to sync product data.', 'igny8-bridge'); ?>
</p>
<?php endif; ?>
</td>
</tr>
<tr>
<th scope="row"><?php _e('Taxonomies to Sync', 'igny8-bridge'); ?></th>
<td>
</div>
<div class="automation-block">
<h3><?php _e('Taxonomies to Sync', 'igny8-bridge'); ?></h3>
<div class="taxonomy-list">
<?php foreach ($available_taxonomies as $taxonomy_slug => $taxonomy_label) : ?>
<label>
<label class="taxonomy-item">
<input
type="checkbox"
name="igny8_enabled_taxonomies[]"
value="<?php echo esc_attr($taxonomy_slug); ?>"
<?php checked(in_array($taxonomy_slug, $enabled_taxonomies, true)); ?>
/>
<?php echo esc_html($taxonomy_label); ?> (<?php echo esc_html($taxonomy_slug); ?>)
<?php echo esc_html($taxonomy_label); ?> <span class="taxonomy-slug">(<?php echo esc_html($taxonomy_slug); ?>)</span>
</label>
<br />
<?php endforeach; ?>
</div>
<p class="description">
<?php _e('Select which taxonomies to synchronize bidirectionally with IGNY8.', 'igny8-bridge'); ?>
</p>
</td>
</tr>
</table>
<?php submit_button(__('Save Automation Settings', 'igny8-bridge')); ?>
</div>
<div class="automation-block" style="margin-top:18px;">
<?php submit_button(__('Save Automation Settings', 'igny8-bridge')); ?>
</div>
</div>
</div>
</form>
<p class="description">
@@ -453,23 +379,7 @@ $webhook_logs = igny8_get_webhook_logs(array('limit' => 10));
</p>
</div>
<div class="igny8-settings-card">
<h2>
<svg width="20" height="20" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24" style="vertical-align: middle; margin-right: 8px; display: inline;">
<path stroke-linecap="round" stroke-linejoin="round" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/>
</svg>
<?php _e('About', 'igny8-bridge'); ?>
</h2>
<p>
<?php _e('The IGNY8 WordPress Bridge plugin connects your WordPress site to the IGNY8 API, enabling two-way synchronization of posts, taxonomies, and site data.', 'igny8-bridge'); ?>
</p>
<p>
<strong><?php _e('Version:', 'igny8-bridge'); ?></strong> <?php echo esc_html(IGNY8_BRIDGE_VERSION); ?>
</p>
<p>
<strong><?php _e('Authentication:', 'igny8-bridge'); ?></strong> <?php _e('API Key Only (secure, modern authentication)', 'igny8-bridge'); ?>
</p>
</div>
<?php if ($is_connected) : ?>
<div class="igny8-settings-card">
@@ -717,6 +627,82 @@ $webhook_logs = igny8_get_webhook_logs(array('limit' => 10));
</div>
</div>
<?php endif; ?>
<!-- Diagnostics (moved to near end) -->
<div class="igny8-settings-card">
<h2>
<svg width="20" height="20" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24" style="vertical-align: middle; margin-right: 8px; display: inline;">
<path stroke-linecap="round" stroke-linejoin="round" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/>
</svg>
<?php _e('Diagnostics', 'igny8-bridge'); ?>
</h2>
<div class="igny8-diagnostics-grid">
<div class="igny8-diagnostic-item">
<div class="igny8-diagnostic-label"><?php _e('Access Token Age', 'igny8-bridge'); ?></div>
<div class="igny8-diagnostic-value"><?php echo esc_html($token_age_text); ?></div>
<p class="description"><?php echo esc_html($token_issued_formatted); ?></p>
</div>
<div class="igny8-diagnostic-item">
<div class="igny8-diagnostic-label"><?php _e('Last API Health Check', 'igny8-bridge'); ?></div>
<div class="igny8-diagnostic-value"><?php echo esc_html($last_health_check_formatted); ?></div>
<p class="description"><?php _e('Updated when tests succeed', 'igny8-bridge'); ?></p>
</div>
<div class="igny8-diagnostic-item">
<div class="igny8-diagnostic-label"><?php _e('Last Site Data Sync', 'igny8-bridge'); ?></div>
<div class="igny8-diagnostic-value"><?php echo esc_html($last_site_sync_formatted); ?></div>
<p class="description"><?php _e('Triggered automatically after setup', 'igny8-bridge'); ?></p>
</div>
<div class="igny8-diagnostic-item">
<div class="igny8-diagnostic-label"><?php _e('Last Full Site Scan', 'igny8-bridge'); ?></div>
<div class="igny8-diagnostic-value"><?php echo esc_html($last_full_site_scan_formatted); ?></div>
<p class="description"><?php _e('Runs weekly or when requested manually', 'igny8-bridge'); ?></p>
</div>
<div class="igny8-diagnostic-item">
<div class="igny8-diagnostic-label"><?php _e('Last Semantic Map', 'igny8-bridge'); ?></div>
<div class="igny8-diagnostic-value"><?php echo esc_html($last_semantic_map_formatted); ?></div>
<p class="description">
<?php
if (!empty($semantic_summary)) {
printf(
esc_html__('Sectors: %1$d · Keywords: %2$d', 'igny8-bridge'),
intval($semantic_summary['sectors'] ?? 0),
intval($semantic_summary['keywords'] ?? 0)
);
} else {
_e('Planner semantic map generated after full scan', 'igny8-bridge');
}
?>
</p>
</div>
<div class="igny8-diagnostic-item">
<div class="igny8-diagnostic-label"><?php _e('Last Taxonomy Sync', 'igny8-bridge'); ?></div>
<div class="igny8-diagnostic-value"><?php echo esc_html($last_taxonomy_sync_formatted); ?></div>
<p class="description"><?php _e('Sectors & clusters imported from Planner', 'igny8-bridge'); ?></p>
</div>
<div class="igny8-diagnostic-item">
<div class="igny8-diagnostic-label"><?php _e('Last Keyword Sync', 'igny8-bridge'); ?></div>
<div class="igny8-diagnostic-value"><?php echo esc_html($last_keyword_sync_formatted); ?></div>
<p class="description"><?php _e('Planner keywords cached to WordPress posts', 'igny8-bridge'); ?></p>
</div>
<div class="igny8-diagnostic-item">
<div class="igny8-diagnostic-label"><?php _e('Last Writer Sync', 'igny8-bridge'); ?></div>
<div class="igny8-diagnostic-value"><?php echo esc_html($last_writer_sync_formatted); ?></div>
<p class="description"><?php _e('New IGNY8 tasks imported automatically', 'igny8-bridge'); ?></p>
</div>
<div class="igny8-diagnostic-item">
<div class="igny8-diagnostic-label"><?php _e('Next Scheduled Site Scan', 'igny8-bridge'); ?></div>
<div class="igny8-diagnostic-value"><?php echo esc_html($next_site_sync_formatted); ?></div>
</div>
</div>
</div>
<!-- About (moved to the end) -->
<div class="igny8-settings-card">
<h2><?php _e('About', 'igny8-bridge'); ?></h2>
<p><?php _e('The IGNY8 WordPress Bridge plugin connects your WordPress site to the IGNY8 API, enabling two-way synchronization of posts, taxonomies, and site data.', 'igny8-bridge'); ?></p>
<p><strong><?php _e('Version:', 'igny8-bridge'); ?></strong> <?php echo esc_html(IGNY8_BRIDGE_VERSION); ?></p>
<p><strong><?php _e('Authentication:', 'igny8-bridge'); ?></strong> <?php _e('API Key Only (secure, modern authentication)', 'igny8-bridge'); ?></p>
</div>
</div>
<?php endif; ?>
</div>