Plugin Directory

Changeset 3462134


Ignore:
Timestamp:
02/16/2026 01:30:43 AM (3 days ago)
Author:
rankpilotai
Message:

v1.0.25 – Modernized settings page UI: gradient header with plugin logo, card-based layout, model radio cards, usage grid with progress bar, index/noindex grid, responsive design. Settings CSS moved inline.

Location:
ai-snippet-seo-pro/trunk
Files:
1 added
4 edited

Legend:

Unmodified
Added
Removed
  • ai-snippet-seo-pro/trunk/admin/assets/css/admin.css

    r3389613 r3462134  
    11/*!
    22 * AI Snippet SEO Pro — Admin Styles
    3  * Version: 1.0.0
    4  * Styles for editor meta boxes and settings screens.
     3 * Version: 1.0.25
     4 * Styles for editor meta boxes and post list columns.
     5 * Settings page CSS is now inline in settings-page.php.
    56 */
    67
     
    5051}
    5152
    52 /* Align with WP “Publish” meta box spacing */
     53/* Align with WP "Publish" meta box spacing */
    5354.misc-pub-section {
    5455  padding-left: 8px !important;
    5556}
    56 
    57 /* Settings page container */
    58 .aissp-settings-wrap {
    59   background: #fff;
    60   padding: 20px;
    61   max-width: 800px;
    62   border: 1px solid #ddd;
    63   border-radius: 4px;
    64 }
    65 .aissp-settings-wrap h1 {
    66   margin-top: 0;
    67   margin-bottom: 10px;
    68   border-bottom: 1px solid #ddd;
    69   padding-bottom: 8px;
    70 }
    71 
    72 /* Wider label column in WP form tables */
    73 .form-table th {
    74   width: 250px;
    75 }
    76 
    77 /* ================================
    78    MOVED FROM settings-page.php <style>
    79    ================================ */
    80 :root{--dark:#243746;--blue:#0984e3;--blue-light:#0b9dfb;--border:#ddd;--bg:#f9f9f9;}
    81 /* layout */
    82 .aissp-wrapper{max-width:1180px;margin:25px 20px 40px 0;display:flex;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif }
    83 .aissp-sidebar{width:260px;background:var(--dark);border-radius:8px 0 0 8px;padding:26px 22px;color:#fff}
    84 .aissp-sidebar h2{font-size:24px;margin:0 0 20px;font-weight:700;border-bottom:1px solid rgba(255,255,255,.15);padding-bottom:14px;color:#fff}
    85 .aissp-sidebar nav a{display:block;padding:12px 14px;border-radius:6px;color:#dfe6e8;text-decoration:none;font-size:18px;margin-bottom:10px;transition:background .2s}
    86 .aissp-sidebar nav a.active,.aissp-sidebar nav a:hover{background:#2f4d64;color:var(--blue)}
    87 .aissp-content{flex:1;background:#fff;border:1px solid var(--border);border-left:none;border-radius:0 8px 8px 0;padding:34px}
    88 .aissp-content h2{margin-top:0;font-size:30px;font-weight:700;color:var(--dark)}
    89 /* inputs & buttons */
    90 .regular-text{width:100%;padding:12px;font-size:17px;background:var(--bg);border:1px solid #ccc;border-radius:4px}
    91 .primary-btn{background:var(--blue);color:#fff!important;border:none;border-radius:6px;padding:12px 28px;font-size:18px;cursor:pointer;transition:background .2s,transform .05s;text-decoration:none;display:inline-block}
    92 .primary-btn:hover{background:var(--blue-light);transform:translateY(-1px);color:#fff!important}
    93 .token-view{display:inline-block;background:#eef2f6;padding:6px 12px;border-radius:4px;font-size:18px}
    94 /* text */
    95 .desc,.intro-txt,.description{font-size:17px;color:#555;margin-top:12px;margin-bottom:0}
    96 .linkpad{margin-bottom:18px}
    97 .need-key{margin-left:8px;color:#666;font-size:17px}
    98 /* key row */
    99 .key-row{display:flex;align-items:center;gap:12px;margin-top:12px;max-width:540px}
    100 .key-row input{flex:1}
    101 .sub-head{margin:18px 0 6px;font-size:22px;color:var(--blue);font-weight:700}
    102 /* usage */
    103 .usage-card{border:1px solid var(--border);background:#fff;border-radius:6px;padding:20px;margin-top:28px;max-width:820px}
    104 .usage-card h3{margin:0 0 14px;font-size:22px;color:var(--blue);font-weight:700}
    105 .usage-table{width:100%;border-collapse:collapse;font-size:17px}
    106 .usage-table th,.usage-table td{border:1px solid var(--border);padding:10px;text-align:left}
    107 .bar-bg{background:#dbeafe;height:14px;border-radius:7px;overflow:hidden;width:100%}
    108 .bar-fill{background:#3b82f6;height:100%}
    109 /* form table */
    110 .form-table td{padding:10px 0}
    111 textarea{ font-family:inherit }
    112 /* ---------- MOBILE  (<991 px) ------------ */
    113 @media (max-width: 991px){
    114   html,body{overflow-x:hidden;}
    115   .aissp-wrapper{flex-direction:column;font-size:15px;}
    116   .aissp-sidebar{width:100%;border-radius:8px 8px 0 0;padding:20px;}
    117   .aissp-content{padding:24px;border-radius:0 0 8px 8px;overflow-x:hidden;}
    118   .aissp-sidebar nav a{font-size:17px;margin-bottom:6px;padding:11px 12px;}
    119   .primary-btn{width:100%;text-align:center;margin-top:12px;}
    120   .key-row{flex-direction:column;gap:10px;}
    121   .key-row input{width:100%;}
    122   .form-table select{width:100%;font-size:15px;padding:10px;appearance:auto;-webkit-appearance:menulist;}
    123   .usage-card{padding:18px;}
    124   .usage-table,.usage-table thead{display:none;}
    125   .usage-table{width:100%;}
    126   .usage-table tbody{display:block;}
    127   .usage-table tr{display:block;border:1px solid var(--border);border-radius:6px;margin:0 0 18px;background:#fff;}
    128   .usage-table td{display:block;padding:12px 14px;border:none;}
    129   .usage-table td::before{display:block;font-weight:600;color:var(--dark);margin-bottom:4px;}
    130   .usage-table td:nth-of-type(1)::before{content:"This Site";}
    131   .usage-table td:nth-of-type(2)::before{content:"Usage";}
    132   .usage-table td:nth-of-type(3)::before{content:"Plan Limit";}
    133   .usage-table td:nth-of-type(4)::before{content:"Remaining";}
    134   .usage-table td:nth-of-type(5)::before{content:"Progress";}
    135   .usage-table td:nth-of-type(6)::before{content:"Action";}
    136   .usage-table td:nth-of-type(5) .bar-bg{width:100%;margin-top:2px;}
    137   .usage-table td:nth-of-type(6) .primary-btn{width:100%;margin:6px 0 0;}
    138   .form-table,.form-table tbody,.form-table tr,.form-table td,.form-table th{display:block;width:100%;}
    139   .form-table th{margin-top:18px;}
    140 }
    141 /* Global select-arrow fix */
    142 .aissp-content select,.form-table select{
    143     appearance:none;-webkit-appearance:none;-moz-appearance:none;background:#f9f9f9
    144         url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23243746'%3E%3Cpath d='M7 10l5 5 5-5'/%3E%3C/svg%3E")
    145         no-repeat right 14px center;background-size:14px 14px;padding-right:48px;
    146 }
    147 .form-table textarea{width:100%!important}
    148 .aissp-content h2{line-height:1.15}
    149 /* EXTRA MOBILE tweaks */
    150 @media (max-width: 991px){
    151   .form-table .description{max-width:100%;white-space:normal}
    152   .usage-table td{padding:12px 14px 12px 46%;text-align:right;color:var(--dark);}
    153   .usage-table td:nth-of-type(5)::before{content:"Progress";}
    154   .usage-table td:nth-of-type(6) .primary-btn{width:100%;margin:6px 0 0;}
    155 }
    156 @media (max-width: 991px){
    157     .usage-table,.usage-table thead,.usage-table tbody,.usage-table tr,.usage-table th,.usage-table td{
    158         display:block!important;width:100%!important;
    159     }
    160     .usage-table thead{display:none!important;}
    161     .usage-table tr{margin:0;border:none;}
    162     .usage-table td{border:none;border-bottom:1px solid #e5e5e5;padding:12px 12px 12px 48%;position:relative;min-height:44px;box-sizing:border-box;font-size:17px;}
    163     .usage-table td::before{position:absolute;left:12px;top:50%;transform:translateY(-50%);font-weight:600;color:var(--dark);white-space:nowrap;}
    164     .usage-table td:nth-of-type(1)::before{content:"Website";}
    165     .usage-table td:nth-of-type(2)::before{content:"Usage";}
    166     .usage-table td:nth-of-type(3)::before{content:"Limit";}
    167     .usage-table td:nth-of-type(4)::before{content:"Remaining";}
    168     .usage-table td:nth-of-type(5)::before{content:"Progress";}
    169     .usage-table td:nth-of-type(6)::before{content:"Get More Tokens";}
    170     .bar-bg{margin-top:6px}
    171     .usage-table td:nth-of-type(6) .primary-btn{width:100%;margin-top:8px;text-align:center}
    172     .usage-card{overflow:hidden}
    173 }
    174 @media (max-width: 991px){
    175     .usage-table td:nth-of-type(6){padding-left:12px}
    176     .usage-table td:nth-of-type(6)::before{position:static;display:block;margin-bottom:6px}
    177 }
    178 @media (max-width: 991px){
    179     .usage-table td:nth-of-type(6){text-align:center;padding-left:12px}
    180     .usage-table td:nth-of-type(6)::before{position:static;display:block;margin-bottom:6px;text-align:center}
    181     .usage-table td:nth-of-type(6) .primary-btn{width:100%;margin:8px auto 0}
    182 }
    183 @media (max-width: 991px){
    184     .usage-table td:nth-of-type(6){padding-left:0;padding-right:0;text-align:center}
    185     .usage-table td:nth-of-type(6) .primary-btn{width:100%;margin:10px 0 0}
    186 }
  • ai-snippet-seo-pro/trunk/admin/settings-page.php

    r3389613 r3462134  
    66 * @package   RankPilotAI\AI_Snippet_SEO_Pro\Admin
    77 * @since     1.0.0
    8  * @version   1.0.0
     8 * @version   1.0.25
    99 * @license   GPL-2.0-or-later
    1010 *
     
    1313 * - Updated token costs → 1 / 3 / 5  (Turbo=1, 4.1=3, 4o=5)
    1414 * - Membership gates (API + PMPro fallback)
    15  * - “Get Started / Buy Tokens” flow
     15 * - "Get Started / Buy Tokens" flow
    1616 * - Show Usage Overview immediately after the first Site Key save
    1717 * - Reject saving keys that belong to another domain
     
    228228        'category'=>'yes','post_tag'=>'no','product_cat'=>'yes','product_tag'=>'no'
    229229    ];
     230
     231    /* ---------- Header logo ---------- */
     232    $header_logo = esc_url( AISSP_URL . 'admin/assets/img/header-logo.png' );
    230233    ?>
    231234<!-- AISSPro build: <?php echo esc_html($__aissp_build); ?> -->
    232 <!-- =================================================================
    233       BEGIN  HTML
    234 ================================================================= -->
    235 <div class="aissp-wrapper">
    236     <aside class="aissp-sidebar">
    237         <h2>AI Snippet SEO Pro</h2>
    238         <nav>
    239             <a href="<?php echo esc_url( add_query_arg('tab','site-key',admin_url('admin.php?page=ai-snippet-seo-pro')) ); ?>"
    240                class="<?php echo $tab==='site-key' ? 'active' : ''; ?>">Site Key Management</a>
    241             <a href="<?php echo esc_url( add_query_arg('tab','seo-settings',admin_url('admin.php?page=ai-snippet-seo-pro')) ); ?>"
    242                class="<?php echo $tab==='seo-settings' ? 'active' : ''; ?>">SEO Snippet Settings</a>
    243         </nav>
    244     </aside>
    245 
    246     <main class="aissp-content">
     235<style>
     236/* ── AI Snippet SEO Pro — Modern Settings ── */
     237:root{--aissp-dark:#1a2332;--aissp-blue:#0984e3;--aissp-blue-light:#0b9dfb;--aissp-green:#00b894;--aissp-purple:#6c5ce7;--aissp-border:#e2e8f0;--aissp-bg:#f8fafc;--aissp-card:#fff;--aissp-radius:12px;--aissp-shadow:0 1px 3px rgba(0,0,0,.08)}
     238*,*::before,*::after{box-sizing:border-box}
     239
     240/* Header */
     241.aissp-header{background:linear-gradient(135deg,#1a2332 0%,#2d3f56 50%,#0984e3 100%);border-radius:var(--aissp-radius) var(--aissp-radius) 0 0;padding:28px 34px;display:flex;align-items:center;gap:16px}
     242.aissp-header img{width:48px;height:48px;border-radius:10px}
     243.aissp-header-text h1{margin:0;font-size:22px;font-weight:700;color:#fff;line-height:1.2}
     244.aissp-header-text p{margin:4px 0 0;font-size:13px;color:rgba(255,255,255,.7)}
     245
     246/* Nav tabs */
     247.aissp-nav{display:flex;gap:0;background:#f1f5f9;border-left:1px solid var(--aissp-border);border-right:1px solid var(--aissp-border)}
     248.aissp-nav a{flex:1;text-align:center;padding:14px 20px;font-size:15px;font-weight:600;color:#64748b;text-decoration:none;border-bottom:3px solid transparent;transition:all .2s}
     249.aissp-nav a:hover{color:var(--aissp-blue);background:#fff}
     250.aissp-nav a.active{color:var(--aissp-blue);border-bottom-color:var(--aissp-blue);background:#fff}
     251.aissp-nav a svg{width:16px;height:16px;vertical-align:-2px;margin-right:6px}
     252
     253/* Container */
     254.aissp-container{max-width:900px;margin:24px auto 40px;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif}
     255.aissp-body{background:var(--aissp-card);border:1px solid var(--aissp-border);border-top:none;border-radius:0 0 var(--aissp-radius) var(--aissp-radius);padding:32px 34px}
     256
     257/* Section titles */
     258.aissp-section-title{font-size:18px;font-weight:700;color:var(--aissp-dark);margin:0 0 6px;display:flex;align-items:center;gap:10px}
     259.aissp-section-title svg{width:22px;height:22px;color:var(--aissp-blue);flex-shrink:0}
     260.aissp-section-desc{font-size:14px;color:#64748b;margin:0 0 20px}
     261
     262/* Cards */
     263.aissp-card{background:var(--aissp-bg);border:1px solid var(--aissp-border);border-radius:10px;padding:22px 24px;margin-bottom:24px}
     264
     265/* Token view */
     266.aissp-token-display{display:inline-block;background:#e2e8f0;padding:8px 16px;border-radius:8px;font-family:monospace;font-size:15px;color:var(--aissp-dark);letter-spacing:.3px}
     267
     268/* Key input row */
     269.aissp-key-row{display:flex;align-items:center;gap:12px;margin-top:14px;max-width:560px}
     270.aissp-key-row input{flex:1;padding:11px 14px;font-size:15px;border:1px solid #cbd5e1;border-radius:8px;background:#fff;transition:border-color .2s}
     271.aissp-key-row input:focus{outline:none;border-color:var(--aissp-blue);box-shadow:0 0 0 3px rgba(9,132,227,.12)}
     272
     273/* Buttons */
     274.aissp-btn{display:inline-block;padding:11px 28px;font-size:15px;font-weight:600;border:none;border-radius:8px;cursor:pointer;text-decoration:none;transition:all .2s;line-height:1.4}
     275.aissp-btn-primary{background:var(--aissp-blue);color:#fff!important}
     276.aissp-btn-primary:hover{background:var(--aissp-blue-light);transform:translateY(-1px);color:#fff!important}
     277.aissp-btn-green{background:var(--aissp-green);color:#fff!important}
     278.aissp-btn-green:hover{background:#00a884;transform:translateY(-1px);color:#fff!important}
     279
     280/* Usage grid */
     281.aissp-usage-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:16px;margin-top:20px}
     282.aissp-usage-stat{background:#fff;border:1px solid var(--aissp-border);border-radius:10px;padding:18px;text-align:center}
     283.aissp-usage-stat .label{font-size:12px;color:#94a3b8;text-transform:uppercase;letter-spacing:.5px;margin-bottom:6px}
     284.aissp-usage-stat .value{font-size:24px;font-weight:700;color:var(--aissp-dark)}
     285.aissp-usage-stat .value.blue{color:var(--aissp-blue)}
     286.aissp-usage-stat .value.green{color:var(--aissp-green)}
     287.aissp-usage-stat .value.red{color:#e74c3c}
     288
     289/* Progress bar */
     290.aissp-progress{background:#e2e8f0;height:10px;border-radius:5px;overflow:hidden;margin:16px 0 8px}
     291.aissp-progress-fill{height:100%;border-radius:5px;transition:width .4s ease}
     292.aissp-progress-text{font-size:13px;color:#64748b;text-align:right}
     293
     294/* Model radio cards */
     295.aissp-model-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:14px;margin-bottom:20px}
     296.aissp-model-card{position:relative;background:#fff;border:2px solid var(--aissp-border);border-radius:10px;padding:20px 16px;text-align:center;cursor:pointer;transition:all .2s}
     297.aissp-model-card:hover{border-color:var(--aissp-blue);box-shadow:var(--aissp-shadow)}
     298.aissp-model-card.selected{border-color:var(--aissp-blue);background:#eff6ff;box-shadow:0 0 0 3px rgba(9,132,227,.15)}
     299.aissp-model-card.disabled{opacity:.45;cursor:not-allowed;pointer-events:none}
     300.aissp-model-card input[type="radio"]{position:absolute;opacity:0;pointer-events:none}
     301.aissp-model-card .icon{font-size:28px;margin-bottom:8px}
     302.aissp-model-card .name{font-size:14px;font-weight:700;color:var(--aissp-dark);margin-bottom:2px}
     303.aissp-model-card .tier{font-size:12px;color:#94a3b8;margin-bottom:6px}
     304.aissp-model-card .cost{display:inline-block;background:#f1f5f9;padding:3px 10px;border-radius:20px;font-size:12px;font-weight:600;color:var(--aissp-blue)}
     305
     306/* Form elements */
     307.aissp-label{display:block;font-size:14px;font-weight:600;color:var(--aissp-dark);margin-bottom:6px}
     308.aissp-input{width:100%;padding:11px 14px;font-size:15px;border:1px solid #cbd5e1;border-radius:8px;background:#fff;font-family:inherit;transition:border-color .2s}
     309.aissp-input:focus{outline:none;border-color:var(--aissp-blue);box-shadow:0 0 0 3px rgba(9,132,227,.12)}
     310.aissp-hint{font-size:13px;color:#94a3b8;margin-top:6px}
     311
     312/* Index settings grid */
     313.aissp-index-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:12px}
     314.aissp-index-item{display:flex;align-items:center;justify-content:space-between;background:#fff;border:1px solid var(--aissp-border);border-radius:8px;padding:12px 16px}
     315.aissp-index-item .type-label{font-size:14px;font-weight:600;color:var(--aissp-dark)}
     316.aissp-index-item select{padding:6px 32px 6px 10px;font-size:13px;border:1px solid #cbd5e1;border-radius:6px;background:#fff url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%231a2332'%3E%3Cpath d='M7 10l5 5 5-5'/%3E%3C/svg%3E") no-repeat right 8px center;background-size:12px;appearance:none;-webkit-appearance:none;cursor:pointer}
     317
     318/* Auto-slug toggle */
     319.aissp-toggle-row{display:flex;align-items:center;gap:12px;padding:16px 20px;background:var(--aissp-bg);border:1px solid var(--aissp-border);border-radius:10px;margin-top:20px}
     320.aissp-toggle-row input[type="checkbox"]{width:18px;height:18px;accent-color:var(--aissp-blue);cursor:pointer}
     321.aissp-toggle-label{font-size:14px;color:var(--aissp-dark)}
     322.aissp-toggle-label strong{font-weight:600}
     323.aissp-toggle-label small{display:block;font-size:12px;color:#94a3b8;margin-top:2px}
     324
     325/* Divider */
     326.aissp-divider{border:none;border-top:1px solid var(--aissp-border);margin:28px 0}
     327
     328/* Intro text */
     329.aissp-intro{font-size:15px;color:#64748b;margin:0 0 20px}
     330.aissp-intro a{color:var(--aissp-blue);text-decoration:none;font-weight:600}
     331.aissp-intro a:hover{text-decoration:underline}
     332
     333/* Responsive */
     334@media(max-width:768px){
     335    .aissp-header{padding:20px;flex-wrap:wrap}
     336    .aissp-body{padding:20px}
     337    .aissp-nav a{padding:12px 10px;font-size:13px}
     338    .aissp-usage-grid{grid-template-columns:repeat(2,1fr);gap:10px}
     339    .aissp-model-grid{grid-template-columns:1fr}
     340    .aissp-index-grid{grid-template-columns:1fr}
     341    .aissp-key-row{flex-direction:column;max-width:100%}
     342    .aissp-key-row input{width:100%}
     343    .aissp-btn{width:100%;text-align:center}
     344}
     345@media(max-width:480px){
     346    .aissp-usage-grid{grid-template-columns:1fr 1fr;gap:8px}
     347    .aissp-usage-stat{padding:14px 10px}
     348    .aissp-usage-stat .value{font-size:20px}
     349}
     350</style>
     351
     352<div class="aissp-container">
     353
     354    <!-- ── HEADER ── -->
     355    <div class="aissp-header">
     356        <img src="<?php echo $header_logo; ?>" alt="AI Snippet SEO Pro" width="48" height="48">
     357        <div class="aissp-header-text">
     358            <h1>AI Snippet SEO Pro</h1>
     359            <p>Generate AI SEO titles &amp; meta descriptions in one click</p>
     360        </div>
     361    </div>
     362
     363    <!-- ── NAV ── -->
     364    <div class="aissp-nav">
     365        <a href="<?php echo esc_url( add_query_arg('tab','site-key',admin_url('admin.php?page=ai-snippet-seo-pro')) ); ?>"
     366           class="<?php echo $tab==='site-key' ? 'active' : ''; ?>">
     367            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 2l-2 2m-7.61 7.61a5.5 5.5 0 1 1-7.778 7.778 5.5 5.5 0 0 1 7.777-7.777zm0 0L15.5 7.5m0 0l3 3L22 7l-3-3m-3.5 3.5L19 4"/></svg>
     368            Site Key Management
     369        </a>
     370        <a href="<?php echo esc_url( add_query_arg('tab','seo-settings',admin_url('admin.php?page=ai-snippet-seo-pro')) ); ?>"
     371           class="<?php echo $tab==='seo-settings' ? 'active' : ''; ?>">
     372            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83-2.83l.06-.06A1.65 1.65 0 0 0 4.68 15a1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 2.83-2.83l.06.06A1.65 1.65 0 0 0 9 4.68a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 2.83l-.06.06A1.65 1.65 0 0 0 19.4 9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z"/></svg>
     373            SEO Snippet Settings
     374        </a>
     375    </div>
     376
     377    <!-- ── BODY ── -->
     378    <div class="aissp-body">
     379
    247380    <?php /* ================= TAB: SITE KEY ================= */ ?>
    248381    <?php if ( $tab === 'site-key' ) : ?>
    249         <h2>RankPilotAI – Site Key Management</h2>
     382
     383        <div class="aissp-section-title">
     384            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 2l-2 2m-7.61 7.61a5.5 5.5 0 1 1-7.778 7.778 5.5 5.5 0 0 1 7.777-7.777zm0 0L15.5 7.5m0 0l3 3L22 7l-3-3m-3.5 3.5L19 4"/></svg>
     385            Site Key Management
     386        </div>
    250387
    251388        <?php if ( ! $token ) : ?>
    252             <p class="intro-txt">Enter your Site Key below to get started.</p>
    253             <form method="post" class="aissp-form">
    254                 <?php wp_nonce_field('aissp_save_site_key'); ?>
    255                 <input type="hidden" name="aissp_action" value="aissp_save_site_key">
    256                 <input type="text" name="site_token" class="regular-text" placeholder="rp_xxxxxxxxxxxxxxxxx" required>
    257                 <p class="desc linkpad">Generate your Site Key from your account at
    258                     <a href="https://rankpilotai.com" target="_blank" rel="noopener">RankPilotAI.com</a></p>
    259                 <button class="primary-btn">Save Site Key</button>
    260             </form>
     389            <p class="aissp-intro">Enter your Site Key below to connect your site with
     390                <a href="https://rankpilotai.com" target="_blank" rel="noopener">RankPilotAI</a>.</p>
     391
     392            <div class="aissp-card">
     393                <form method="post">
     394                    <?php wp_nonce_field('aissp_save_site_key'); ?>
     395                    <input type="hidden" name="aissp_action" value="aissp_save_site_key">
     396                    <label class="aissp-label">Site Key</label>
     397                    <div class="aissp-key-row">
     398                        <input type="text" name="site_token" class="aissp-input" placeholder="rp_xxxxxxxxxxxxxxxxx" required style="flex:1">
     399                        <button type="submit" class="aissp-btn aissp-btn-primary">Save Site Key</button>
     400                    </div>
     401                    <p class="aissp-hint">Generate your Site Key from your account at
     402                        <a href="https://rankpilotai.com" target="_blank" rel="noopener" style="color:var(--aissp-blue)">RankPilotAI.com</a></p>
     403                </form>
     404            </div>
    261405
    262406        <?php else : ?>
    263             <p><strong>Your Active Site Key</strong></p>
    264             <code class="token-view"><?php echo esc_html($token); ?></code>
     407            <p class="aissp-section-desc">Your site is connected to RankPilotAI.</p>
     408
     409            <div class="aissp-card">
     410                <label class="aissp-label">Active Site Key</label>
     411                <div class="aissp-token-display"><?php echo esc_html($token); ?></div>
     412            </div>
    265413
    266414            <?php if ( $usage !== null ) : ?>
    267             <div class="usage-card">
    268                 <h3>Usage Overview</h3>
    269                 <table class="usage-table">
    270                     <thead><tr>
    271                         <th>This&nbsp;Site</th>
    272                         <th>Usage</th>
    273                         <th>Plan&nbsp;Limit</th>
    274                         <th>Remaining</th>
    275                         <th>Progress</th>
    276                         <th></th>
    277                     </tr></thead>
    278                     <tbody><tr>
    279                         <td><?php echo esc_html( parse_url( home_url(), PHP_URL_HOST ) ?: 'Site' ); ?></td>
    280                         <td><?php echo number_format_i18n( (int)$usage ); ?></td> <!-- GLOBAL usage -->
    281                         <td><?php echo number_format_i18n( (int)$limit ); ?></td>
    282                         <td><?php echo number_format_i18n( (int)$remain ); ?></td>   <!-- GLOBAL remaining -->
    283                         <td>
    284                             <?php
    285                                 $pct = $limit ? round( (($limit - (int)$remain) / (int)$limit) * 100 ) : 0;
    286                                 $bar = ($remain === 0) ? '#dc3232' : '#3b82f6';
    287                             ?>
    288                             <div class="bar-bg">
    289                               <div class="bar-fill" style="width:<?php echo $pct; ?>%;background:<?php echo $bar; ?>"></div>
    290                             </div>
    291                         </td>
    292                         <td>
    293                             <a href="<?php echo esc_url( $token_btn_url ); ?>" target="_blank" rel="noopener"
    294                                class="primary-btn"><?php echo esc_html( $token_btn_label ); ?></a>
    295                         </td>
    296                     </tr></tbody>
    297                 </table>
     415            <!-- Usage Overview -->
     416            <div class="aissp-section-title" style="margin-top:28px">
     417                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 20V10"/><path d="M18 20V4"/><path d="M6 20v-4"/></svg>
     418                Usage Overview
     419            </div>
     420            <p class="aissp-section-desc">Your current token usage across all sites.</p>
     421
     422            <div class="aissp-card" style="padding-bottom:16px">
     423                <div class="aissp-usage-grid">
     424                    <div class="aissp-usage-stat">
     425                        <div class="label">Website</div>
     426                        <div class="value" style="font-size:15px"><?php echo esc_html( parse_url( home_url(), PHP_URL_HOST ) ?: 'Site' ); ?></div>
     427                    </div>
     428                    <div class="aissp-usage-stat">
     429                        <div class="label">Usage</div>
     430                        <div class="value blue"><?php echo number_format_i18n( (int)$usage ); ?></div>
     431                    </div>
     432                    <div class="aissp-usage-stat">
     433                        <div class="label">Plan Limit</div>
     434                        <div class="value"><?php echo number_format_i18n( (int)$limit ); ?></div>
     435                    </div>
     436                    <div class="aissp-usage-stat">
     437                        <div class="label">Remaining</div>
     438                        <div class="value <?php echo (int)$remain > 0 ? 'green' : 'red'; ?>"><?php echo number_format_i18n( (int)$remain ); ?></div>
     439                    </div>
     440                </div>
     441
     442                <?php
     443                    $pct = $limit ? round( (($limit - (int)$remain) / (int)$limit) * 100 ) : 0;
     444                    $bar_color = ($remain === 0) ? '#e74c3c' : 'var(--aissp-blue)';
     445                ?>
     446                <div class="aissp-progress">
     447                    <div class="aissp-progress-fill" style="width:<?php echo (int)$pct; ?>%;background:<?php echo $bar_color; ?>"></div>
     448                </div>
     449                <div class="aissp-progress-text"><?php echo (int)$pct; ?>% used</div>
     450
     451                <div style="text-align:center;margin-top:16px">
     452                    <a href="<?php echo esc_url( $token_btn_url ); ?>" target="_blank" rel="noopener"
     453                       class="aissp-btn <?php echo $membership === 'free' ? 'aissp-btn-primary' : 'aissp-btn-green'; ?>">
     454                        <?php echo esc_html( $token_btn_label ); ?>
     455                    </a>
     456                </div>
    298457            </div>
    299458            <?php endif; ?>
    300459
    301             <form method="post" class="aissp-form" style="margin-top:26px;">
    302                 <?php wp_nonce_field('aissp_save_site_key'); ?>
    303                 <input type="hidden" name="aissp_action" value="aissp_save_site_key">
    304                 <h3 class="sub-head">Update / Change Site Key</h3>
    305                 <div class="key-row">
    306                     <input type="text" name="site_token" value="<?php echo esc_attr($token); ?>" class="regular-text">
    307                     <button class="primary-btn">Save</button>
    308                 </div>
    309             </form>
     460            <!-- Update Key -->
     461            <hr class="aissp-divider">
     462            <div class="aissp-section-title">
     463                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"/><path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"/></svg>
     464                Update / Change Site Key
     465            </div>
     466            <div class="aissp-card">
     467                <form method="post">
     468                    <?php wp_nonce_field('aissp_save_site_key'); ?>
     469                    <input type="hidden" name="aissp_action" value="aissp_save_site_key">
     470                    <div class="aissp-key-row">
     471                        <input type="text" name="site_token" value="<?php echo esc_attr($token); ?>">
     472                        <button type="submit" class="aissp-btn aissp-btn-primary">Save</button>
     473                    </div>
     474                </form>
     475            </div>
    310476        <?php endif; ?>
    311477
     
    313479    <?php else :
    314480        $dis = empty($token) ? 'disabled' : ''; ?>
    315         <h2>SEO Snippet Settings</h2>
    316 
    317         <form method="post" class="aissp-form-wide">
     481
     482        <div class="aissp-section-title">
     483            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83-2.83l.06-.06A1.65 1.65 0 0 0 4.68 15a1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 2.83-2.83l.06.06A1.65 1.65 0 0 0 9 4.68a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 2.83l-.06.06A1.65 1.65 0 0 0 19.4 9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z"/></svg>
     484            SEO Snippet Settings
     485        </div>
     486        <p class="aissp-section-desc">Configure your AI model, prompts, indexing rules and slug behavior.</p>
     487
     488        <form method="post">
    318489            <?php wp_nonce_field('aissp_save_seo_settings'); ?>
    319490            <input type="hidden" name="aissp_action" value="aissp_save_seo_settings">
    320491
    321             <table class="form-table">
    322 
    323                 <tr>
    324                     <th><label for="model_choice">GPT Model</label></th>
    325                     <td>
    326                         <select id="model_choice" name="model_choice" <?php echo $dis;?>>
    327                             <option value="gpt-4-turbo" <?php selected($model,'gpt-4-turbo'); ?>>
    328                                 🟢 Economical (GPT-4 Turbo) – 1 token / snippet</option>
    329 
    330                             <option value="gpt-4.1" <?php selected($model,'gpt-4.1');?>
    331                                 <?php echo in_array('gpt-4.1',$allowed,true)?'':'disabled';?>>
    332                                 🔵 Balanced (GPT-4.1) – 3 tokens / snippet</option>
    333 
    334                             <option value="gpt-4o" <?php selected($model,'gpt-4o');?>
    335                                 <?php echo in_array('gpt-4o',$allowed,true)?'':'disabled';?>>
    336                                 🟣 Premium (GPT-4o) – 5 tokens / snippet</option>
    337                         </select>
    338                         <p class="description" style="margin-top:6px;">
    339                             Unavailable options appear greyed-out – upgrade your plan to unlock them.
    340                         </p>
    341                     </td>
    342                 </tr>
    343 
    344                 <tr>
    345                     <th><label for="custom_prompt">Custom Prompt</label></th>
    346                     <td>
    347                         <textarea id="custom_prompt" name="custom_prompt" rows="3" class="regular-text"
    348                                   style="width:420px;" <?php echo $dis;?>><?php
    349                             echo esc_textarea($opts['custom_prompt']??'');?></textarea>
    350                         <p class="description">
    351                             We already apply an internal prompt that meets all SEO criteria.
    352                             Add tone or extra instructions here if you want the AI to include them
    353                             <em>on top of</em> ours.
    354                         </p>
    355                     </td>
    356                 </tr>
    357 
     492            <!-- Model Selection -->
     493            <label class="aissp-label" style="margin-bottom:12px">
     494                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="width:16px;height:16px;vertical-align:-2px;margin-right:4px"><path d="M12 2L2 7l10 5 10-5-10-5z"/><path d="M2 17l10 5 10-5"/><path d="M2 12l10 5 10-5"/></svg>
     495                GPT Model
     496            </label>
     497            <div class="aissp-model-grid">
     498                <?php
     499                $models = [
     500                    'gpt-4-turbo' => ['name'=>'GPT-4 Turbo','tier'=>'Economical','cost'=>'1 token / snippet','icon'=>'&#x1F7E2;','color'=>'#00b894'],
     501                    'gpt-4.1'     => ['name'=>'GPT-4.1','tier'=>'Balanced','cost'=>'3 tokens / snippet','icon'=>'&#x1F535;','color'=>'#0984e3'],
     502                    'gpt-4o'      => ['name'=>'GPT-4o','tier'=>'Premium','cost'=>'5 tokens / snippet','icon'=>'&#x1F7E3;','color'=>'#6c5ce7'],
     503                ];
     504                foreach ( $models as $val => $m ) :
     505                    $is_allowed  = in_array( $val, $allowed, true );
     506                    $is_selected = ( $model === $val );
     507                    $cls  = 'aissp-model-card';
     508                    $cls .= $is_selected ? ' selected' : '';
     509                    $cls .= ( !$is_allowed || $dis ) ? ' disabled' : '';
     510                ?>
     511                <label class="<?php echo esc_attr($cls); ?>">
     512                    <input type="radio" name="model_choice" value="<?php echo esc_attr($val); ?>"
     513                           <?php checked($is_selected); ?>
     514                           <?php echo (!$is_allowed || $dis) ? 'disabled' : ''; ?>>
     515                    <div class="icon"><?php echo $m['icon']; ?></div>
     516                    <div class="name"><?php echo esc_html($m['name']); ?></div>
     517                    <div class="tier"><?php echo esc_html($m['tier']); ?></div>
     518                    <div class="cost"><?php echo esc_html($m['cost']); ?></div>
     519                </label>
     520                <?php endforeach; ?>
     521            </div>
     522            <p class="aissp-hint">Greyed-out models require a higher plan.
     523                <a href="https://rankpilotai.com/ai-snippet-seo-pro-pricing/" target="_blank" rel="noopener" style="color:var(--aissp-blue)">Upgrade</a></p>
     524
     525            <hr class="aissp-divider">
     526
     527            <!-- Custom Prompt -->
     528            <div class="aissp-card">
     529                <label class="aissp-label" for="custom_prompt">Custom Prompt</label>
     530                <textarea id="custom_prompt" name="custom_prompt" rows="3" class="aissp-input"
     531                          <?php echo $dis; ?>><?php echo esc_textarea($opts['custom_prompt']??''); ?></textarea>
     532                <p class="aissp-hint">We already apply an internal prompt that meets all SEO criteria.
     533                    Add tone or extra instructions here if you want the AI to include them <em>on top of</em> ours.</p>
     534            </div>
     535
     536            <hr class="aissp-divider">
     537
     538            <!-- Index Settings -->
     539            <div class="aissp-section-title">
     540                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/><line x1="16" y1="13" x2="8" y2="13"/><line x1="16" y1="17" x2="8" y2="17"/></svg>
     541                Index / Noindex Settings
     542            </div>
     543            <p class="aissp-section-desc">Choose which content types should include an index or noindex meta tag.</p>
     544
     545            <div class="aissp-index-grid">
    358546                <?php
    359547                $labels=['post'=>'Post','page'=>'Page','landing_page'=>'Landing Page',
     
    362550                foreach($labels as $k=>$lab):
    363551                    $val=$opts["index_$k"]??$def[$k];?>
    364                     <tr>
    365                         <th><?php echo $lab; ?> Index?</th>
    366                         <td>
    367                             <select name="index_<?php echo $k;?>" <?php echo $dis;?>>
    368                                 <option value="yes" <?php selected($val,'yes');?>>Yes</option>
    369                                 <option value="no"  <?php selected($val,'no' );?>>No (noindex)</option>
    370                             </select>
    371                         </td>
    372                     </tr>
     552                    <div class="aissp-index-item">
     553                        <span class="type-label"><?php echo esc_html($lab); ?></span>
     554                        <select name="index_<?php echo esc_attr($k); ?>" <?php echo $dis; ?>>
     555                            <option value="yes" <?php selected($val,'yes'); ?>>Index</option>
     556                            <option value="no"  <?php selected($val,'no' ); ?>>Noindex</option>
     557                        </select>
     558                    </div>
    373559                <?php endforeach; ?>
    374                 <tr>
    375                   <th><label for="auto_slug">Auto-update URL Slug?</label></th>
    376                   <td>
    377                     <label>
    378                       <input type="checkbox" id="auto_slug" name="auto_slug" value="yes"
    379                              <?php checked($opts['auto_slug'] ?? 'no', 'yes'); ?> <?php echo $dis; ?>>
    380                       Replace slug with AI suggestion &nbsp;<small>(adds 301 redirect)</small>
    381                     </label>
    382                     <p class="description">
    383                       Default OFF. When enabled, the AI-generated slug will overwrite the current one.<br>
    384                       WordPress instantly creates a <code>301</code> from the old URL (<em>_wp_old_slug_</em> meta).
    385                     </p>
    386                   </td>
    387                 </tr>
    388             </table>
    389 
    390             <p>
    391                 <button type="submit" class="primary-btn"><?php
    392                     echo empty($token)?'Save (needs key)':'Save Changes';?></button>
    393                 <?php if(empty($token)):?><span class="need-key">← enter a Site Key first</span><?php endif;?>
    394             </p>
     560            </div>
     561
     562            <!-- Auto Slug -->
     563            <div class="aissp-toggle-row">
     564                <input type="checkbox" id="auto_slug" name="auto_slug" value="yes"
     565                       <?php checked($opts['auto_slug'] ?? 'no', 'yes'); ?> <?php echo $dis; ?>>
     566                <label class="aissp-toggle-label" for="auto_slug">
     567                    <strong>Auto-update URL Slug</strong>
     568                    <small>Replace slug with AI suggestion. WordPress adds a 301 redirect via <code>_wp_old_slug</code>.</small>
     569                </label>
     570            </div>
     571
     572            <hr class="aissp-divider">
     573
     574            <button type="submit" class="aissp-btn aissp-btn-primary" <?php echo $dis; ?>>
     575                <?php echo empty($token) ? 'Save (needs key)' : 'Save Changes'; ?>
     576            </button>
     577            <?php if(empty($token)):?><span style="margin-left:10px;color:#94a3b8;font-size:14px">Enter a Site Key first</span><?php endif; ?>
    395578        </form>
    396579    <?php endif; ?>
    397     </main>
    398 </div>
     580
     581    </div><!-- .aissp-body -->
     582</div><!-- .aissp-container -->
     583
     584<script>
     585(function(){
     586    var cards = document.querySelectorAll('.aissp-model-card:not(.disabled)');
     587    cards.forEach(function(card){
     588        card.addEventListener('click', function(){
     589            document.querySelectorAll('.aissp-model-card').forEach(function(c){ c.classList.remove('selected'); });
     590            card.classList.add('selected');
     591            var radio = card.querySelector('input[type="radio"]');
     592            if(radio) radio.checked = true;
     593        });
     594    });
     595})();
     596</script>
    399597
    400598<?php } /* end aissp_render_settings_page */ ?>
  • ai-snippet-seo-pro/trunk/ai-snippet-seo-pro.php

    r3441058 r3462134  
    33Plugin Name: AI Snippet SEO Pro
    44Description: Generate AI SEO titles and meta descriptions in one click, with scoring, live preview and bulk tools for posts and taxonomies.
    5 Version: 1.0.24
     5Version: 1.0.25
    66Author:      RankPilotAI
    77Author URI:  https://rankpilotai.com
     
    2121
    2222/* Version constant — basit ve PHP5 uyumlu */
    23 if ( ! defined('AISSP_VERSION') ) { if ( ! defined('AISSP_VERSION') ) if ( ! defined('AISSP_VERSION') ) if ( ! defined('AISSP_VERSION') ) define('AISSP_VERSION','1.0.24'); }
     23if ( ! defined('AISSP_VERSION') ) { if ( ! defined('AISSP_VERSION') ) if ( ! defined('AISSP_VERSION') ) if ( ! defined('AISSP_VERSION') ) define('AISSP_VERSION','1.0.25'); }
    2424function aissp_plugin_activate() {
    2525    $option_key = 'aissp_settings';
     
    5555
    5656    private function define_constants(){
    57         if ( ! defined('AISSP_VERSION') ) if ( ! defined('AISSP_VERSION') ) if ( ! defined('AISSP_VERSION') ) define('AISSP_VERSION','1.0.24');
     57        if ( ! defined('AISSP_VERSION') ) if ( ! defined('AISSP_VERSION') ) if ( ! defined('AISSP_VERSION') ) define('AISSP_VERSION','1.0.25');
    5858        define('AISSP_PATH', plugin_dir_path(__FILE__));
    5959        define('AISSP_URL', plugin_dir_url(__FILE__));
  • ai-snippet-seo-pro/trunk/readme.txt

    r3441058 r3462134  
    55Tested up to: 6.9
    66Requires PHP: 7.4
    7 Stable tag: 1.0.24
     7Stable tag: 1.0.25
    88License: GPLv2 or later
    99License URI: https://www.gnu.org/licenses/gpl-2.0.html
     
    119119== Changelog ==
    120120
     121= 1.0.25 =
     122* UI: Modernized settings page with gradient header, card-based layout, model radio cards, usage grid, and responsive design.
     123
    121124= 1.0.24 =
    122125* Maintenance: minor version consistency updates and small documentation/copy cleanup. No functional changes.
Note: See TracChangeset for help on using the changeset viewer.